@reactionary/source 0.0.27
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/.editorconfig +13 -0
- package/.github/workflows/pull-request.yml +37 -0
- package/.github/workflows/release.yml +49 -0
- package/.nvmrc +1 -0
- package/.prettierignore +6 -0
- package/.prettierrc +3 -0
- package/.verdaccio/config.yml +28 -0
- package/.vscode/extensions.json +9 -0
- package/README.md +39 -0
- package/core/README.md +11 -0
- package/core/eslint.config.mjs +23 -0
- package/core/package.json +8 -0
- package/core/project.json +33 -0
- package/core/src/cache/caching-strategy.ts +25 -0
- package/core/src/cache/redis-cache.ts +41 -0
- package/core/src/client/client.ts +39 -0
- package/core/src/index.ts +42 -0
- package/core/src/providers/analytics.provider.ts +10 -0
- package/core/src/providers/base.provider.ts +75 -0
- package/core/src/providers/cart.provider.ts +10 -0
- package/core/src/providers/identity.provider.ts +10 -0
- package/core/src/providers/inventory.provider.ts +11 -0
- package/core/src/providers/price.provider.ts +10 -0
- package/core/src/providers/product.provider.ts +11 -0
- package/core/src/providers/search.provider.ts +12 -0
- package/core/src/schemas/capabilities.schema.ts +13 -0
- package/core/src/schemas/models/analytics.model.ts +7 -0
- package/core/src/schemas/models/base.model.ts +19 -0
- package/core/src/schemas/models/cart.model.ts +17 -0
- package/core/src/schemas/models/currency.model.ts +187 -0
- package/core/src/schemas/models/identifiers.model.ts +45 -0
- package/core/src/schemas/models/identity.model.ts +15 -0
- package/core/src/schemas/models/inventory.model.ts +8 -0
- package/core/src/schemas/models/price.model.ts +17 -0
- package/core/src/schemas/models/product.model.ts +28 -0
- package/core/src/schemas/models/search.model.ts +35 -0
- package/core/src/schemas/mutations/analytics.mutation.ts +22 -0
- package/core/src/schemas/mutations/base.mutation.ts +7 -0
- package/core/src/schemas/mutations/cart.mutation.ts +30 -0
- package/core/src/schemas/mutations/identity.mutation.ts +18 -0
- package/core/src/schemas/mutations/inventory.mutation.ts +5 -0
- package/core/src/schemas/mutations/price.mutation.ts +5 -0
- package/core/src/schemas/mutations/product.mutation.ts +6 -0
- package/core/src/schemas/mutations/search.mutation.ts +5 -0
- package/core/src/schemas/queries/analytics.query.ts +5 -0
- package/core/src/schemas/queries/base.query.ts +7 -0
- package/core/src/schemas/queries/cart.query.ts +12 -0
- package/core/src/schemas/queries/identity.query.ts +10 -0
- package/core/src/schemas/queries/inventory.query.ts +9 -0
- package/core/src/schemas/queries/price.query.ts +12 -0
- package/core/src/schemas/queries/product.query.ts +18 -0
- package/core/src/schemas/queries/search.query.ts +12 -0
- package/core/src/schemas/session.schema.ts +9 -0
- package/core/tsconfig.json +23 -0
- package/core/tsconfig.lib.json +23 -0
- package/core/tsconfig.spec.json +28 -0
- package/eslint.config.mjs +46 -0
- package/examples/angular/e2e/example.spec.ts +9 -0
- package/examples/angular/eslint.config.mjs +41 -0
- package/examples/angular/playwright.config.ts +38 -0
- package/examples/angular/project.json +86 -0
- package/examples/angular/public/favicon.ico +0 -0
- package/examples/angular/src/app/app.component.html +6 -0
- package/examples/angular/src/app/app.component.scss +22 -0
- package/examples/angular/src/app/app.component.ts +14 -0
- package/examples/angular/src/app/app.config.ts +16 -0
- package/examples/angular/src/app/app.routes.ts +25 -0
- package/examples/angular/src/app/cart/cart.component.html +4 -0
- package/examples/angular/src/app/cart/cart.component.scss +14 -0
- package/examples/angular/src/app/cart/cart.component.ts +73 -0
- package/examples/angular/src/app/identity/identity.component.html +6 -0
- package/examples/angular/src/app/identity/identity.component.scss +18 -0
- package/examples/angular/src/app/identity/identity.component.ts +49 -0
- package/examples/angular/src/app/product/product.component.html +14 -0
- package/examples/angular/src/app/product/product.component.scss +11 -0
- package/examples/angular/src/app/product/product.component.ts +42 -0
- package/examples/angular/src/app/search/search.component.html +35 -0
- package/examples/angular/src/app/search/search.component.scss +129 -0
- package/examples/angular/src/app/search/search.component.ts +50 -0
- package/examples/angular/src/app/services/product.service.ts +35 -0
- package/examples/angular/src/app/services/search.service.ts +48 -0
- package/examples/angular/src/app/services/trpc.client.ts +27 -0
- package/examples/angular/src/index.html +13 -0
- package/examples/angular/src/main.ts +7 -0
- package/examples/angular/src/styles.scss +17 -0
- package/examples/angular/src/test-setup.ts +6 -0
- package/examples/angular/tsconfig.app.json +10 -0
- package/examples/angular/tsconfig.editor.json +6 -0
- package/examples/angular/tsconfig.json +32 -0
- package/examples/node/README.md +11 -0
- package/examples/node/eslint.config.mjs +22 -0
- package/examples/node/jest.config.ts +10 -0
- package/examples/node/package.json +10 -0
- package/examples/node/project.json +20 -0
- package/examples/node/src/index.ts +2 -0
- package/examples/node/src/initialize-algolia.spec.ts +29 -0
- package/examples/node/src/initialize-commercetools.spec.ts +31 -0
- package/examples/node/src/initialize-extended-providers.spec.ts +38 -0
- package/examples/node/src/initialize-mixed-providers.spec.ts +36 -0
- package/examples/node/src/providers/custom-algolia-product.provider.ts +18 -0
- package/examples/node/src/schemas/custom-product.schema.ts +8 -0
- package/examples/node/tsconfig.json +23 -0
- package/examples/node/tsconfig.lib.json +10 -0
- package/examples/node/tsconfig.spec.json +15 -0
- package/examples/trpc-node/eslint.config.mjs +3 -0
- package/examples/trpc-node/project.json +61 -0
- package/examples/trpc-node/src/assets/.gitkeep +0 -0
- package/examples/trpc-node/src/main.ts +55 -0
- package/examples/trpc-node/src/router-instance.ts +52 -0
- package/examples/trpc-node/tsconfig.app.json +9 -0
- package/examples/trpc-node/tsconfig.json +13 -0
- package/examples/vue/eslint.config.mjs +24 -0
- package/examples/vue/index.html +13 -0
- package/examples/vue/project.json +8 -0
- package/examples/vue/src/app/App.vue +275 -0
- package/examples/vue/src/main.ts +6 -0
- package/examples/vue/src/styles.scss +9 -0
- package/examples/vue/src/vue-shims.d.ts +5 -0
- package/examples/vue/tsconfig.app.json +14 -0
- package/examples/vue/tsconfig.json +20 -0
- package/examples/vue/vite.config.ts +31 -0
- package/jest.config.ts +6 -0
- package/jest.preset.js +3 -0
- package/migrations.json +11 -0
- package/nx.json +130 -0
- package/package.json +118 -0
- package/project.json +14 -0
- package/providers/algolia/README.md +11 -0
- package/providers/algolia/eslint.config.mjs +22 -0
- package/providers/algolia/jest.config.ts +10 -0
- package/providers/algolia/package.json +9 -0
- package/providers/algolia/project.json +33 -0
- package/providers/algolia/src/core/initialize.ts +20 -0
- package/providers/algolia/src/index.ts +7 -0
- package/providers/algolia/src/providers/product.provider.ts +25 -0
- package/providers/algolia/src/providers/search.provider.ts +125 -0
- package/providers/algolia/src/schema/capabilities.schema.ts +10 -0
- package/providers/algolia/src/schema/configuration.schema.ts +9 -0
- package/providers/algolia/src/schema/search.schema.ts +14 -0
- package/providers/algolia/src/test/product.provider.spec.ts +18 -0
- package/providers/algolia/src/test/search.provider.spec.ts +82 -0
- package/providers/algolia/tsconfig.json +23 -0
- package/providers/algolia/tsconfig.lib.json +10 -0
- package/providers/algolia/tsconfig.spec.json +15 -0
- package/providers/commercetools/README.md +11 -0
- package/providers/commercetools/eslint.config.mjs +22 -0
- package/providers/commercetools/jest.config.ts +10 -0
- package/providers/commercetools/package.json +10 -0
- package/providers/commercetools/project.json +33 -0
- package/providers/commercetools/src/core/client.ts +152 -0
- package/providers/commercetools/src/core/initialize.ts +40 -0
- package/providers/commercetools/src/index.ts +12 -0
- package/providers/commercetools/src/providers/cart.provider.ts +223 -0
- package/providers/commercetools/src/providers/identity.provider.ts +130 -0
- package/providers/commercetools/src/providers/inventory.provider.ts +82 -0
- package/providers/commercetools/src/providers/price.provider.ts +66 -0
- package/providers/commercetools/src/providers/product.provider.ts +90 -0
- package/providers/commercetools/src/providers/search.provider.ts +86 -0
- package/providers/commercetools/src/schema/capabilities.schema.ts +13 -0
- package/providers/commercetools/src/schema/configuration.schema.ts +11 -0
- package/providers/commercetools/src/test/product.provider.spec.ts +20 -0
- package/providers/commercetools/src/test/search.provider.spec.ts +18 -0
- package/providers/commercetools/tsconfig.json +23 -0
- package/providers/commercetools/tsconfig.lib.json +10 -0
- package/providers/commercetools/tsconfig.spec.json +15 -0
- package/providers/fake/README.md +7 -0
- package/providers/fake/eslint.config.mjs +22 -0
- package/providers/fake/package.json +9 -0
- package/providers/fake/project.json +33 -0
- package/providers/fake/src/core/initialize.ts +24 -0
- package/providers/fake/src/index.ts +8 -0
- package/providers/fake/src/providers/identity.provider.ts +91 -0
- package/providers/fake/src/providers/product.provider.ts +73 -0
- package/providers/fake/src/providers/search.provider.ts +142 -0
- package/providers/fake/src/schema/capabilities.schema.ts +10 -0
- package/providers/fake/src/schema/configuration.schema.ts +15 -0
- package/providers/fake/src/utilities/jitter.ts +14 -0
- package/providers/fake/tsconfig.json +20 -0
- package/providers/fake/tsconfig.lib.json +9 -0
- package/providers/posthog/README.md +7 -0
- package/providers/posthog/eslint.config.mjs +22 -0
- package/providers/posthog/package.json +11 -0
- package/providers/posthog/project.json +33 -0
- package/providers/posthog/src/core/initialize.ts +9 -0
- package/providers/posthog/src/index.ts +4 -0
- package/providers/posthog/src/schema/capabilities.schema.ts +8 -0
- package/providers/posthog/src/schema/configuration.schema.ts +8 -0
- package/providers/posthog/tsconfig.json +20 -0
- package/providers/posthog/tsconfig.lib.json +9 -0
- package/trpc/README.md +7 -0
- package/trpc/eslint.config.mjs +19 -0
- package/trpc/package.json +13 -0
- package/trpc/project.json +31 -0
- package/trpc/src/index.ts +64 -0
- package/trpc/tsconfig.json +13 -0
- package/trpc/tsconfig.lib.json +9 -0
- package/tsconfig.base.json +30 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"forceConsistentCasingInFileNames": true,
|
|
6
|
+
"strict": true,
|
|
7
|
+
"importHelpers": true,
|
|
8
|
+
"noImplicitOverride": true,
|
|
9
|
+
"noImplicitReturns": true,
|
|
10
|
+
"noFallthroughCasesInSwitch": true,
|
|
11
|
+
"noPropertyAccessFromIndexSignature": true
|
|
12
|
+
},
|
|
13
|
+
"files": [],
|
|
14
|
+
"include": [],
|
|
15
|
+
"references": [
|
|
16
|
+
{
|
|
17
|
+
"path": "./tsconfig.lib.json"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"path": "./tsconfig.spec.json"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "../../dist/out-tsc",
|
|
5
|
+
"module": "commonjs",
|
|
6
|
+
"moduleResolution": "node10",
|
|
7
|
+
"types": ["jest", "node"]
|
|
8
|
+
},
|
|
9
|
+
"include": [
|
|
10
|
+
"jest.config.ts",
|
|
11
|
+
"src/**/*.test.ts",
|
|
12
|
+
"src/**/*.spec.ts",
|
|
13
|
+
"src/**/*.d.ts"
|
|
14
|
+
]
|
|
15
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# provider-commercetools
|
|
2
|
+
|
|
3
|
+
This library was generated with [Nx](https://nx.dev).
|
|
4
|
+
|
|
5
|
+
## Building
|
|
6
|
+
|
|
7
|
+
Run `nx build provider-commercetools` to build the library.
|
|
8
|
+
|
|
9
|
+
## Running unit tests
|
|
10
|
+
|
|
11
|
+
Run `nx test provider-commercetools` to execute the unit tests via [Jest](https://jestjs.io).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import baseConfig from '../../eslint.config.mjs';
|
|
2
|
+
|
|
3
|
+
export default [
|
|
4
|
+
...baseConfig,
|
|
5
|
+
{
|
|
6
|
+
files: ['**/*.json'],
|
|
7
|
+
rules: {
|
|
8
|
+
'@nx/dependency-checks': [
|
|
9
|
+
'error',
|
|
10
|
+
{
|
|
11
|
+
ignoredFiles: [
|
|
12
|
+
'{projectRoot}/eslint.config.{js,cjs,mjs}',
|
|
13
|
+
'{projectRoot}/esbuild.config.{js,ts,mjs,mts}',
|
|
14
|
+
],
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
languageOptions: {
|
|
19
|
+
parser: await import('jsonc-eslint-parser'),
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
displayName: 'provider-commercetools',
|
|
3
|
+
preset: '../../jest.preset.js',
|
|
4
|
+
testEnvironment: 'node',
|
|
5
|
+
transform: {
|
|
6
|
+
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
|
|
7
|
+
},
|
|
8
|
+
moduleFileExtensions: ['ts', 'js', 'html'],
|
|
9
|
+
coverageDirectory: '../../coverage/providers/commercetools',
|
|
10
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "provider-commercetools",
|
|
3
|
+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
+
"sourceRoot": "providers/commercetools/src",
|
|
5
|
+
"projectType": "library",
|
|
6
|
+
"release": {
|
|
7
|
+
"version": {
|
|
8
|
+
"currentVersionResolver": "git-tag",
|
|
9
|
+
"fallbackCurrentVersionResolver": "disk",
|
|
10
|
+
"preserveLocalDependencyProtocols": false,
|
|
11
|
+
"manifestRootsToUpdate": ["dist/{projectRoot}"]
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"tags": [],
|
|
15
|
+
"targets": {
|
|
16
|
+
"build": {
|
|
17
|
+
"executor": "@nx/esbuild:esbuild",
|
|
18
|
+
"outputs": ["{options.outputPath}"],
|
|
19
|
+
"options": {
|
|
20
|
+
"outputPath": "dist/providers/commercetools",
|
|
21
|
+
"main": "providers/commercetools/src/index.ts",
|
|
22
|
+
"tsConfig": "providers/commercetools/tsconfig.lib.json",
|
|
23
|
+
"assets": ["providers/commercetools/*.md"],
|
|
24
|
+
"format": ["esm"]
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"nx-release-publish": {
|
|
28
|
+
"options": {
|
|
29
|
+
"packageRoot": "dist/{projectRoot}"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { ClientBuilder } from '@commercetools/ts-client';
|
|
2
|
+
import { createApiBuilderFromCtpClient } from '@commercetools/platform-sdk';
|
|
3
|
+
import { CommercetoolsConfiguration } from '../schema/configuration.schema';
|
|
4
|
+
import { Session } from '@reactionary/core';
|
|
5
|
+
|
|
6
|
+
const ANONYMOUS_SCOPES = ['view_published_products', 'manage_shopping_lists', 'view_shipping_methods', 'manage_customers', 'view_product_selections', 'view_categories', 'view_project_settings', 'manage_order_edits', 'view_sessions', 'view_standalone_prices', 'manage_orders', 'view_tax_categories', 'view_cart_discounts', 'view_discount_codes', 'create_anonymous_token', 'manage_sessions', 'view_products', 'view_types'];
|
|
7
|
+
const GUEST_SCOPES = [...ANONYMOUS_SCOPES];
|
|
8
|
+
const REGISTERED_SCOPES = [...GUEST_SCOPES];
|
|
9
|
+
|
|
10
|
+
export class CommercetoolsClient {
|
|
11
|
+
protected config: CommercetoolsConfiguration;
|
|
12
|
+
|
|
13
|
+
constructor(config: CommercetoolsConfiguration) {
|
|
14
|
+
this.config = config;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public getClient(token?: string) {
|
|
18
|
+
if (token) {
|
|
19
|
+
return this.createClientWithToken(token);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return this.createAnonymousClient();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public async login(username: string, password: string) {
|
|
26
|
+
const scopes = REGISTERED_SCOPES.map(
|
|
27
|
+
(scope) => `${scope}:${this.config.projectKey}`
|
|
28
|
+
).join(' ');
|
|
29
|
+
const queryParams = new URLSearchParams({
|
|
30
|
+
grant_type: 'password',
|
|
31
|
+
username: username,
|
|
32
|
+
password: password,
|
|
33
|
+
scope: scopes,
|
|
34
|
+
});
|
|
35
|
+
const url = `${this.config.authUrl}/oauth/${
|
|
36
|
+
this.config.projectKey
|
|
37
|
+
}/customers/token?${queryParams.toString()}`;
|
|
38
|
+
const headers = {
|
|
39
|
+
Authorization:
|
|
40
|
+
'Basic ' + btoa(this.config.clientId + ':' + this.config.clientSecret),
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const remote = await fetch(url, { method: 'POST', headers });
|
|
44
|
+
const json = await remote.json();
|
|
45
|
+
|
|
46
|
+
return json;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public async guest() {
|
|
50
|
+
const scopes = GUEST_SCOPES.map(
|
|
51
|
+
(scope) => `${scope}:${this.config.projectKey}`
|
|
52
|
+
).join(' ');
|
|
53
|
+
const queryParams = new URLSearchParams({
|
|
54
|
+
grant_type: 'client_credentials',
|
|
55
|
+
scope: scopes,
|
|
56
|
+
});
|
|
57
|
+
const url = `${this.config.authUrl}/oauth/${
|
|
58
|
+
this.config.projectKey
|
|
59
|
+
}/anonymous/token?${queryParams.toString()}`;
|
|
60
|
+
const headers = {
|
|
61
|
+
Authorization:
|
|
62
|
+
'Basic ' + btoa(this.config.clientId + ':' + this.config.clientSecret),
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const remote = await fetch(url, { method: 'POST', headers });
|
|
66
|
+
const json = await remote.json();
|
|
67
|
+
|
|
68
|
+
return json;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public async logout(token: string) {
|
|
72
|
+
const queryParams = new URLSearchParams({
|
|
73
|
+
token: token,
|
|
74
|
+
token_type_hint: 'access_token',
|
|
75
|
+
});
|
|
76
|
+
const url = `${
|
|
77
|
+
this.config.authUrl
|
|
78
|
+
}/oauth/token/revoke?${queryParams.toString()}`;
|
|
79
|
+
const headers = {
|
|
80
|
+
Authorization:
|
|
81
|
+
'Basic ' + btoa(this.config.clientId + ':' + this.config.clientSecret),
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const remote = await fetch(url, { method: 'POST', headers });
|
|
85
|
+
|
|
86
|
+
return remote;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public async introspect(token: string) {
|
|
90
|
+
const queryParams = new URLSearchParams({
|
|
91
|
+
token,
|
|
92
|
+
});
|
|
93
|
+
const url = `${this.config.authUrl}/oauth/introspect?` + queryParams;
|
|
94
|
+
const headers = {
|
|
95
|
+
Authorization:
|
|
96
|
+
'Basic ' + btoa(this.config.clientId + ':' + this.config.clientSecret),
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const remote = await fetch(url, { method: 'POST', headers });
|
|
100
|
+
const json = await remote.json();
|
|
101
|
+
|
|
102
|
+
return json;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
public createAnonymousClient() {
|
|
106
|
+
const scopes = ANONYMOUS_SCOPES.map(
|
|
107
|
+
(scope) => `${scope}:${this.config.projectKey}`
|
|
108
|
+
).join(' ');
|
|
109
|
+
const builder = this.createBaseClientBuilder().withClientCredentialsFlow({
|
|
110
|
+
host: this.config.authUrl,
|
|
111
|
+
projectKey: this.config.projectKey,
|
|
112
|
+
credentials: {
|
|
113
|
+
clientId: this.config.clientId,
|
|
114
|
+
clientSecret: this.config.clientSecret,
|
|
115
|
+
},
|
|
116
|
+
scopes: [scopes],
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
return createApiBuilderFromCtpClient(builder.build());
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
protected createClientWithToken(token: string) {
|
|
123
|
+
const builder = this.createBaseClientBuilder().withExistingTokenFlow(`Bearer ${ token }`, { force: true });
|
|
124
|
+
|
|
125
|
+
return createApiBuilderFromCtpClient(builder.build());
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
protected createBaseClientBuilder() {
|
|
129
|
+
const builder = new ClientBuilder()
|
|
130
|
+
.withProjectKey(this.config.projectKey)
|
|
131
|
+
.withQueueMiddleware({
|
|
132
|
+
concurrency: 20,
|
|
133
|
+
})
|
|
134
|
+
.withHttpMiddleware({
|
|
135
|
+
retryConfig: {
|
|
136
|
+
backoff: true,
|
|
137
|
+
maxRetries: 3,
|
|
138
|
+
retryDelay: 500,
|
|
139
|
+
retryOnAbort: true,
|
|
140
|
+
retryCodes: [500, 429, 420],
|
|
141
|
+
maxDelay: 5000,
|
|
142
|
+
},
|
|
143
|
+
enableRetry: true,
|
|
144
|
+
includeResponseHeaders: true,
|
|
145
|
+
maskSensitiveHeaderData: false,
|
|
146
|
+
host: this.config.apiUrl,
|
|
147
|
+
httpClient: fetch,
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
return builder;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { CartMutationSchema, CartQuerySchema, CartSchema, Client, IdentityMutationSchema, IdentityQuerySchema, IdentitySchema, InventoryQuerySchema, InventorySchema, PriceMutationSchema, PriceQuerySchema, PriceSchema, ProductMutationSchema, ProductQuerySchema, ProductSchema, SearchMutationSchema, SearchQuerySchema, SearchResultSchema } from "@reactionary/core";
|
|
2
|
+
import { CommercetoolsCapabilities } from "../schema/capabilities.schema";
|
|
3
|
+
import { CommercetoolsSearchProvider } from "../providers/search.provider";
|
|
4
|
+
import { CommercetoolsProductProvider } from '../providers/product.provider';
|
|
5
|
+
import { CommercetoolsConfiguration } from "../schema/configuration.schema";
|
|
6
|
+
import { CommercetoolsIdentityProvider } from "../providers/identity.provider";
|
|
7
|
+
import { CommercetoolsCartProvider } from "../providers/cart.provider";
|
|
8
|
+
import { CommercetoolsInventoryProvider } from "../providers/inventory.provider";
|
|
9
|
+
import { CommercetoolsPriceProvider } from "../providers/price.provider";
|
|
10
|
+
import { InventoryMutationSchema } from "core/src/schemas/mutations/inventory.mutation";
|
|
11
|
+
|
|
12
|
+
export function withCommercetoolsCapabilities(configuration: CommercetoolsConfiguration, capabilities: CommercetoolsCapabilities) {
|
|
13
|
+
const client: Partial<Client> = {};
|
|
14
|
+
|
|
15
|
+
if (capabilities.product) {
|
|
16
|
+
client.product = new CommercetoolsProductProvider(configuration, ProductSchema, ProductQuerySchema, ProductMutationSchema);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (capabilities.search) {
|
|
20
|
+
client.search = new CommercetoolsSearchProvider(configuration, SearchResultSchema, SearchQuerySchema, SearchMutationSchema);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (capabilities.identity) {
|
|
24
|
+
client.identity = new CommercetoolsIdentityProvider(configuration, IdentitySchema, IdentityQuerySchema, IdentityMutationSchema);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (capabilities.cart) {
|
|
28
|
+
client.cart = new CommercetoolsCartProvider(configuration, CartSchema, CartQuerySchema, CartMutationSchema);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (capabilities.inventory) {
|
|
32
|
+
client.inventory = new CommercetoolsInventoryProvider(configuration, InventorySchema, InventoryQuerySchema, InventoryMutationSchema);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (capabilities.price) {
|
|
36
|
+
client.price = new CommercetoolsPriceProvider(configuration, PriceSchema, PriceQuerySchema, PriceMutationSchema);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return client;
|
|
40
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from './core/client';
|
|
2
|
+
export * from './core/initialize';
|
|
3
|
+
|
|
4
|
+
export * from './providers/cart.provider';
|
|
5
|
+
export * from './providers/identity.provider';
|
|
6
|
+
export * from './providers/inventory.provider';
|
|
7
|
+
export * from './providers/price.provider';
|
|
8
|
+
export * from './providers/product.provider';
|
|
9
|
+
export * from './providers/search.provider';
|
|
10
|
+
|
|
11
|
+
export * from './schema/capabilities.schema';
|
|
12
|
+
export * from './schema/configuration.schema';
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Cart,
|
|
3
|
+
CartItemSchema,
|
|
4
|
+
CartMutation,
|
|
5
|
+
CartMutationItemAdd,
|
|
6
|
+
CartMutationItemQuantityChange,
|
|
7
|
+
CartMutationItemRemove,
|
|
8
|
+
CartProvider,
|
|
9
|
+
CartQuery,
|
|
10
|
+
Session,
|
|
11
|
+
} from '@reactionary/core';
|
|
12
|
+
import { CommercetoolsConfiguration } from '../schema/configuration.schema';
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import { CommercetoolsClient } from '../core/client';
|
|
15
|
+
import { Cart as CTCart } from '@commercetools/platform-sdk';
|
|
16
|
+
|
|
17
|
+
export class CommercetoolsCartProvider<
|
|
18
|
+
T extends Cart = Cart,
|
|
19
|
+
Q extends CartQuery = CartQuery,
|
|
20
|
+
M extends CartMutation = CartMutation
|
|
21
|
+
> extends CartProvider<T, Q, M> {
|
|
22
|
+
protected config: CommercetoolsConfiguration;
|
|
23
|
+
|
|
24
|
+
constructor(
|
|
25
|
+
config: CommercetoolsConfiguration,
|
|
26
|
+
schema: z.ZodType<T>,
|
|
27
|
+
querySchema: z.ZodType<Q, Q>,
|
|
28
|
+
mutationSchema: z.ZodType<M, M>
|
|
29
|
+
) {
|
|
30
|
+
super(schema, querySchema, mutationSchema);
|
|
31
|
+
|
|
32
|
+
this.config = config;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
protected override async fetch(queries: Q[], session: Session): Promise<T[]> {
|
|
36
|
+
const results = [];
|
|
37
|
+
|
|
38
|
+
for (const query of queries) {
|
|
39
|
+
if (query.cart.key) {
|
|
40
|
+
const client = this.getClient(session);
|
|
41
|
+
const remote = await client
|
|
42
|
+
.withId({ ID: query.cart.key })
|
|
43
|
+
.get()
|
|
44
|
+
.execute();
|
|
45
|
+
|
|
46
|
+
const result = this.composeCart(remote.body);
|
|
47
|
+
|
|
48
|
+
results.push(result);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return results;
|
|
53
|
+
}
|
|
54
|
+
protected override async process(
|
|
55
|
+
mutations: M[],
|
|
56
|
+
session: Session
|
|
57
|
+
): Promise<T> {
|
|
58
|
+
let cart = this.newModel();
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* TODO: Optimize this, since CT as a remote provider allows us to forward multiple changes
|
|
62
|
+
* at once. As part of the current rewrite, this is mostly preserved as was before.
|
|
63
|
+
*/
|
|
64
|
+
for (const mutation of mutations) {
|
|
65
|
+
switch (mutation.mutation) {
|
|
66
|
+
case 'add':
|
|
67
|
+
cart = await this.add(mutation, session);
|
|
68
|
+
break;
|
|
69
|
+
case 'adjustQuantity':
|
|
70
|
+
cart = await this.adjust(mutation, session);
|
|
71
|
+
break;
|
|
72
|
+
case 'remove':
|
|
73
|
+
cart = await this.remove(mutation, session);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return cart;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
protected async adjust(
|
|
81
|
+
payload: CartMutationItemQuantityChange,
|
|
82
|
+
session: Session
|
|
83
|
+
): Promise<T> {
|
|
84
|
+
const client = this.getClient(session);
|
|
85
|
+
|
|
86
|
+
// TODO: Consider whether we can skip this step by proxying the version as part of the CommercetoolsCartIdentifier
|
|
87
|
+
const existing = await client
|
|
88
|
+
.withId({ ID: payload.cart.key })
|
|
89
|
+
.get()
|
|
90
|
+
.execute();
|
|
91
|
+
|
|
92
|
+
const remote = await client
|
|
93
|
+
.withId({ ID: payload.cart.key })
|
|
94
|
+
.post({
|
|
95
|
+
body: {
|
|
96
|
+
version: existing.body.version,
|
|
97
|
+
actions: [
|
|
98
|
+
{
|
|
99
|
+
action: 'changeLineItemQuantity',
|
|
100
|
+
lineItemId: payload.item.key,
|
|
101
|
+
quantity: payload.quantity,
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
})
|
|
106
|
+
.execute();
|
|
107
|
+
|
|
108
|
+
const result = this.composeCart(remote.body);
|
|
109
|
+
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
protected async add(
|
|
114
|
+
payload: CartMutationItemAdd,
|
|
115
|
+
session: Session
|
|
116
|
+
): Promise<T> {
|
|
117
|
+
const client = this.getClient(session);
|
|
118
|
+
|
|
119
|
+
let id = payload.cart.key;
|
|
120
|
+
let version = 0;
|
|
121
|
+
|
|
122
|
+
if (!id) {
|
|
123
|
+
const remoteCart = await client
|
|
124
|
+
.post({
|
|
125
|
+
body: {
|
|
126
|
+
currency: 'USD',
|
|
127
|
+
country: 'US',
|
|
128
|
+
},
|
|
129
|
+
})
|
|
130
|
+
.execute();
|
|
131
|
+
|
|
132
|
+
id = remoteCart.body.id;
|
|
133
|
+
version = remoteCart.body.version;
|
|
134
|
+
} else {
|
|
135
|
+
// TODO: Consider whether we can skip this step by proxying the version as part of the CommercetoolsCartIdentifier
|
|
136
|
+
const existing = await client.withId({ ID: payload.cart.key }).get().execute();
|
|
137
|
+
|
|
138
|
+
version = existing.body.version;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const remoteAdd = await client
|
|
142
|
+
.withId({ ID: id })
|
|
143
|
+
.post({
|
|
144
|
+
body: {
|
|
145
|
+
version: version,
|
|
146
|
+
actions: [
|
|
147
|
+
{
|
|
148
|
+
action: 'addLineItem',
|
|
149
|
+
quantity: payload.quantity,
|
|
150
|
+
productId: payload.product.key,
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
},
|
|
154
|
+
})
|
|
155
|
+
.execute();
|
|
156
|
+
|
|
157
|
+
const result = this.composeCart(remoteAdd.body);
|
|
158
|
+
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
protected async remove(
|
|
163
|
+
payload: CartMutationItemRemove,
|
|
164
|
+
session: Session
|
|
165
|
+
): Promise<T> {
|
|
166
|
+
const client = this.getClient(session);
|
|
167
|
+
|
|
168
|
+
// TODO: Consider whether we can skip this step by proxying the version as part of the CommercetoolsCartIdentifier
|
|
169
|
+
const existing = await client
|
|
170
|
+
.withId({ ID: payload.cart.key })
|
|
171
|
+
.get()
|
|
172
|
+
.execute();
|
|
173
|
+
|
|
174
|
+
const remote = await client
|
|
175
|
+
.withId({ ID: payload.cart.key })
|
|
176
|
+
.post({
|
|
177
|
+
body: {
|
|
178
|
+
version: existing.body.version,
|
|
179
|
+
actions: [
|
|
180
|
+
{
|
|
181
|
+
action: 'removeLineItem',
|
|
182
|
+
lineItemId: payload.item.key,
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
},
|
|
186
|
+
})
|
|
187
|
+
.execute();
|
|
188
|
+
|
|
189
|
+
const result = this.composeCart(remote.body);
|
|
190
|
+
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
protected getClient(session: Session) {
|
|
195
|
+
const client = new CommercetoolsClient(this.config).getClient(
|
|
196
|
+
session.identity.token
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
const cartClient = client
|
|
200
|
+
.withProjectKey({ projectKey: this.config.projectKey })
|
|
201
|
+
.carts();
|
|
202
|
+
|
|
203
|
+
return cartClient;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
protected composeCart(remote: CTCart): T {
|
|
207
|
+
const result = this.newModel();
|
|
208
|
+
|
|
209
|
+
result.identifier.key = remote.id;
|
|
210
|
+
|
|
211
|
+
for (const remoteItem of remote.lineItems) {
|
|
212
|
+
const item = CartItemSchema.parse({});
|
|
213
|
+
|
|
214
|
+
item.identifier.key = remoteItem.id;
|
|
215
|
+
item.product.key = remoteItem.productId;
|
|
216
|
+
item.quantity = remoteItem.quantity;
|
|
217
|
+
|
|
218
|
+
result.items.push(item);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return result;
|
|
222
|
+
}
|
|
223
|
+
}
|