@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,173 @@
1
+ import type { Logger } from '@logger-types';
2
+ import {
3
+ HeaderBasedAuthentication,
4
+ Oauth2Authentication,
5
+ type Oauth2AuthenticationManager,
6
+ } from '@security';
7
+ import type {
8
+ ContextProvider,
9
+ RequestContextData,
10
+ } from '@/api/context/types/request-context.type.js';
11
+ import { Oauth2AuthenticationHook } from '@/api/hooks/oauth2-auth.hook.js';
12
+
13
+ describe('Oauth2AuthenticationHook', () => {
14
+ const authenticationManager = {
15
+ authenticate: vi.fn(),
16
+ };
17
+ const contextProvider = {
18
+ updateContextData: vi.fn(),
19
+ };
20
+ const logger = vi.fn() as unknown as Logger;
21
+ const authenticationHook = new Oauth2AuthenticationHook({
22
+ authenticationManager:
23
+ authenticationManager as unknown as Oauth2AuthenticationManager,
24
+ contextProvider:
25
+ contextProvider as unknown as ContextProvider<RequestContextData>,
26
+ logger,
27
+ });
28
+
29
+ beforeEach(() => {
30
+ vi.clearAllMocks();
31
+ });
32
+
33
+ test('authenticate should update the context data with authentication', async () => {
34
+ // Arrange
35
+ const authorizationHeader = 'Bearer <oauth2-token>';
36
+ const request = {
37
+ headers: {
38
+ authorization: authorizationHeader,
39
+ },
40
+ };
41
+ const oauth2Authentication = new Oauth2Authentication('<oauth2-token>', {
42
+ scope: 'manage_project:test-project customer_id:123',
43
+ clientId: 'test-client',
44
+ customerId: '123',
45
+ anonymousId: undefined,
46
+ });
47
+
48
+ // Act
49
+ authenticationManager.authenticate.mockResolvedValue(oauth2Authentication);
50
+ const authenticateFn = authenticationHook.authenticate();
51
+ await authenticateFn(request);
52
+
53
+ // Assert
54
+ expect(contextProvider.updateContextData).toHaveBeenCalledWith({
55
+ authentication: oauth2Authentication,
56
+ });
57
+ expect(authenticationManager.authenticate).toHaveBeenCalledWith(
58
+ expect.any(HeaderBasedAuthentication),
59
+ );
60
+ const capturedArg = authenticationManager.authenticate.mock
61
+ .calls[0][0] as HeaderBasedAuthentication;
62
+ expect(capturedArg.getCredentials()).toBe(authorizationHeader);
63
+ });
64
+
65
+ test('authenticate should handle requests without authorization header', async () => {
66
+ // Arrange
67
+ const request = {
68
+ headers: {},
69
+ };
70
+ const oauth2Authentication = new Oauth2Authentication('<oauth2-token>', {
71
+ scope: 'manage_project:test-project',
72
+ clientId: 'test-client',
73
+ customerId: undefined,
74
+ anonymousId: undefined,
75
+ });
76
+
77
+ // Act
78
+ authenticationManager.authenticate.mockResolvedValue(oauth2Authentication);
79
+ const authenticateFn = authenticationHook.authenticate();
80
+ await authenticateFn(request);
81
+
82
+ // Assert
83
+ expect(contextProvider.updateContextData).toHaveBeenCalledWith({
84
+ authentication: oauth2Authentication,
85
+ });
86
+ expect(authenticationManager.authenticate).toHaveBeenCalledWith(
87
+ expect.any(HeaderBasedAuthentication),
88
+ );
89
+ const capturedArg = authenticationManager.authenticate.mock
90
+ .calls[0][0] as HeaderBasedAuthentication;
91
+ expect(capturedArg.getCredentials()).toBeUndefined();
92
+ });
93
+
94
+ test('authenticate should handle authentication with anonymous user', async () => {
95
+ // Arrange
96
+ const authorizationHeader = 'Bearer <oauth2-token>';
97
+ const request = {
98
+ headers: {
99
+ authorization: authorizationHeader,
100
+ },
101
+ };
102
+ const oauth2Authentication = new Oauth2Authentication('<oauth2-token>', {
103
+ scope: 'manage_project:test-project anonymous_id:456',
104
+ clientId: 'test-client',
105
+ customerId: undefined,
106
+ anonymousId: '456',
107
+ });
108
+
109
+ // Act
110
+ authenticationManager.authenticate.mockResolvedValue(oauth2Authentication);
111
+ const authenticateFn = authenticationHook.authenticate();
112
+ await authenticateFn(request);
113
+
114
+ // Assert
115
+ expect(contextProvider.updateContextData).toHaveBeenCalledWith({
116
+ authentication: oauth2Authentication,
117
+ });
118
+ expect(authenticationManager.authenticate).toHaveBeenCalledWith(
119
+ expect.any(HeaderBasedAuthentication),
120
+ );
121
+ });
122
+
123
+ test('authenticate should propagate authentication manager errors', async () => {
124
+ // Arrange
125
+ const authorizationHeader = 'Bearer invalid-token';
126
+ const request = {
127
+ headers: {
128
+ authorization: authorizationHeader,
129
+ },
130
+ };
131
+ const error = new Error('Invalid token');
132
+
133
+ // Act
134
+ authenticationManager.authenticate.mockRejectedValue(error);
135
+ const authenticateFn = authenticationHook.authenticate();
136
+
137
+ // Assert
138
+ await expect(authenticateFn(request)).rejects.toThrow('Invalid token');
139
+ expect(contextProvider.updateContextData).not.toHaveBeenCalled();
140
+ });
141
+
142
+ test('authenticate should handle requests with query parameters', async () => {
143
+ // Arrange
144
+ const authorizationHeader = 'Bearer <oauth2-token>';
145
+ const request = {
146
+ headers: {
147
+ authorization: authorizationHeader,
148
+ },
149
+ query: {
150
+ someParam: 'someValue',
151
+ },
152
+ };
153
+ const oauth2Authentication = new Oauth2Authentication('<oauth2-token>', {
154
+ scope: 'manage_project:test-project',
155
+ clientId: 'test-client',
156
+ customerId: undefined,
157
+ anonymousId: undefined,
158
+ });
159
+
160
+ // Act
161
+ authenticationManager.authenticate.mockResolvedValue(oauth2Authentication);
162
+ const authenticateFn = authenticationHook.authenticate();
163
+ await authenticateFn(request);
164
+
165
+ // Assert
166
+ expect(contextProvider.updateContextData).toHaveBeenCalledWith({
167
+ authentication: oauth2Authentication,
168
+ });
169
+ expect(authenticationManager.authenticate).toHaveBeenCalledWith(
170
+ expect.any(HeaderBasedAuthentication),
171
+ );
172
+ });
173
+ });
@@ -0,0 +1,46 @@
1
+ import type { IncomingHttpHeaders } from 'node:http';
2
+ import type { Logger } from '@logger-types';
3
+ import {
4
+ HeaderBasedAuthentication,
5
+ type Oauth2AuthenticationManager,
6
+ } from '@security';
7
+ import type {
8
+ ContextProvider,
9
+ RequestContextData,
10
+ } from '@/api/context/types/request-context.type.js';
11
+ import type { AuthenticationHook } from '@/api/hooks/types/hook.type.js';
12
+
13
+ export class Oauth2AuthenticationHook implements AuthenticationHook {
14
+ private authenticationManager: Oauth2AuthenticationManager;
15
+ private contextProvider: ContextProvider<RequestContextData>;
16
+ private logger: Logger;
17
+
18
+ constructor(opts: {
19
+ authenticationManager: Oauth2AuthenticationManager;
20
+ contextProvider: ContextProvider<RequestContextData>;
21
+ logger: Logger;
22
+ }) {
23
+ this.authenticationManager = opts.authenticationManager;
24
+ this.contextProvider = opts.contextProvider;
25
+ this.logger = opts.logger;
26
+ }
27
+
28
+ authenticate() {
29
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
+ return async (request: {
31
+ headers: IncomingHttpHeaders;
32
+ query?: unknown;
33
+ }) => {
34
+ const authorizationHeader = new HeaderBasedAuthentication(
35
+ request.headers.authorization as string,
36
+ );
37
+
38
+ const authn =
39
+ await this.authenticationManager.authenticate(authorizationHeader);
40
+
41
+ this.contextProvider.updateContextData({
42
+ authentication: authn,
43
+ });
44
+ };
45
+ }
46
+ }
@@ -0,0 +1,47 @@
1
+ import type { IncomingHttpHeaders } from 'node:http';
2
+ import type { Logger } from '@logger-types';
3
+ import {
4
+ HeaderBasedAuthentication,
5
+ type SessionHeaderAuthenticationManager,
6
+ } from '@security';
7
+ import type {
8
+ ContextProvider,
9
+ RequestContextData,
10
+ } from '@/api/context/types/request-context.type.js';
11
+ import type { AuthenticationHook } from '@/api/hooks/types/hook.type.js';
12
+
13
+ export class SessionHeaderAuthenticationHook implements AuthenticationHook {
14
+ private authenticationManager: SessionHeaderAuthenticationManager;
15
+ private contextProvider: ContextProvider<RequestContextData>;
16
+ private logger: Logger;
17
+
18
+ constructor(opts: {
19
+ authenticationManager: SessionHeaderAuthenticationManager;
20
+ contextProvider: ContextProvider<RequestContextData>;
21
+ logger: Logger;
22
+ }) {
23
+ this.authenticationManager = opts.authenticationManager;
24
+ this.contextProvider = opts.contextProvider;
25
+ this.logger = opts.logger;
26
+ }
27
+
28
+ authenticate() {
29
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
+ return async (request: {
31
+ headers: IncomingHttpHeaders;
32
+ query?: unknown;
33
+ }) => {
34
+ const sessionIdAuthn = new HeaderBasedAuthentication(
35
+ request.headers['x-session-id'] as string,
36
+ );
37
+ const authn =
38
+ await this.authenticationManager.authenticate(sessionIdAuthn);
39
+ const correlationId = authn.getPrincipal().correlationId;
40
+
41
+ this.contextProvider.updateContextData({
42
+ authentication: authn,
43
+ ...(correlationId && { correlationId }),
44
+ });
45
+ };
46
+ }
47
+ }
@@ -0,0 +1,46 @@
1
+ import type { IncomingHttpHeaders } from 'node:http';
2
+ import type { Logger } from '@logger-types';
3
+ import type {
4
+ ContextProvider,
5
+ RequestContextData,
6
+ } from '@/api/context/types/request-context.type.js';
7
+ import type { AuthenticationHook } from '@/api/hooks/types/hook.type.js';
8
+ import { QueryParamBasedAuthentication } from '@/security/authn/authns.js';
9
+ import type { SessionQueryParamAuthenticationManager } from '@/security/authn/session-query-param-authn-manager.js';
10
+
11
+ // TODO: This should not be here or at least being more generic
12
+ export class SessionQueryParamAuthenticationHook implements AuthenticationHook {
13
+ private authenticationManager: SessionQueryParamAuthenticationManager;
14
+ private contextProvider: ContextProvider<RequestContextData>;
15
+ private logger: Logger;
16
+
17
+ constructor(opts: {
18
+ authenticationManager: SessionQueryParamAuthenticationManager;
19
+ contextProvider: ContextProvider<RequestContextData>;
20
+ logger: Logger;
21
+ }) {
22
+ this.authenticationManager = opts.authenticationManager;
23
+ this.contextProvider = opts.contextProvider;
24
+ this.logger = opts.logger;
25
+ }
26
+
27
+ authenticate() {
28
+ return async (request: {
29
+ headers: IncomingHttpHeaders;
30
+ query?: unknown;
31
+ }) => {
32
+ const query = request.query as { ctsid: string };
33
+ const sessionIdAuthn = new QueryParamBasedAuthentication(
34
+ query.ctsid as string,
35
+ );
36
+ const authn =
37
+ await this.authenticationManager.authenticate(sessionIdAuthn);
38
+ const correlationId = authn.getPrincipal().correlationId;
39
+
40
+ this.contextProvider.updateContextData({
41
+ authentication: authn,
42
+ ...(correlationId && { correlationId }),
43
+ });
44
+ };
45
+ }
46
+ }
@@ -0,0 +1,12 @@
1
+ import type { IncomingHttpHeaders } from 'node:http';
2
+
3
+ export interface AuthenticationHook {
4
+ authenticate(): (request: {
5
+ headers: IncomingHttpHeaders;
6
+ query?: unknown;
7
+ }) => Promise<void>;
8
+ }
9
+
10
+ export interface AuthorizationHook {
11
+ authorize(...authorities: string[]): () => Promise<void>;
12
+ }
@@ -0,0 +1,11 @@
1
+ export * from '@/api/context/request-context.helper.js';
2
+ export * from '@/api/context/request-context.provider.js';
3
+ export * from '@/api/handlers/payment-components.handler.js';
4
+ export * from '@/api/handlers/payment-intents.handler.js';
5
+ export * from '@/api/handlers/status.handler.js';
6
+ export * from '@/api/handlers/transaction.handler.js';
7
+ export * from '@/api/hooks/authorize.hook.js';
8
+ export * from '@/api/hooks/jwt-auth.hook.js';
9
+ export * from '@/api/hooks/oauth2-auth.hook.js';
10
+ export * from '@/api/hooks/session-header-auth.hook.js';
11
+ export * from '@/api/hooks/session-query-param-auth.hook.js';
@@ -0,0 +1,3 @@
1
+ export * from '@/api/context/types/request-context.type.js';
2
+ export * from '@/api/handlers/types/handler.type.js';
3
+ export * from '@/api/hooks/types/hook.type.js';
@@ -0,0 +1,28 @@
1
+ import type { ClientResponse } from '@commercetools/platform-sdk';
2
+ import {
3
+ type CocoErrorType,
4
+ CommercetoolsAPIError,
5
+ } from '@/commercetools/errors/ct-api.error.js';
6
+ import type {
7
+ APIOpts,
8
+ CommercetoolsClient,
9
+ } from '@/commercetools/types/api.type.js';
10
+
11
+ export abstract class CommercetoolsBaseAPI {
12
+ protected client: CommercetoolsClient;
13
+
14
+ constructor(opts: APIOpts) {
15
+ this.client = opts.client;
16
+ }
17
+
18
+ protected async executeCall<T>(cr: Promise<ClientResponse<T>>): Promise<T> {
19
+ try {
20
+ return (await cr).body;
21
+ } catch (e: unknown) {
22
+ if (e instanceof Object && 'statusCode' in e) {
23
+ throw new CommercetoolsAPIError(e as CocoErrorType);
24
+ }
25
+ throw e;
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,95 @@
1
+ import { RequestContextProvider } from '@api';
2
+ import { CommercetoolsLogger } from '@logger';
3
+ import { HttpResponse, http } from 'msw';
4
+ import { setupServer } from 'msw/node';
5
+ import { DefaultCommercetoolsAPI } from '@/commercetools/api/root-api.js';
6
+ import { authToken } from '@/mocks/auth.mock.js';
7
+ import { cartMock } from '@/mocks/cart.mock.js';
8
+ import { ctAPIErrorMock } from '@/mocks/ct-api-error.mock.js';
9
+
10
+ const mockServer = setupServer();
11
+
12
+ describe('commercetools cart API', () => {
13
+ beforeAll(() =>
14
+ mockServer.listen({
15
+ onUnhandledRequest: 'error',
16
+ }),
17
+ );
18
+ afterAll(() => mockServer.close());
19
+ const projectKey = 'test';
20
+ const contextProvider = new RequestContextProvider({
21
+ getContextFn: () => ({
22
+ correlationId: 'correlation-id',
23
+ requestId: 'request-id',
24
+ }),
25
+ updateContextFn: () => {},
26
+ });
27
+ const logger = new CommercetoolsLogger({ contextProvider, projectKey });
28
+
29
+ const { cart: cartAPI } = new DefaultCommercetoolsAPI({
30
+ apiUrl: 'http://api.test.com',
31
+ authUrl: 'http://auth.test.com',
32
+ clientId: 'clientId',
33
+ clientSecret: 'clientSecret',
34
+ projectKey,
35
+ contextProvider,
36
+ logger,
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+ httpClient: (input: string | URL | Request, init?: RequestInit) => {
39
+ return fetch(input, init);
40
+ },
41
+ });
42
+
43
+ describe('getCartById', () => {
44
+ test('should return a cart', async () => {
45
+ //given
46
+ const cartId = '12345';
47
+ mockServer.use(
48
+ mockGetAuthToken(200, authToken),
49
+ mockGetCartById(cartId, 200, cartMock),
50
+ );
51
+
52
+ //when
53
+ const cart = await cartAPI.getCartById(cartId);
54
+
55
+ //then
56
+ expect(cart).toEqual(cartMock);
57
+ });
58
+
59
+ test('should throw an error when cart is not found', async () => {
60
+ //given
61
+ const cartId = '12345';
62
+ const statusCode = 404;
63
+ const errorMessage = 'Cart not found';
64
+ const error = ctAPIErrorMock(statusCode, 'Not Found', errorMessage);
65
+ mockServer.use(
66
+ mockGetAuthToken(200, authToken),
67
+ mockGetCartById(cartId, statusCode, error),
68
+ );
69
+
70
+ //when
71
+ const cartPromise = cartAPI.getCartById(cartId);
72
+
73
+ //then
74
+ await expect(cartPromise).rejects.toThrow(errorMessage);
75
+ });
76
+ });
77
+ });
78
+
79
+ const mockGetAuthToken = (respCode: number, data?: object) =>
80
+ http.post(
81
+ 'http://auth.test.com/oauth/token',
82
+ () => HttpResponse.json(data, { status: respCode }),
83
+ { once: true },
84
+ );
85
+
86
+ const mockGetCartById = (id: string, respCode: number, data?: object) => {
87
+ return http.get(
88
+ `http://api.test.com/test/carts/${id}`,
89
+ () =>
90
+ HttpResponse.json(data, {
91
+ status: respCode,
92
+ }),
93
+ { once: true },
94
+ );
95
+ };
@@ -0,0 +1,55 @@
1
+ import type { Cart, CartPagedQueryResponse } from '@commercetools/platform-sdk';
2
+ import { CommercetoolsBaseAPI } from '@/commercetools/api/base-api.js';
3
+ import type {
4
+ AddPayment,
5
+ APIOpts,
6
+ CartAPI,
7
+ } from '@/commercetools/types/api.type.js';
8
+
9
+ export class CommercetoolsCartAPI
10
+ extends CommercetoolsBaseAPI
11
+ implements CartAPI
12
+ {
13
+ constructor(opts: APIOpts) {
14
+ super(opts);
15
+ Object.setPrototypeOf(this, CommercetoolsCartAPI.prototype);
16
+ }
17
+
18
+ public async find(queryPredicate: string): Promise<CartPagedQueryResponse> {
19
+ return this.executeCall(
20
+ this.client
21
+ .carts()
22
+ .get({ queryArgs: { where: queryPredicate } })
23
+ .execute(),
24
+ );
25
+ }
26
+
27
+ public async getCartById(id: string): Promise<Cart> {
28
+ return this.executeCall(
29
+ this.client.carts().withId({ ID: id }).get().execute(),
30
+ );
31
+ }
32
+
33
+ public async addPayment(opts: AddPayment): Promise<Cart> {
34
+ return this.executeCall(
35
+ this.client
36
+ .carts()
37
+ .withId({ ID: opts.resource.id })
38
+ .post({
39
+ body: {
40
+ version: opts.resource.version,
41
+ actions: [
42
+ {
43
+ action: 'addPayment',
44
+ payment: {
45
+ id: opts.paymentId,
46
+ typeId: 'payment',
47
+ },
48
+ },
49
+ ],
50
+ },
51
+ })
52
+ .execute(),
53
+ );
54
+ }
55
+ }
@@ -0,0 +1,39 @@
1
+ import type { Type, TypePagedQueryResponse } from '@commercetools/platform-sdk';
2
+ import type { APIOpts, CustomTypeAPI } from '../types/api.type.js';
3
+ import { CommercetoolsBaseAPI } from './base-api.js';
4
+
5
+ export class CommercetoolsCustomTypeAPI
6
+ extends CommercetoolsBaseAPI
7
+ implements CustomTypeAPI
8
+ {
9
+ constructor(opts: APIOpts) {
10
+ super(opts);
11
+ Object.setPrototypeOf(this, CommercetoolsCustomTypeAPI.prototype);
12
+ }
13
+
14
+ public async getByKey(key: string): Promise<Type> {
15
+ return this.executeCall(
16
+ this.client.types().withKey({ key }).get().execute(),
17
+ );
18
+ }
19
+
20
+ public async find(queryPredicate: string): Promise<TypePagedQueryResponse> {
21
+ return this.executeCall(
22
+ this.client
23
+ .types()
24
+ .get({ queryArgs: { where: queryPredicate } })
25
+ .execute(),
26
+ );
27
+ }
28
+
29
+ public async create(draft: Type): Promise<Type> {
30
+ return this.executeCall(
31
+ this.client
32
+ .types()
33
+ .post({
34
+ body: draft,
35
+ })
36
+ .execute(),
37
+ );
38
+ }
39
+ }
@@ -0,0 +1,22 @@
1
+ import type { OrderPagedQueryResponse } from '@commercetools/platform-sdk';
2
+ import { CommercetoolsBaseAPI } from '@/commercetools/api/base-api.js';
3
+ import type { APIOpts, OrderAPI } from '@/commercetools/types/api.type.js';
4
+
5
+ export class CommercetoolsOrderAPI
6
+ extends CommercetoolsBaseAPI
7
+ implements OrderAPI
8
+ {
9
+ constructor(opts: APIOpts) {
10
+ super(opts);
11
+ Object.setPrototypeOf(this, CommercetoolsOrderAPI.prototype);
12
+ }
13
+
14
+ public async find(queryPredicate: string): Promise<OrderPagedQueryResponse> {
15
+ return this.executeCall(
16
+ this.client
17
+ .orders()
18
+ .get({ queryArgs: { where: queryPredicate } })
19
+ .execute(),
20
+ );
21
+ }
22
+ }
@@ -0,0 +1,64 @@
1
+ import type {
2
+ Payment,
3
+ PaymentDraft,
4
+ PaymentPagedQueryResponse,
5
+ } from '@commercetools/platform-sdk';
6
+ import { CommercetoolsBaseAPI } from '@/commercetools/api/base-api.js';
7
+ import type {
8
+ APIOpts,
9
+ PaymentAPI,
10
+ UpdatePayment,
11
+ } from '@/commercetools/types/api.type.js';
12
+
13
+ export class CommercetoolsPaymentAPI
14
+ extends CommercetoolsBaseAPI
15
+ implements PaymentAPI
16
+ {
17
+ constructor(opts: APIOpts) {
18
+ super(opts);
19
+ Object.setPrototypeOf(this, CommercetoolsPaymentAPI.prototype);
20
+ }
21
+
22
+ public async getPaymentById(id: string): Promise<Payment> {
23
+ return this.executeCall(
24
+ this.client.payments().withId({ ID: id }).get().execute(),
25
+ );
26
+ }
27
+
28
+ public async find(
29
+ queryPredicate: string,
30
+ ): Promise<PaymentPagedQueryResponse> {
31
+ return this.executeCall(
32
+ this.client
33
+ .payments()
34
+ .get({ queryArgs: { where: queryPredicate } })
35
+ .execute(),
36
+ );
37
+ }
38
+
39
+ public async createPayment(paymentDraft: PaymentDraft): Promise<Payment> {
40
+ return this.executeCall(
41
+ this.client
42
+ .payments()
43
+ .post({
44
+ body: paymentDraft,
45
+ })
46
+ .execute(),
47
+ );
48
+ }
49
+
50
+ public async updatePayment(opts: UpdatePayment): Promise<Payment> {
51
+ return this.executeCall(
52
+ this.client
53
+ .payments()
54
+ .withId({ ID: opts.resource.id })
55
+ .post({
56
+ body: {
57
+ version: opts.resource.version,
58
+ actions: opts.actions,
59
+ },
60
+ })
61
+ .execute(),
62
+ );
63
+ }
64
+ }