@commercetools/checkout-payments-processor-sdk 0.0.6

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.
Files changed (105) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +42 -0
  3. package/biome.json +38 -0
  4. package/package.json +48 -0
  5. package/src/api/context/request-context.helper.test.ts +98 -0
  6. package/src/api/context/request-context.helper.ts +89 -0
  7. package/src/api/context/request-context.provider.ts +27 -0
  8. package/src/api/context/types/request-context.type.ts +18 -0
  9. package/src/api/handlers/payment-components.handler.test.ts +378 -0
  10. package/src/api/handlers/payment-components.handler.ts +80 -0
  11. package/src/api/handlers/payment-intents.handler.test.ts +475 -0
  12. package/src/api/handlers/payment-intents.handler.ts +169 -0
  13. package/src/api/handlers/status.handler.test.ts +551 -0
  14. package/src/api/handlers/status.handler.ts +216 -0
  15. package/src/api/handlers/transaction.handler.ts +86 -0
  16. package/src/api/handlers/types/handler.type.ts +49 -0
  17. package/src/api/hooks/authorize.hook.test.ts +62 -0
  18. package/src/api/hooks/authorize.hook.ts +51 -0
  19. package/src/api/hooks/jwt-auth.hook.test.ts +54 -0
  20. package/src/api/hooks/jwt-auth.hook.ts +56 -0
  21. package/src/api/hooks/oauth2-auth.hook.test.ts +173 -0
  22. package/src/api/hooks/oauth2-auth.hook.ts +46 -0
  23. package/src/api/hooks/session-header-auth.hook.ts +47 -0
  24. package/src/api/hooks/session-query-param-auth.hook.ts +46 -0
  25. package/src/api/hooks/types/hook.type.ts +12 -0
  26. package/src/api/index.ts +11 -0
  27. package/src/api/types.ts +3 -0
  28. package/src/commercetools/api/base-api.ts +28 -0
  29. package/src/commercetools/api/cart-api.test.ts +95 -0
  30. package/src/commercetools/api/cart-api.ts +55 -0
  31. package/src/commercetools/api/custom-type-api.ts +39 -0
  32. package/src/commercetools/api/order-api.ts +22 -0
  33. package/src/commercetools/api/payment-api.ts +64 -0
  34. package/src/commercetools/api/payment-method-api.ts +118 -0
  35. package/src/commercetools/api/root-api.ts +109 -0
  36. package/src/commercetools/errors/ct-api.error.ts +27 -0
  37. package/src/commercetools/helpers/currency.converter.test.ts +121 -0
  38. package/src/commercetools/helpers/currency.converter.test_data.json +2379 -0
  39. package/src/commercetools/helpers/currency.converter.ts +102 -0
  40. package/src/commercetools/helpers/taxrate.converter.test.ts +48 -0
  41. package/src/commercetools/helpers/taxrate.converter.ts +39 -0
  42. package/src/commercetools/index.ts +22 -0
  43. package/src/commercetools/services/ct-cart.service.test.ts +1616 -0
  44. package/src/commercetools/services/ct-cart.service.ts +316 -0
  45. package/src/commercetools/services/ct-custom-type.service.ts +62 -0
  46. package/src/commercetools/services/ct-order.service.test.ts +136 -0
  47. package/src/commercetools/services/ct-order.service.ts +47 -0
  48. package/src/commercetools/services/ct-payment-method.service.test.ts +878 -0
  49. package/src/commercetools/services/ct-payment-method.service.ts +223 -0
  50. package/src/commercetools/services/ct-payment.service.test.ts +1123 -0
  51. package/src/commercetools/services/ct-payment.service.ts +574 -0
  52. package/src/commercetools/types/api.type.ts +162 -0
  53. package/src/commercetools/types/cart.type.ts +83 -0
  54. package/src/commercetools/types/custom-type.type.ts +21 -0
  55. package/src/commercetools/types/order.type.ts +19 -0
  56. package/src/commercetools/types/payment-method.type.ts +130 -0
  57. package/src/commercetools/types/payment.type.ts +74 -0
  58. package/src/commercetools/types/predefined-custom-types.type.ts +240 -0
  59. package/src/commercetools/types.ts +7 -0
  60. package/src/errorx/errorx.ts +625 -0
  61. package/src/errorx/index.ts +1 -0
  62. package/src/errorx/types.ts +5 -0
  63. package/src/fetch/decorators/base.decorator.ts +13 -0
  64. package/src/fetch/decorators/monitoring.decorator.ts +41 -0
  65. package/src/fetch/fetch.test.ts +57 -0
  66. package/src/fetch/index.ts +3 -0
  67. package/src/fetch/types/fetch.type.ts +11 -0
  68. package/src/fetch/types.ts +1 -0
  69. package/src/index.ts +15 -0
  70. package/src/logger/commercetools-logger.ts +69 -0
  71. package/src/logger/index.ts +1 -0
  72. package/src/logger/types/logger.type.ts +6 -0
  73. package/src/logger/types.ts +1 -0
  74. package/src/mocks/auth.mock.ts +6 -0
  75. package/src/mocks/cart.mock.ts +239 -0
  76. package/src/mocks/ct-api-error.mock.ts +23 -0
  77. package/src/mocks/index.ts +4 -0
  78. package/src/mocks/payment.mock.ts +35 -0
  79. package/src/payment-processor.ts +317 -0
  80. package/src/security/authn/authns.ts +219 -0
  81. package/src/security/authn/bearer-utils.test.ts +35 -0
  82. package/src/security/authn/bearer-utils.ts +28 -0
  83. package/src/security/authn/jwt-authn-manager.ts +69 -0
  84. package/src/security/authn/oauth2-authn-manager.ts +105 -0
  85. package/src/security/authn/session-header-authn-manager.ts +58 -0
  86. package/src/security/authn/session-query-param-authn-manager.ts +53 -0
  87. package/src/security/authn/types/authn.type.ts +50 -0
  88. package/src/security/authz/authorization-manager.ts +39 -0
  89. package/src/security/authz/types/authz.type.ts +13 -0
  90. package/src/security/index.ts +13 -0
  91. package/src/security/services/authorization.service.ts +54 -0
  92. package/src/security/services/jwt.service.test.ts +27 -0
  93. package/src/security/services/jwt.service.ts +45 -0
  94. package/src/security/services/oauth2.service.ts +60 -0
  95. package/src/security/services/session.service.ts +141 -0
  96. package/src/security/services/types/authorization.type.ts +10 -0
  97. package/src/security/services/types/jwt.type.ts +3 -0
  98. package/src/security/services/types/oauth2.type.ts +15 -0
  99. package/src/security/services/types/session.type.ts +38 -0
  100. package/src/security/types.ts +6 -0
  101. package/tsconfig.json +28 -0
  102. package/tsconfig.prod.json +9 -0
  103. package/typedoc.json +6 -0
  104. package/vitest.config.ts +15 -0
  105. package/wiki/getting-started.md +13 -0
@@ -0,0 +1,625 @@
1
+ export interface ErrorxAdditionalOpts {
2
+ privateFields?: object;
3
+ privateMessage?: string;
4
+ fields?: object;
5
+ skipLog?: boolean;
6
+ cause?: Error;
7
+ }
8
+
9
+ export interface ErrorxBaseOpts {
10
+ message: string;
11
+ code: string;
12
+ httpErrorStatus: number;
13
+ }
14
+
15
+ export type ErrorxOpts = ErrorxBaseOpts & ErrorxAdditionalOpts;
16
+
17
+ /**
18
+ * Errorx is a custom error class that extends the native Error class.
19
+ */
20
+ export class Errorx extends Error {
21
+ privateFields?: object;
22
+ privateMessage?: string;
23
+ fields?: object;
24
+ skipLog?: boolean;
25
+ cause?: Error;
26
+
27
+ message: string;
28
+ code: string;
29
+ httpErrorStatus: number;
30
+
31
+ constructor(opts: ErrorxOpts) {
32
+ super(opts.message);
33
+ this.privateFields = opts.privateFields;
34
+ this.privateMessage = opts.privateMessage;
35
+ this.fields = opts.fields;
36
+ this.skipLog = opts.skipLog;
37
+ this.cause = opts.cause;
38
+ this.message = opts.message;
39
+ this.code = opts.code;
40
+ this.httpErrorStatus = opts.httpErrorStatus;
41
+
42
+ this.cause = opts.cause;
43
+ this.name = this.code;
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Allows multiple Errorx objects to be grouped together into a single response. Main purposes it so combine multiple of the same response types together.
49
+ * For example when the provided HTTP body schema validation fails this can be used to return all schema validation errors in one HTTP response
50
+ */
51
+ export class MultiErrorx extends Error {
52
+ public errors: Errorx[];
53
+ constructor(errors: Errorx[]) {
54
+ if (errors.length > 0) {
55
+ const allHaveSameStatusCode = errors.every(
56
+ (v) => v.httpErrorStatus === errors[0].httpErrorStatus,
57
+ );
58
+ if (!allHaveSameStatusCode) {
59
+ throw new Error(
60
+ 'MultiErrorx is only allow to have errors of the same HTTP status code.',
61
+ );
62
+ }
63
+ }
64
+
65
+ super(errors.map((e) => e.message).join(','));
66
+ this.errors = errors;
67
+ }
68
+ }
69
+
70
+ /**
71
+ * AuthErrorResponse (https://docs.commercetools.com/api/errors#autherrorresponse)
72
+ * Represents errors related to authentication and authorization in a format conforming to the OAuth 2.0 specification.
73
+ * {
74
+ * "statusCode": 401,
75
+ * "message": "invalid_token",
76
+ * "errors": [
77
+ * {
78
+ * "code": "invalid_token",
79
+ * "message": "invalid_token"
80
+ * }
81
+ * ],
82
+ * "error": "invalid_token"
83
+ * }
84
+ */
85
+ export class ErrorAuthErrorResponse extends Errorx {
86
+ constructor(
87
+ message?: string,
88
+ additionalOpts?: ErrorxAdditionalOpts,
89
+ code?: string,
90
+ ) {
91
+ super({
92
+ code: code || 'invalid_token',
93
+ httpErrorStatus: 401,
94
+ message: message || 'Authentication error.',
95
+ ...additionalOpts,
96
+ });
97
+ }
98
+ }
99
+
100
+ /**
101
+ * General (https://docs.commercetools.com/api/errors#general)
102
+ * Returned when a server-side problem occurs.
103
+ */
104
+ export class ErrorGeneral extends Errorx {
105
+ constructor(
106
+ msg: string = 'Unknown error.',
107
+ additionalOpts?: ErrorxAdditionalOpts,
108
+ ) {
109
+ super({
110
+ code: 'General',
111
+ httpErrorStatus: 500,
112
+ message: msg,
113
+ ...additionalOpts,
114
+ });
115
+ }
116
+ }
117
+
118
+ /**
119
+ * DuplicateFieldWithConflictingResource (https://docs.commercetools.com/api/errors#duplicatefieldwithconflictingresource)
120
+ * Returned when a field value conflicts with an existing value stored in a particular resource causing a duplicate.
121
+ */
122
+ export class ErrorDuplicateFieldWithConflictingResource extends Errorx {
123
+ constructor(
124
+ field: string,
125
+ duplicateValue: string,
126
+ additionalOpts?: ErrorxAdditionalOpts,
127
+ ) {
128
+ super({
129
+ code: 'DuplicateFieldWithConflictingResource',
130
+ httpErrorStatus: 400,
131
+ message: `A duplicate value ${duplicateValue} exists for field ${field} in request.`,
132
+ ...additionalOpts,
133
+ });
134
+ }
135
+ }
136
+
137
+ /**
138
+ * MissingProjectKey
139
+ * Missing the project key in the path.
140
+ */
141
+ export class ErrorMissingProjectKey extends Errorx {
142
+ constructor(additionalOpts?: ErrorxAdditionalOpts) {
143
+ super({
144
+ code: 'MissingProjectKey',
145
+ httpErrorStatus: 400,
146
+ message: 'Missing project key in the request path.',
147
+ ...additionalOpts,
148
+ });
149
+ }
150
+ }
151
+
152
+ /**
153
+ * MissingApplicationKey
154
+ * Missing the project key in the path.
155
+ */
156
+ export class ErrorMissingApplicationKey extends Errorx {
157
+ constructor(additionalOpts?: ErrorxAdditionalOpts) {
158
+ super({
159
+ code: 'MissingApplicationKey',
160
+ httpErrorStatus: 400,
161
+ message: 'Missing application key in request.',
162
+ ...additionalOpts,
163
+ });
164
+ }
165
+ }
166
+
167
+ /**
168
+ * MissingAuthenticationInfo
169
+ * Missing the project key in the path.
170
+ */
171
+ export class ErrorMissingAuthenticationInfo extends Errorx {
172
+ constructor(additionalOpts?: ErrorxAdditionalOpts) {
173
+ super({
174
+ code: 'MissingAuthenticationInfo',
175
+ httpErrorStatus: 400,
176
+ message: 'Not able to identify the user',
177
+ ...additionalOpts,
178
+ });
179
+ }
180
+ }
181
+
182
+ /**
183
+ * InvalidInput (https://docs.commercetools.com/api/errors#invalidinput)
184
+ * Returned when an invalid input has been sent.
185
+ */
186
+ export class ErrorInvalidInput extends Errorx {
187
+ constructor(message: string, additionalOpts?: ErrorxAdditionalOpts) {
188
+ const { ...rest } = additionalOpts || {};
189
+ super({
190
+ code: 'InvalidInput',
191
+ httpErrorStatus: 400,
192
+ message,
193
+ ...rest,
194
+ });
195
+ }
196
+ }
197
+
198
+ /**
199
+ * InvalidJsonInput (https://docs.commercetools.com/api/errors#invalidjsoninput)
200
+ * Returned when an invalid JSON input has been sent. Either the JSON is syntactically incorrect or does not conform to the expected shape (for example is missing a required field).
201
+ *
202
+ * The client application should validate the input according to the constraints described in the error message before sending the request.
203
+ */
204
+ export class ErrorInvalidJsonInput extends Errorx {
205
+ constructor(
206
+ detailedErrorMessage?: string,
207
+ additionalOpts?: ErrorxAdditionalOpts,
208
+ ) {
209
+ const { fields, ...rest } = additionalOpts || {};
210
+ super({
211
+ code: 'InvalidJsonInput',
212
+ httpErrorStatus: 400,
213
+ message: 'Request body does not contain valid JSON.',
214
+ fields: {
215
+ ...fields,
216
+ detailedErrorMessage,
217
+ },
218
+ ...rest,
219
+ });
220
+ }
221
+ }
222
+
223
+ /**
224
+ * InvalidOperation (https://docs.commercetools.com/api/errors#invalidoperation)
225
+ * Returned when the resources involved in the request are not in a valid state for the operation.
226
+ *
227
+ * The client application should validate the constraints described in the error message before sending the request.
228
+ */
229
+ export class ErrorInvalidOperation extends Errorx {
230
+ constructor(message: string, additionalOpts?: ErrorxAdditionalOpts) {
231
+ super({
232
+ code: 'InvalidOperation',
233
+ httpErrorStatus: 400,
234
+ message,
235
+ ...additionalOpts,
236
+ });
237
+ }
238
+ }
239
+
240
+ /**
241
+ * InvalidField (https://docs.commercetools.com/api/errors#invalidfield)
242
+ * Returned when a field has an invalid value.
243
+ */
244
+ export class ErrorInvalidField<T> extends Errorx {
245
+ constructor(
246
+ field: string,
247
+ invalidValue: T,
248
+ allowedValues?: string,
249
+ additionalOpts?: ErrorxAdditionalOpts,
250
+ ) {
251
+ const { fields, ...rest } = additionalOpts || {};
252
+ super({
253
+ code: 'InvalidField',
254
+ httpErrorStatus: 400,
255
+ message: `The value ${invalidValue} is not valid for field ${field}.`,
256
+ fields: {
257
+ ...fields,
258
+ field,
259
+ invalidValue,
260
+ ...(allowedValues ? { allowedValues } : {}),
261
+ },
262
+ ...rest,
263
+ });
264
+ }
265
+ }
266
+
267
+ /**
268
+ * InternalConstraintViolated (https://docs.commercetools.com/api/errors#internalconstraintviolated)
269
+ * Returned when certain API-specific constraints were not met. For example, the specified Discount Code was never applied and cannot be updated.
270
+ */
271
+ export class ErrorInternalConstraintViolated extends Errorx {
272
+ constructor(message: string, additionalOpts?: ErrorxAdditionalOpts) {
273
+ super({
274
+ code: 'InternalConstraintViolated',
275
+ httpErrorStatus: 400,
276
+ message,
277
+ skipLog: true,
278
+ ...additionalOpts,
279
+ });
280
+ }
281
+ }
282
+
283
+ /**
284
+ * MoneyOverflow (https://docs.commercetools.com/api/errors#moneyoverflow)
285
+ * Returned when a Money operation overflows the 64-bit integer range. See Money usage for more information.
286
+ */
287
+ export class ErrorMoneyOverflow extends Errorx {
288
+ constructor(additionalOpts?: ErrorxAdditionalOpts) {
289
+ super({
290
+ code: 'MoneyOverflow',
291
+ httpErrorStatus: 400,
292
+ message: `A Money operation resulted in an overflow.`,
293
+ skipLog: true,
294
+ ...additionalOpts,
295
+ });
296
+ }
297
+ }
298
+
299
+ /**
300
+ * MaxResourceLimitExceeded (https://docs.commercetools.com/api/errors#maxresourcelimitexceeded)
301
+ * Returned when a resource type cannot be created as it has reached its limits.
302
+ */
303
+ export class ErrorMaxResourceLimitExceeded extends Errorx {
304
+ constructor(
305
+ limit: number,
306
+ resourceTypeId: string,
307
+ additionalOpts?: ErrorxAdditionalOpts,
308
+ ) {
309
+ super({
310
+ code: 'MaxResourceLimitExceeded',
311
+ httpErrorStatus: 400,
312
+ message: `You have exceeded the limit of ${limit} resources of type ${resourceTypeId}.`,
313
+ skipLog: true,
314
+ ...additionalOpts,
315
+ });
316
+ }
317
+ }
318
+
319
+ /**
320
+ * ObjectNotFound (https://docs.commercetools.com/api/errors#objectnotfound)
321
+ * Returned when the requested resource was not found.
322
+ */
323
+ export class ErrorObjectNotFound extends Errorx {
324
+ constructor(
325
+ resourceTypeId: string,
326
+ id: unknown,
327
+ additionalOpts?: ErrorxAdditionalOpts,
328
+ ) {
329
+ super({
330
+ code: 'ObjectNotFound',
331
+ httpErrorStatus: 400,
332
+ message: `A ${resourceTypeId} with identifier ${id} was unexpectedly not found.`,
333
+ skipLog: true,
334
+ ...additionalOpts,
335
+ });
336
+ }
337
+ }
338
+
339
+ /**
340
+ * ReferenceExists (https://docs.commercetools.com/api/errors#invalidfield)
341
+ * Returned when a resource cannot be deleted because it is being referenced by another resource.
342
+ */
343
+ export class ErrorReferenceExists extends Errorx {
344
+ constructor(
345
+ resource: string,
346
+ referencedBy?: string,
347
+ additionalOpts?: ErrorxAdditionalOpts,
348
+ ) {
349
+ const { fields, ...rest } = additionalOpts ?? {};
350
+ super({
351
+ code: 'ReferenceExists',
352
+ httpErrorStatus: 400,
353
+ message: `Can not delete a ${resource} while it is referenced by at least one ${referencedBy}.`,
354
+ fields: {
355
+ ...fields,
356
+ referencedBy,
357
+ },
358
+ ...rest,
359
+ });
360
+ }
361
+ }
362
+
363
+ /**
364
+ * ReferencedResourceNotFound (https://docs.commercetools.com/api/errors#referencedresourcenotfound)
365
+ * Returned when a resource referenced by a Reference or a ResourceIdentifier could not be found.
366
+ */
367
+ export class ErrorReferencedResourceNotFound extends Errorx {
368
+ constructor(
369
+ typeId: string,
370
+ id?: string,
371
+ key?: string,
372
+ additionalOpts?: ErrorxAdditionalOpts,
373
+ message?: string,
374
+ ) {
375
+ const { fields, ...rest } = additionalOpts || {};
376
+ super({
377
+ code: 'ReferencedResourceNotFound',
378
+ httpErrorStatus: 400,
379
+ message: message
380
+ ? message
381
+ : `The referenced object of type ${typeId} ${
382
+ id || key
383
+ } was not found. It either doesn't exist, or it can't be accessed from this endpoint (e.g., if the endpoint filters by store or customer account).`,
384
+ fields: {
385
+ ...fields,
386
+ id,
387
+ key,
388
+ typeId,
389
+ },
390
+ ...rest,
391
+ });
392
+ }
393
+ }
394
+
395
+ /**
396
+ * ReferencedResourceNotFound (https://docs.commercetools.com/api/errors#referencedresourcenotfound)
397
+ * Returned when a resource referenced by a Reference or a ResourceIdentifier could not be found.
398
+ */
399
+ export class ErrorRequiredField extends Errorx {
400
+ constructor(field: string, additionalOpts?: ErrorxAdditionalOpts) {
401
+ const { fields, ...rest } = additionalOpts || {};
402
+ super({
403
+ code: 'RequiredField',
404
+ httpErrorStatus: 400,
405
+ message: `A value is required for field ${field}.`,
406
+ fields: {
407
+ ...fields,
408
+ field,
409
+ },
410
+ ...rest,
411
+ });
412
+ }
413
+ }
414
+
415
+ /**
416
+ * SyntaxError (https://docs.commercetools.com/api/errors#syntaxerror)
417
+ * Returned when a Discount predicate, API Extension predicate, or search query does not have the correct syntax.
418
+ */
419
+ export class ErrorSyntaxError extends Errorx {
420
+ constructor(fieldDefinition: string, additionalOpts?: ErrorxAdditionalOpts) {
421
+ super({
422
+ code: 'SyntaxError',
423
+ httpErrorStatus: 400,
424
+ message: `Syntax error while parsing ${fieldDefinition}.`,
425
+ ...additionalOpts,
426
+ });
427
+ }
428
+ }
429
+
430
+ /**
431
+ * ResourceNotFound (https://docs.commercetools.com/api/errors#resourcenotfound)
432
+ * Returned when the resource addressed by the request URL does not exist.
433
+ */
434
+ export class ErrorResourceNotFound extends Errorx {
435
+ constructor(
436
+ resourceIdentifier: string,
437
+ resourceId: string,
438
+ additionalOpts?: ErrorxAdditionalOpts,
439
+ ) {
440
+ super({
441
+ code: 'ResourceNotFound',
442
+ httpErrorStatus: 404,
443
+ message: `The Resource with ${resourceIdentifier} ${resourceId} was not found.`,
444
+ skipLog: false,
445
+ ...additionalOpts,
446
+ });
447
+ }
448
+ }
449
+
450
+ /**
451
+ * ConcurrentModification (https://docs.commercetools.com/api/errors#concurrentmodification)
452
+ * Returned when the request conflicts with the current state of the involved resources. Typically, the request attempts to modify a resource that is out of date (that is modified by another client since it was last retrieved). The client application should resolve the conflict (with or without involving the end-user) before retrying the request.
453
+ */
454
+ export class ErrorConcurrentModification extends Errorx {
455
+ constructor(
456
+ resourceId: string,
457
+ expectedVersion: number,
458
+ currentVersion: number,
459
+ additionalOpts?: ErrorxAdditionalOpts,
460
+ ) {
461
+ const { fields, ...rest } = additionalOpts || {};
462
+ super({
463
+ code: 'ConcurrentModification',
464
+ httpErrorStatus: 409,
465
+ message: `Object ${resourceId} has a different version than expected. Expected: ${expectedVersion} - Actual: ${currentVersion}.`,
466
+ skipLog: true,
467
+ fields: {
468
+ ...fields,
469
+ resourceId,
470
+ expectedVersion,
471
+ currentVersion,
472
+ },
473
+ ...rest,
474
+ });
475
+ }
476
+ }
477
+
478
+ /**
479
+ * Error class for proxying errors from commercetools API
480
+ */
481
+ export class CommercetoolsApiError extends Errorx {
482
+ // TODO: Handle this better (add types)
483
+ // biome-ignore lint/suspicious/noExplicitAny: Accept any error object
484
+ constructor(err: any, additionalOpts?: ErrorxAdditionalOpts) {
485
+ super({
486
+ code: err.body?.code,
487
+ message: err?.body?.message || err?.message,
488
+ httpErrorStatus: err.statusCode,
489
+ cause: err,
490
+ fields: err.body?.errors,
491
+ ...additionalOpts,
492
+ });
493
+ this.name = 'CommercetoolsApiError';
494
+ }
495
+ }
496
+
497
+ /**
498
+ * Error class for proxying errors from commercetools API
499
+ */
500
+ export class CommercetoolsEmptyResponseApiError extends Errorx {
501
+ constructor(httpStatus: number, additionalOpts?: ErrorxAdditionalOpts) {
502
+ super({
503
+ code: 'CommercetoolsEmptyResponseApiError',
504
+ message: 'Empty response from commercetools API',
505
+ httpErrorStatus: httpStatus,
506
+ ...additionalOpts,
507
+ });
508
+ this.name = 'CommercetoolsEmptyResponseApiError';
509
+ }
510
+ }
511
+
512
+ /**
513
+ * Error class for proxying errors from commercetools Connect API
514
+ */
515
+ export class CommercetoolsConnectApiError extends Errorx {
516
+ constructor(
517
+ statusCode: number,
518
+ data: {
519
+ code?: string;
520
+ message?: string;
521
+ errors?: {
522
+ code?: string;
523
+ message?: string;
524
+ [key: string]: unknown;
525
+ }[];
526
+ [key: string]: unknown;
527
+ },
528
+ ) {
529
+ const errorData = data.errors ? data.errors[0] : data;
530
+
531
+ super({
532
+ code: errorData.code || 'ConnectUnknownError',
533
+ message: errorData.message || 'ConnectUnknownError',
534
+ httpErrorStatus: statusCode,
535
+ privateFields: data,
536
+ skipLog: true,
537
+ });
538
+ this.name = 'CommercetoolsConnectApiError';
539
+ }
540
+ }
541
+
542
+ /**
543
+ * ConnectorFailed
544
+ *
545
+ * Returned when the connector cannot be reached
546
+ */
547
+ export class ConnectorFailedError extends Errorx {
548
+ constructor(url: string, additionalOpts?: ErrorxAdditionalOpts) {
549
+ super({
550
+ code: 'ConnectorFailed',
551
+ httpErrorStatus: 502,
552
+ message: `The connector could not be reached.`,
553
+ skipLog: false,
554
+ privateFields: {
555
+ url,
556
+ },
557
+ ...additionalOpts,
558
+ });
559
+ }
560
+ }
561
+
562
+ /**
563
+ * PaymentFailureError
564
+ *
565
+ * Returned when the payment cannot be completed succesfully
566
+ */
567
+ export class PaymentFailureError extends Errorx {
568
+ constructor(additionalOpts?: ErrorxAdditionalOpts) {
569
+ super({
570
+ code: 'PaymentFailure',
571
+ httpErrorStatus: 502,
572
+ message: `Payment could not be completed succesfully.`,
573
+ skipLog: false,
574
+ ...additionalOpts,
575
+ });
576
+ }
577
+ }
578
+
579
+ /**
580
+ * Error class for proxying errors from commercetools Notification Service API
581
+ */
582
+ export class CommercetoolsNotificationServiceApiError extends Errorx {
583
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
584
+ constructor(
585
+ statusCode: number,
586
+ data: {
587
+ code?: string;
588
+ message?: string;
589
+ errors?: {
590
+ code?: string;
591
+ message?: string;
592
+ [key: string]: unknown;
593
+ }[];
594
+ [key: string]: unknown;
595
+ },
596
+ ) {
597
+ const errorData = data.errors ? data.errors[0] : data;
598
+
599
+ super({
600
+ code: errorData.code || 'NotificationServiceUnknownError',
601
+ message: errorData.message || 'NotificationServiceUnknownError',
602
+ httpErrorStatus: statusCode,
603
+ privateFields: data,
604
+ skipLog: false,
605
+ });
606
+ this.name = 'CommercetoolsNotificationServiceApiError';
607
+ }
608
+ }
609
+
610
+ /**
611
+ * ServiceUnavailableError
612
+ *
613
+ * Returned when the service is unavailable, for example when the Notification Service is down.
614
+ */
615
+ export class ServiceUnavailableError extends Errorx {
616
+ constructor(additionalOpts?: ErrorxAdditionalOpts) {
617
+ super({
618
+ code: 'ServiceUnavailable',
619
+ httpErrorStatus: 503,
620
+ message: `The service is unavailable.`,
621
+ skipLog: false,
622
+ ...additionalOpts,
623
+ });
624
+ }
625
+ }
@@ -0,0 +1 @@
1
+ export * from '@/errorx/errorx.js';
@@ -0,0 +1,5 @@
1
+ export type {
2
+ ErrorxAdditionalOpts,
3
+ ErrorxBaseOpts,
4
+ ErrorxOpts,
5
+ } from '@/errorx/errorx.js';
@@ -0,0 +1,13 @@
1
+ import type { Fetcher } from '@/fetch/types/fetch.type.js';
2
+
3
+ /**
4
+ * Basic fetcher implementation
5
+ */
6
+ export class BasicFetcher implements Fetcher {
7
+ run(
8
+ input: string | URL | globalThis.Request,
9
+ init?: RequestInit,
10
+ ): Promise<Response> {
11
+ return fetch(input, init);
12
+ }
13
+ }
@@ -0,0 +1,41 @@
1
+ import type { ContextProvider, RequestContextData } from '@api-types';
2
+ import type { Fetcher } from '@/fetch/types/fetch.type.js';
3
+
4
+ /**
5
+ * Decorates the fetcher with the correlation id and request id
6
+ */
7
+ export class MonitoringFetcherDecorator implements Fetcher {
8
+ private decoratee: Fetcher;
9
+ private contextProvider: ContextProvider<RequestContextData>;
10
+
11
+ constructor(
12
+ decoratee: Fetcher,
13
+ contextProvider: ContextProvider<RequestContextData>,
14
+ ) {
15
+ this.decoratee = decoratee;
16
+ this.contextProvider = contextProvider;
17
+ }
18
+
19
+ async run(
20
+ input: string | URL | globalThis.Request,
21
+ init?: RequestInit,
22
+ ): Promise<Response> {
23
+ init = init || {};
24
+
25
+ const { requestId, correlationId } = this.contextProvider.getContextData();
26
+ if (requestId || correlationId) {
27
+ if (!init) {
28
+ init = {};
29
+ }
30
+ init.headers = new Headers(init.headers);
31
+ if (requestId) {
32
+ init.headers.set('x-request-id', requestId);
33
+ }
34
+ if (correlationId) {
35
+ init.headers.set('x-correlation-id', correlationId);
36
+ }
37
+ }
38
+
39
+ return this.decoratee.run(input, init);
40
+ }
41
+ }