@reactionary/source 0.0.52 → 0.2.16
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/.env-template +19 -0
- package/.github/workflows/pull-request.yml +3 -1
- package/.github/workflows/release.yml +9 -0
- package/.vscode/extensions.json +0 -2
- package/LICENSE +21 -0
- package/README.md +175 -23
- package/core/package.json +6 -3
- package/core/src/cache/cache.interface.ts +1 -0
- package/core/src/cache/index.ts +4 -0
- package/core/src/cache/memory-cache.ts +30 -2
- package/core/src/cache/noop-cache.ts +15 -1
- package/core/src/cache/redis-cache.ts +20 -0
- package/core/src/client/client-builder.ts +71 -54
- package/core/src/client/client.ts +9 -47
- package/core/src/client/index.ts +2 -0
- package/core/src/decorators/index.ts +1 -0
- package/core/src/decorators/reactionary.decorator.ts +203 -34
- package/core/src/index.ts +6 -19
- package/core/src/initialization.ts +1 -18
- package/core/src/metrics/metrics.ts +67 -0
- package/core/src/providers/analytics.provider.ts +1 -6
- package/core/src/providers/base.provider.ts +5 -69
- package/core/src/providers/cart.provider.ts +15 -55
- package/core/src/providers/category.provider.ts +7 -11
- package/core/src/providers/checkout.provider.ts +17 -15
- package/core/src/providers/identity.provider.ts +6 -8
- package/core/src/providers/index.ts +2 -1
- package/core/src/providers/inventory.provider.ts +15 -5
- package/core/src/providers/order-search.provider.ts +29 -0
- package/core/src/providers/order.provider.ts +47 -15
- package/core/src/providers/price.provider.ts +30 -36
- package/core/src/providers/product-search.provider.ts +61 -0
- package/core/src/providers/product.provider.ts +71 -12
- package/core/src/providers/profile.provider.ts +74 -14
- package/core/src/providers/store.provider.ts +3 -5
- package/core/src/schemas/capabilities.schema.ts +10 -3
- package/core/src/schemas/errors/generic.error.ts +9 -0
- package/core/src/schemas/errors/index.ts +4 -0
- package/core/src/schemas/errors/invalid-input.error.ts +9 -0
- package/core/src/schemas/errors/invalid-output.error.ts +9 -0
- package/core/src/schemas/errors/not-found.error.ts +9 -0
- package/core/src/schemas/index.ts +7 -0
- package/core/src/schemas/models/analytics.model.ts +2 -1
- package/core/src/schemas/models/base.model.ts +6 -24
- package/core/src/schemas/models/cart.model.ts +5 -8
- package/core/src/schemas/models/category.model.ts +4 -9
- package/core/src/schemas/models/checkout.model.ts +6 -7
- package/core/src/schemas/models/cost.model.ts +4 -3
- package/core/src/schemas/models/currency.model.ts +2 -1
- package/core/src/schemas/models/identifiers.model.ts +106 -62
- package/core/src/schemas/models/identity.model.ts +10 -19
- package/core/src/schemas/models/index.ts +2 -1
- package/core/src/schemas/models/inventory.model.ts +8 -5
- package/core/src/schemas/models/order-search.model.ts +28 -0
- package/core/src/schemas/models/order.model.ts +20 -26
- package/core/src/schemas/models/payment.model.ts +14 -17
- package/core/src/schemas/models/price.model.ts +11 -11
- package/core/src/schemas/models/product-search.model.ts +42 -0
- package/core/src/schemas/models/product.model.ts +64 -22
- package/core/src/schemas/models/profile.model.ts +19 -22
- package/core/src/schemas/models/shipping-method.model.ts +24 -29
- package/core/src/schemas/models/store.model.ts +9 -5
- package/core/src/schemas/mutations/analytics.mutation.ts +8 -7
- package/core/src/schemas/mutations/base.mutation.ts +2 -1
- package/core/src/schemas/mutations/cart.mutation.ts +33 -33
- package/core/src/schemas/mutations/checkout.mutation.ts +23 -30
- package/core/src/schemas/mutations/identity.mutation.ts +4 -3
- package/core/src/schemas/mutations/profile.mutation.ts +38 -3
- package/core/src/schemas/queries/base.query.ts +2 -1
- package/core/src/schemas/queries/cart.query.ts +3 -3
- package/core/src/schemas/queries/category.query.ts +18 -18
- package/core/src/schemas/queries/checkout.query.ts +7 -9
- package/core/src/schemas/queries/identity.query.ts +2 -1
- package/core/src/schemas/queries/index.ts +2 -1
- package/core/src/schemas/queries/inventory.query.ts +5 -5
- package/core/src/schemas/queries/order-search.query.ts +10 -0
- package/core/src/schemas/queries/order.query.ts +3 -2
- package/core/src/schemas/queries/price.query.ts +10 -4
- package/core/src/schemas/queries/product-search.query.ts +16 -0
- package/core/src/schemas/queries/product.query.ts +13 -6
- package/core/src/schemas/queries/profile.query.ts +5 -2
- package/core/src/schemas/queries/store.query.ts +6 -5
- package/core/src/schemas/result.ts +107 -0
- package/core/src/schemas/session.schema.ts +4 -4
- package/core/src/test/reactionary.decorator.spec.ts +249 -0
- package/core/src/zod-utils.ts +19 -0
- package/core/tsconfig.json +1 -1
- package/core/tsconfig.spec.json +2 -26
- package/core/vitest.config.ts +14 -0
- package/documentation/1-purpose.md +114 -0
- package/documentation/2-getting-started.md +229 -0
- package/documentation/3-querying-and-changing-data.md +74 -0
- package/documentation/4-product-data.md +107 -0
- package/documentation/5-cart-and-checkout.md +211 -0
- package/documentation/6-product-search.md +143 -0
- package/documentation/7-marketing.md +3 -0
- package/eslint.config.mjs +1 -0
- package/examples/node/eslint.config.mjs +1 -4
- package/examples/node/package.json +10 -3
- package/examples/node/project.json +4 -1
- package/examples/node/src/basic/basic-node-provider-model-extension.spec.ts +22 -23
- package/examples/node/src/basic/basic-node-provider-query-extension.spec.ts +15 -11
- package/examples/node/src/basic/basic-node-setup.spec.ts +44 -28
- package/examples/node/src/basic/client-creation.spec.ts +53 -0
- package/examples/node/src/capabilities/cart.spec.ts +255 -0
- package/examples/node/src/capabilities/category.spec.ts +193 -0
- package/examples/node/src/capabilities/checkout.spec.ts +341 -0
- package/examples/node/src/capabilities/identity.spec.ts +93 -0
- package/examples/node/src/capabilities/inventory.spec.ts +66 -0
- package/examples/node/src/capabilities/order-search.spec.ts +265 -0
- package/examples/node/src/capabilities/order.spec.ts +91 -0
- package/examples/node/src/capabilities/price.spec.ts +51 -0
- package/examples/node/src/capabilities/product-search.spec.ts +293 -0
- package/examples/node/src/capabilities/product.spec.ts +122 -0
- package/examples/node/src/capabilities/profile.spec.ts +316 -0
- package/examples/node/src/capabilities/store.spec.ts +26 -0
- package/examples/node/src/utils.ts +147 -0
- package/examples/node/tsconfig.json +9 -12
- package/examples/node/tsconfig.lib.json +1 -2
- package/examples/node/tsconfig.spec.json +2 -14
- package/examples/node/vitest.config.ts +14 -0
- package/migrations.json +22 -5
- package/nx.json +8 -47
- package/package.json +24 -96
- package/providers/algolia/README.md +39 -2
- package/providers/algolia/package.json +2 -1
- package/providers/algolia/src/core/initialize.ts +7 -14
- package/providers/algolia/src/index.ts +2 -4
- package/providers/algolia/src/providers/index.ts +1 -0
- package/providers/algolia/src/providers/product-search.provider.ts +241 -0
- package/providers/algolia/src/schema/capabilities.schema.ts +2 -3
- package/providers/algolia/src/schema/index.ts +3 -0
- package/providers/algolia/src/schema/search.schema.ts +8 -8
- package/providers/algolia/tsconfig.json +1 -1
- package/providers/algolia/tsconfig.lib.json +1 -1
- package/providers/algolia/tsconfig.spec.json +2 -14
- package/providers/algolia/vitest.config.ts +14 -0
- package/providers/commercetools/README.md +30 -3
- package/providers/commercetools/package.json +2 -1
- package/providers/commercetools/src/core/client.ts +178 -99
- package/providers/commercetools/src/core/initialize.ts +130 -74
- package/providers/commercetools/src/core/token-cache.ts +45 -0
- package/providers/commercetools/src/index.ts +3 -2
- package/providers/commercetools/src/providers/cart.provider.ts +281 -341
- package/providers/commercetools/src/providers/category.provider.ts +223 -138
- package/providers/commercetools/src/providers/checkout.provider.ts +631 -449
- package/providers/commercetools/src/providers/identity.provider.ts +50 -29
- package/providers/commercetools/src/providers/index.ts +2 -2
- package/providers/commercetools/src/providers/inventory.provider.ts +76 -74
- package/providers/commercetools/src/providers/order-search.provider.ts +220 -0
- package/providers/commercetools/src/providers/order.provider.ts +96 -61
- package/providers/commercetools/src/providers/price.provider.ts +147 -117
- package/providers/commercetools/src/providers/product-search.provider.ts +528 -0
- package/providers/commercetools/src/providers/product.provider.ts +249 -74
- package/providers/commercetools/src/providers/profile.provider.ts +445 -28
- package/providers/commercetools/src/providers/store.provider.ts +54 -40
- package/providers/commercetools/src/schema/capabilities.schema.ts +3 -1
- package/providers/commercetools/src/schema/commercetools.schema.ts +17 -3
- package/providers/commercetools/src/schema/configuration.schema.ts +1 -0
- package/providers/commercetools/src/schema/session.schema.ts +7 -0
- package/providers/commercetools/src/test/caching.spec.ts +82 -0
- package/providers/commercetools/src/test/identity.spec.ts +109 -0
- package/providers/commercetools/src/test/test-utils.ts +21 -19
- package/providers/commercetools/tsconfig.json +1 -1
- package/providers/commercetools/tsconfig.lib.json +1 -1
- package/providers/commercetools/tsconfig.spec.json +2 -14
- package/providers/commercetools/vitest.config.ts +15 -0
- package/providers/fake/README.md +20 -4
- package/providers/fake/package.json +2 -1
- package/providers/fake/src/core/initialize.ts +47 -49
- package/providers/fake/src/providers/analytics.provider.ts +5 -7
- package/providers/fake/src/providers/cart.provider.ts +163 -92
- package/providers/fake/src/providers/category.provider.ts +78 -50
- package/providers/fake/src/providers/checkout.provider.ts +254 -0
- package/providers/fake/src/providers/identity.provider.ts +57 -65
- package/providers/fake/src/providers/index.ts +6 -2
- package/providers/fake/src/providers/inventory.provider.ts +40 -36
- package/providers/fake/src/providers/order-search.provider.ts +78 -0
- package/providers/fake/src/providers/order.provider.ts +106 -0
- package/providers/fake/src/providers/price.provider.ts +93 -41
- package/providers/fake/src/providers/product-search.provider.ts +206 -0
- package/providers/fake/src/providers/product.provider.ts +56 -41
- package/providers/fake/src/providers/profile.provider.ts +147 -0
- package/providers/fake/src/providers/store.provider.ts +30 -20
- package/providers/fake/src/schema/capabilities.schema.ts +5 -1
- package/providers/fake/src/test/cart.provider.spec.ts +59 -80
- package/providers/fake/src/test/category.provider.spec.ts +145 -87
- package/providers/fake/src/test/checkout.provider.spec.ts +222 -0
- package/providers/fake/src/test/order-search.provider.spec.ts +50 -0
- package/providers/fake/src/test/order.provider.spec.ts +44 -0
- package/providers/fake/src/test/price.provider.spec.ts +50 -45
- package/providers/fake/src/test/product.provider.spec.ts +15 -7
- package/providers/fake/src/test/profile.provider.spec.ts +167 -0
- package/providers/fake/tsconfig.json +1 -1
- package/providers/fake/tsconfig.lib.json +1 -1
- package/providers/fake/tsconfig.spec.json +2 -12
- package/providers/fake/vitest.config.ts +14 -0
- package/providers/medusa/README.md +30 -0
- package/providers/medusa/TESTING.md +98 -0
- package/providers/medusa/eslint.config.mjs +19 -0
- package/providers/medusa/package.json +22 -0
- package/providers/medusa/project.json +34 -0
- package/providers/medusa/src/core/client.ts +370 -0
- package/providers/medusa/src/core/initialize.ts +78 -0
- package/providers/medusa/src/index.ts +13 -0
- package/providers/medusa/src/providers/cart.provider.ts +575 -0
- package/providers/medusa/src/providers/category.provider.ts +247 -0
- package/providers/medusa/src/providers/checkout.provider.ts +636 -0
- package/providers/medusa/src/providers/identity.provider.ts +137 -0
- package/providers/medusa/src/providers/inventory.provider.ts +173 -0
- package/providers/medusa/src/providers/order-search.provider.ts +202 -0
- package/providers/medusa/src/providers/order.provider.ts +226 -0
- package/providers/medusa/src/providers/price.provider.ts +140 -0
- package/providers/medusa/src/providers/product-search.provider.ts +243 -0
- package/providers/medusa/src/providers/product.provider.ts +261 -0
- package/providers/medusa/src/providers/profile.provider.ts +392 -0
- package/providers/medusa/src/schema/capabilities.schema.ts +18 -0
- package/providers/medusa/src/schema/configuration.schema.ts +11 -0
- package/providers/medusa/src/schema/medusa.schema.ts +31 -0
- package/providers/medusa/src/test/cart.provider.spec.ts +240 -0
- package/providers/medusa/src/test/category.provider.spec.ts +231 -0
- package/providers/medusa/src/test/checkout.spec.ts +349 -0
- package/providers/medusa/src/test/identity.provider.spec.ts +122 -0
- package/providers/medusa/src/test/inventory.provider.spec.ts +88 -0
- package/providers/medusa/src/test/large-cart.provider.spec.ts +103 -0
- package/providers/medusa/src/test/price.provider.spec.ts +104 -0
- package/providers/medusa/src/test/product.provider.spec.ts +146 -0
- package/providers/medusa/src/test/search.provider.spec.ts +203 -0
- package/providers/medusa/src/test/test-utils.ts +13 -0
- package/providers/medusa/src/utils/medusa-helpers.ts +89 -0
- package/providers/medusa/tsconfig.json +21 -0
- package/providers/medusa/tsconfig.lib.json +9 -0
- package/providers/medusa/tsconfig.spec.json +4 -0
- package/providers/medusa/vitest.config.ts +15 -0
- package/providers/meilisearch/README.md +48 -0
- package/providers/meilisearch/eslint.config.mjs +22 -0
- package/providers/meilisearch/package.json +13 -0
- package/providers/meilisearch/project.json +34 -0
- package/providers/meilisearch/src/core/initialize.ts +21 -0
- package/providers/meilisearch/src/index.ts +6 -0
- package/providers/meilisearch/src/providers/index.ts +1 -0
- package/providers/meilisearch/src/providers/order-search.provider.ts +222 -0
- package/providers/meilisearch/src/providers/product-search.provider.ts +251 -0
- package/providers/meilisearch/src/schema/capabilities.schema.ts +10 -0
- package/providers/meilisearch/src/schema/configuration.schema.ts +11 -0
- package/providers/meilisearch/src/schema/index.ts +3 -0
- package/providers/meilisearch/src/schema/search.schema.ts +14 -0
- package/providers/meilisearch/tsconfig.json +24 -0
- package/providers/meilisearch/tsconfig.lib.json +10 -0
- package/providers/meilisearch/tsconfig.spec.json +4 -0
- package/providers/meilisearch/vitest.config.ts +14 -0
- package/providers/posthog/package.json +2 -1
- package/providers/posthog/tsconfig.json +1 -1
- package/tsconfig.base.json +5 -0
- package/vitest.config.ts +10 -0
- package/core/src/providers/search.provider.ts +0 -18
- package/core/src/schemas/models/search.model.ts +0 -36
- package/core/src/schemas/queries/search.query.ts +0 -9
- package/examples/next/.swcrc +0 -30
- package/examples/next/eslint.config.mjs +0 -21
- package/examples/next/index.d.ts +0 -6
- package/examples/next/next-env.d.ts +0 -5
- package/examples/next/next.config.js +0 -31
- package/examples/next/project.json +0 -9
- package/examples/next/public/.gitkeep +0 -0
- package/examples/next/public/favicon.ico +0 -0
- package/examples/next/src/app/global.css +0 -0
- package/examples/next/src/app/layout.tsx +0 -18
- package/examples/next/src/app/page.module.scss +0 -2
- package/examples/next/src/app/page.tsx +0 -47
- package/examples/next/src/instrumentation.ts +0 -9
- package/examples/next/tsconfig.json +0 -44
- package/examples/node/jest.config.ts +0 -10
- package/jest.config.ts +0 -6
- package/jest.preset.js +0 -3
- package/providers/algolia/jest.config.ts +0 -10
- package/providers/algolia/src/providers/product.provider.ts +0 -66
- package/providers/algolia/src/providers/search.provider.ts +0 -106
- package/providers/algolia/src/test/search.provider.spec.ts +0 -91
- package/providers/commercetools/jest.config.cjs +0 -10
- package/providers/commercetools/src/providers/search.provider.ts +0 -96
- package/providers/commercetools/src/test/cart.provider.spec.ts +0 -199
- package/providers/commercetools/src/test/category.provider.spec.ts +0 -168
- package/providers/commercetools/src/test/checkout.provider.spec.ts +0 -312
- package/providers/commercetools/src/test/identity.provider.spec.ts +0 -88
- package/providers/commercetools/src/test/inventory.provider.spec.ts +0 -41
- package/providers/commercetools/src/test/price.provider.spec.ts +0 -81
- package/providers/commercetools/src/test/product.provider.spec.ts +0 -80
- package/providers/commercetools/src/test/profile.provider.spec.ts +0 -49
- package/providers/commercetools/src/test/search.provider.spec.ts +0 -61
- package/providers/commercetools/src/test/store.provider.spec.ts +0 -37
- package/providers/fake/jest.config.cjs +0 -10
- package/providers/fake/src/providers/search.provider.ts +0 -132
|
@@ -1,16 +1,4 @@
|
|
|
1
1
|
{
|
|
2
|
-
"extends": "./tsconfig.json",
|
|
3
|
-
"
|
|
4
|
-
"module": "commonjs",
|
|
5
|
-
"moduleResolution": "node",
|
|
6
|
-
"verbatimModuleSyntax": false,
|
|
7
|
-
"outDir": "../../dist/out-tsc",
|
|
8
|
-
"types": ["jest", "node"]
|
|
9
|
-
},
|
|
10
|
-
"include": [
|
|
11
|
-
"jest.config.ts",
|
|
12
|
-
"src/**/*.test.ts",
|
|
13
|
-
"src/**/*.spec.ts",
|
|
14
|
-
"src/**/*.d.ts"
|
|
15
|
-
]
|
|
2
|
+
"extends": "./tsconfig.lib.json",
|
|
3
|
+
"exclude": []
|
|
16
4
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineConfig, defineProject } from 'vitest/config';
|
|
2
|
+
import tsconfigPaths from 'vite-tsconfig-paths';
|
|
3
|
+
import { resolve } from 'path';
|
|
4
|
+
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
|
|
5
|
+
|
|
6
|
+
export default defineProject({
|
|
7
|
+
plugins: [nxViteTsPaths()],
|
|
8
|
+
test: {
|
|
9
|
+
root: resolve(__dirname),
|
|
10
|
+
globals: true,
|
|
11
|
+
environment: 'node',
|
|
12
|
+
include: ['src/**/*.spec.ts'],
|
|
13
|
+
},
|
|
14
|
+
});
|
|
@@ -1,6 +1,33 @@
|
|
|
1
|
-
# provider
|
|
1
|
+
# Commmercetools provider for Reactionary
|
|
2
|
+
|
|
3
|
+
## Supports
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
| Feature | Support | Notes |
|
|
7
|
+
| ----------- | ----------- | --------- |
|
|
8
|
+
| product | Full | |
|
|
9
|
+
| productSearch | Full | |
|
|
10
|
+
| identity | Full | |
|
|
11
|
+
| cart | Full | |
|
|
12
|
+
| checkout | Full | |
|
|
13
|
+
| order | Full | |
|
|
14
|
+
| inventory | Full | |
|
|
15
|
+
| price | Full | |
|
|
16
|
+
| category | Full | |
|
|
17
|
+
| store | Full | |
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## Notes
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
2
30
|
|
|
3
|
-
This library was generated with [Nx](https://nx.dev).
|
|
4
31
|
|
|
5
32
|
## Building
|
|
6
33
|
|
|
@@ -11,7 +38,7 @@ Run `nx build provider-commercetools` to build the library.
|
|
|
11
38
|
Run `nx test provider-commercetools` to execute the unit tests via [Jest](https://jestjs.io).
|
|
12
39
|
|
|
13
40
|
|
|
14
|
-
|
|
41
|
+
## Assumptions for backend config
|
|
15
42
|
|
|
16
43
|
- You will have 2 different channels for prices, one called `Offer Price` and one called `List Price`
|
|
17
44
|
- ProductVariants will all have unique SKU values.
|
|
@@ -1,70 +1,92 @@
|
|
|
1
|
+
import { ClientBuilder } from '@commercetools/ts-client';
|
|
1
2
|
import {
|
|
2
|
-
|
|
3
|
-
type
|
|
4
|
-
|
|
5
|
-
type TokenStore,
|
|
6
|
-
} from '@commercetools/ts-client';
|
|
7
|
-
import { createApiBuilderFromCtpClient } from '@commercetools/platform-sdk';
|
|
3
|
+
createApiBuilderFromCtpClient,
|
|
4
|
+
type ApiRoot,
|
|
5
|
+
} from '@commercetools/platform-sdk';
|
|
8
6
|
import type { CommercetoolsConfiguration } from '../schema/configuration.schema.js';
|
|
9
7
|
import { randomUUID } from 'crypto';
|
|
10
8
|
import {
|
|
11
9
|
AnonymousIdentitySchema,
|
|
12
|
-
GuestIdentitySchema,
|
|
13
10
|
RegisteredIdentitySchema,
|
|
11
|
+
type AnonymousIdentity,
|
|
12
|
+
type GuestIdentity,
|
|
13
|
+
type RegisteredIdentity,
|
|
14
14
|
type RequestContext,
|
|
15
15
|
} from '@reactionary/core';
|
|
16
16
|
import * as crypto from 'crypto';
|
|
17
|
-
import createDebug from 'debug'
|
|
18
|
-
|
|
17
|
+
import createDebug from 'debug';
|
|
18
|
+
import { RequestContextTokenCache } from './token-cache.js';
|
|
19
|
+
const debug = createDebug('reactionary:commercetools');
|
|
19
20
|
|
|
21
|
+
export class CommercetoolsAPI {
|
|
22
|
+
protected config: CommercetoolsConfiguration;
|
|
23
|
+
protected context: RequestContext;
|
|
24
|
+
protected cache: RequestContextTokenCache;
|
|
25
|
+
protected client: Promise<ApiRoot> | undefined;
|
|
26
|
+
protected adminClient: Promise<ApiRoot> | undefined;
|
|
20
27
|
|
|
28
|
+
constructor(config: CommercetoolsConfiguration, context: RequestContext) {
|
|
29
|
+
this.config = config;
|
|
30
|
+
this.context = context;
|
|
31
|
+
this.cache = new RequestContextTokenCache(this.context);
|
|
32
|
+
}
|
|
21
33
|
|
|
34
|
+
public async getClient() {
|
|
35
|
+
if (!this.client) {
|
|
36
|
+
this.client = this.createClient();
|
|
37
|
+
}
|
|
22
38
|
|
|
23
|
-
|
|
24
|
-
|
|
39
|
+
return this.client;
|
|
40
|
+
}
|
|
25
41
|
|
|
26
|
-
public async
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
42
|
+
public async getAdminClient() {
|
|
43
|
+
if (!this.adminClient) {
|
|
44
|
+
this.adminClient = this.createAdminClient();
|
|
45
|
+
}
|
|
30
46
|
|
|
31
|
-
return
|
|
32
|
-
refreshToken: identity.refresh_token,
|
|
33
|
-
token: identity.token || '',
|
|
34
|
-
expirationTime: identity.expiry.getTime(),
|
|
35
|
-
};
|
|
47
|
+
return this.adminClient;
|
|
36
48
|
}
|
|
37
49
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
50
|
+
protected async createAdminClient() {
|
|
51
|
+
let builder = this.createBaseClientBuilder();
|
|
52
|
+
builder = builder.withAnonymousSessionFlow({
|
|
53
|
+
credentials: {
|
|
54
|
+
clientId: this.config.clientId,
|
|
55
|
+
clientSecret: this.config.clientSecret,
|
|
56
|
+
},
|
|
57
|
+
host: this.config.authUrl,
|
|
58
|
+
projectKey: this.config.projectKey,
|
|
59
|
+
});
|
|
43
60
|
|
|
44
|
-
|
|
45
|
-
identity.token = cache.token;
|
|
46
|
-
identity.expiry = new Date(cache.expirationTime);
|
|
61
|
+
return createApiBuilderFromCtpClient(builder.build());
|
|
47
62
|
}
|
|
48
|
-
}
|
|
49
63
|
|
|
64
|
+
protected async createClient() {
|
|
65
|
+
let session = await this.cache.get();
|
|
66
|
+
const isNewSession = !session || !session.refreshToken;
|
|
50
67
|
|
|
68
|
+
if (isNewSession) {
|
|
69
|
+
await this.becomeGuest();
|
|
51
70
|
|
|
52
|
-
|
|
53
|
-
|
|
71
|
+
session = await this.cache.get();
|
|
72
|
+
}
|
|
54
73
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
74
|
+
let builder = this.createBaseClientBuilder();
|
|
75
|
+
builder = builder.withRefreshTokenFlow({
|
|
76
|
+
credentials: {
|
|
77
|
+
clientId: this.config.clientId,
|
|
78
|
+
clientSecret: this.config.clientSecret,
|
|
79
|
+
},
|
|
80
|
+
host: this.config.authUrl,
|
|
81
|
+
projectKey: this.config.projectKey,
|
|
82
|
+
refreshToken: session?.refreshToken || '',
|
|
83
|
+
tokenCache: this.cache,
|
|
84
|
+
});
|
|
58
85
|
|
|
59
|
-
|
|
60
|
-
return this.createClient(reqCtx);
|
|
86
|
+
return createApiBuilderFromCtpClient(builder.build());
|
|
61
87
|
}
|
|
62
88
|
|
|
63
|
-
public async register(
|
|
64
|
-
username: string,
|
|
65
|
-
password: string,
|
|
66
|
-
reqCtx: RequestContext
|
|
67
|
-
) {
|
|
89
|
+
public async register(username: string, password: string) {
|
|
68
90
|
const registrationBuilder =
|
|
69
91
|
this.createBaseClientBuilder().withAnonymousSessionFlow({
|
|
70
92
|
host: this.config.authUrl,
|
|
@@ -92,19 +114,13 @@ export class CommercetoolsClient {
|
|
|
92
114
|
})
|
|
93
115
|
.execute();
|
|
94
116
|
|
|
95
|
-
const login = await this.login(username, password
|
|
117
|
+
const login = await this.login(username, password);
|
|
96
118
|
|
|
97
119
|
return login;
|
|
98
120
|
}
|
|
99
121
|
|
|
100
|
-
public async login(
|
|
101
|
-
|
|
102
|
-
password: string,
|
|
103
|
-
reqCtx: RequestContext
|
|
104
|
-
) {
|
|
105
|
-
const cache = new RequestContextTokenCache(reqCtx);
|
|
106
|
-
|
|
107
|
-
const loginBuilder = this.createBaseClientBuilder().withPasswordFlow({
|
|
122
|
+
public async login(username: string, password: string) {
|
|
123
|
+
const loginBuilder = this.createBaseClientBuilder().withPasswordFlow({
|
|
108
124
|
host: this.config.authUrl,
|
|
109
125
|
projectKey: this.config.projectKey,
|
|
110
126
|
credentials: {
|
|
@@ -112,7 +128,7 @@ export class CommercetoolsClient {
|
|
|
112
128
|
clientSecret: this.config.clientSecret,
|
|
113
129
|
user: { username, password },
|
|
114
130
|
},
|
|
115
|
-
tokenCache: cache,
|
|
131
|
+
tokenCache: this.cache,
|
|
116
132
|
scopes: this.config.scopes,
|
|
117
133
|
});
|
|
118
134
|
|
|
@@ -130,78 +146,136 @@ export class CommercetoolsClient {
|
|
|
130
146
|
})
|
|
131
147
|
.execute();
|
|
132
148
|
|
|
133
|
-
|
|
134
|
-
|
|
149
|
+
const self = await loginClient
|
|
150
|
+
.withProjectKey({ projectKey: this.config.projectKey })
|
|
151
|
+
.me()
|
|
152
|
+
.get({})
|
|
153
|
+
.execute();
|
|
154
|
+
|
|
155
|
+
return RegisteredIdentitySchema.parse({
|
|
135
156
|
type: 'Registered',
|
|
136
|
-
logonId: username,
|
|
137
157
|
id: {
|
|
138
|
-
userId:
|
|
158
|
+
userId: self.body.id,
|
|
139
159
|
},
|
|
140
160
|
});
|
|
161
|
+
}
|
|
141
162
|
|
|
142
|
-
|
|
163
|
+
public async logout() {
|
|
164
|
+
await this.cache.set({ token: '', refreshToken: '', expirationTime: 0 });
|
|
165
|
+
|
|
166
|
+
// TODO: We could do token revocation here, if we wanted to. The above simply whacks the session.
|
|
167
|
+
const identity = {
|
|
168
|
+
type: 'Anonymous'
|
|
169
|
+
} satisfies AnonymousIdentity;
|
|
170
|
+
return identity;
|
|
143
171
|
}
|
|
144
172
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
173
|
+
// FIXME: This can fail if the short-lived access token has expired. In other words, probably missing a token refresh.
|
|
174
|
+
public async introspect(): Promise<
|
|
175
|
+
AnonymousIdentity | GuestIdentity | RegisteredIdentity
|
|
176
|
+
> {
|
|
177
|
+
const session = await this.cache.get();
|
|
148
178
|
|
|
149
|
-
|
|
179
|
+
if (!session || !session.token) {
|
|
180
|
+
const identity = {
|
|
181
|
+
type: 'Anonymous'
|
|
182
|
+
} satisfies AnonymousIdentity;
|
|
150
183
|
|
|
151
|
-
|
|
184
|
+
return identity;
|
|
185
|
+
}
|
|
152
186
|
|
|
153
|
-
|
|
154
|
-
|
|
187
|
+
const authHeader =
|
|
188
|
+
'Basic ' +
|
|
189
|
+
Buffer.from(
|
|
190
|
+
`${this.config.clientId}:${this.config.clientSecret}`
|
|
191
|
+
).toString('base64');
|
|
192
|
+
const introspectionUrl = `${this.config.authUrl}/oauth/introspect`;
|
|
193
|
+
|
|
194
|
+
const response = await fetch(introspectionUrl, {
|
|
195
|
+
method: 'POST',
|
|
196
|
+
headers: {
|
|
197
|
+
Authorization: authHeader,
|
|
198
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
199
|
+
},
|
|
200
|
+
body: new URLSearchParams({
|
|
201
|
+
token: session.token,
|
|
202
|
+
}),
|
|
203
|
+
});
|
|
155
204
|
|
|
156
|
-
protected createClient(reqCtx: RequestContext) {
|
|
157
|
-
const cache = new RequestContextTokenCache(reqCtx);
|
|
158
205
|
|
|
159
|
-
|
|
160
|
-
|
|
206
|
+
const body = await response.json();
|
|
207
|
+
if (!body) {
|
|
208
|
+
return AnonymousIdentitySchema.parse({});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const scopes: string = body.scope + '';
|
|
212
|
+
|
|
213
|
+
// FIXME: Map unmapped user_id...
|
|
214
|
+
if (scopes.indexOf('anonymous_id') > -1) {
|
|
215
|
+
const s = scopes.split(' ');
|
|
216
|
+
const idScope = s.find((x) => x.startsWith('anonymous_id'));
|
|
217
|
+
const id = idScope?.split(':')[1] || '';
|
|
218
|
+
const identity = {
|
|
161
219
|
id: {
|
|
162
|
-
userId:
|
|
220
|
+
userId: id,
|
|
163
221
|
},
|
|
164
222
|
type: 'Guest',
|
|
165
|
-
}
|
|
166
|
-
}
|
|
223
|
+
} satisfies GuestIdentity;
|
|
167
224
|
|
|
168
|
-
|
|
169
|
-
|
|
225
|
+
return identity;
|
|
226
|
+
}
|
|
170
227
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
},
|
|
180
|
-
tokenCache: cache,
|
|
181
|
-
});
|
|
182
|
-
} else {
|
|
183
|
-
builder = builder.withRefreshTokenFlow({
|
|
184
|
-
credentials: {
|
|
185
|
-
clientId: this.config.clientId,
|
|
186
|
-
clientSecret: this.config.clientSecret,
|
|
228
|
+
// FIXME: Map unmapped user_id...
|
|
229
|
+
if (scopes.indexOf('customer_id') > -1) {
|
|
230
|
+
const s = scopes.split(' ');
|
|
231
|
+
const idScope = s.find((x: any) => x.startsWith('customer_id'));
|
|
232
|
+
const id = idScope?.split(':')[1] || '';
|
|
233
|
+
const identity = {
|
|
234
|
+
id: {
|
|
235
|
+
userId: id,
|
|
187
236
|
},
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
});
|
|
237
|
+
type: 'Registered',
|
|
238
|
+
} satisfies RegisteredIdentity;
|
|
239
|
+
|
|
240
|
+
return identity;
|
|
193
241
|
}
|
|
194
242
|
|
|
195
|
-
return
|
|
243
|
+
return {
|
|
244
|
+
type: 'Anonymous',
|
|
245
|
+
} satisfies AnonymousIdentity;
|
|
196
246
|
}
|
|
197
247
|
|
|
248
|
+
protected async becomeGuest() {
|
|
249
|
+
const credentials = Buffer.from(
|
|
250
|
+
`${this.config.clientId}:${this.config.clientSecret}`
|
|
251
|
+
).toString('base64');
|
|
252
|
+
|
|
253
|
+
// FIXME: Missing scope-down from .env scopes list
|
|
254
|
+
const response = await fetch(
|
|
255
|
+
`${this.config.authUrl}/oauth/${this.config.projectKey}/anonymous/token?grant_type=client_credentials`,
|
|
256
|
+
{
|
|
257
|
+
method: 'POST',
|
|
258
|
+
headers: {
|
|
259
|
+
Authorization: `Basic ${credentials}`,
|
|
260
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
261
|
+
},
|
|
262
|
+
body: new URLSearchParams({
|
|
263
|
+
grant_type: 'client_credentials',
|
|
264
|
+
}),
|
|
265
|
+
}
|
|
266
|
+
);
|
|
198
267
|
|
|
268
|
+
const result = await response.json();
|
|
199
269
|
|
|
270
|
+
this.cache.set({
|
|
271
|
+
expirationTime:
|
|
272
|
+
Date.now() + Number(result.expires_in) * 1000 - 5 * 60 * 1000,
|
|
273
|
+
token: result.access_token,
|
|
274
|
+
refreshToken: result.refresh_token,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
200
277
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
protected createBaseClientBuilder(reqCtx?: RequestContext) {
|
|
278
|
+
protected createBaseClientBuilder() {
|
|
205
279
|
let builder = new ClientBuilder()
|
|
206
280
|
.withProjectKey(this.config.projectKey)
|
|
207
281
|
.withQueueMiddleware({
|
|
@@ -237,7 +311,12 @@ export class CommercetoolsClient {
|
|
|
237
311
|
httpClient: fetch,
|
|
238
312
|
});
|
|
239
313
|
|
|
240
|
-
const correlationId =
|
|
314
|
+
const correlationId =
|
|
315
|
+
this.context.correlationId ||
|
|
316
|
+
'REACTIONARY-' +
|
|
317
|
+
(typeof crypto !== 'undefined' && 'randomUUID' in crypto
|
|
318
|
+
? crypto.randomUUID()
|
|
319
|
+
: randomUUID());
|
|
241
320
|
builder = builder.withCorrelationIdMiddleware({
|
|
242
321
|
generate: () => correlationId,
|
|
243
322
|
});
|