diff --git a/.gitignore b/.gitignore index a527ce8a..95c11d07 100644 --- a/.gitignore +++ b/.gitignore @@ -107,3 +107,7 @@ dist-* # Act .secrets + +# JWT keys +private.key +public.key diff --git a/package.json b/package.json index 7ae86779..d5c0f786 100644 --- a/package.json +++ b/package.json @@ -35,10 +35,10 @@ "@commercelayer/eslint-config-ts": "^1.4.5", "concurrently": "^9.1.0", "eslint": "^8.57.1", - "husky": "^9.1.6", + "husky": "^9.1.7", "lerna": "^8.1.9", "lint-staged": "^15.2.10", "replace-in-file": "^8.2.0", - "typescript": "^5.6.3" + "typescript": "^5.7.2" } } diff --git a/packages/docs/package.json b/packages/docs/package.json index 87b5d8bc..8c038683 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -20,20 +20,20 @@ "@babel/preset-env": "^7.26.0", "@babel/preset-react": "^7.25.9", "@babel/preset-typescript": "^7.26.0", - "@storybook/addon-essentials": "^8.4.2", - "@storybook/addon-interactions": "^8.4.2", - "@storybook/addon-links": "^8.4.2", + "@storybook/addon-essentials": "^8.4.6", + "@storybook/addon-interactions": "^8.4.6", + "@storybook/addon-links": "^8.4.6", "@storybook/addon-webpack5-compiler-swc": "^1.0.5", - "@storybook/blocks": "^8.4.2", - "@storybook/components": "^8.4.2", - "@storybook/core-common": "^8.4.2", - "@storybook/html": "^8.4.2", - "@storybook/html-webpack5": "^8.4.2", + "@storybook/blocks": "^8.4.6", + "@storybook/components": "^8.4.6", + "@storybook/core-common": "^8.4.6", + "@storybook/html": "^8.4.6", + "@storybook/html-webpack5": "^8.4.6", "@storybook/icons": "^1.2.12", - "@storybook/manager-api": "^8.4.2", - "@storybook/test": "^8.4.2", - "@storybook/theming": "^8.4.2", - "@storybook/types": "^8.4.2", + "@storybook/manager-api": "^8.4.6", + "@storybook/test": "^8.4.6", + "@storybook/theming": "^8.4.6", + "@storybook/types": "^8.4.6", "@types/common-tags": "^1.8.4", "@types/react": "^18", "babel-loader": "^9.2.1", @@ -43,9 +43,9 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "remark-gfm": "^4.0.0", - "sass": "^1.80.6", - "storybook": "^8.4.2", - "typescript": "^5.6.3", + "sass": "^1.81.0", + "storybook": "^8.4.6", + "typescript": "^5.7.2", "webpack": "^5.96.1" }, "dependencies": { diff --git a/packages/docs/stories/assets/constants.ts b/packages/docs/stories/assets/constants.ts index eceb8282..b324f4f6 100644 --- a/packages/docs/stories/assets/constants.ts +++ b/packages/docs/stories/assets/constants.ts @@ -15,7 +15,6 @@ export const codes = { // // eslint-disable-next-line @typescript-eslint/explicit-function-return-type // export const createConfig = (scope: string) => ({ // clientId: 'gQMSINLyMm2TrZo0UGEEdubC7uSgm9-', -// slug: 'drop-in-js-stg', // scope, // debug: 'all', // domain: 'commercelayer.co' @@ -25,7 +24,6 @@ export const codes = { // eslint-disable-next-line @typescript-eslint/explicit-function-return-type export const createConfig = (scope: string) => ({ clientId: 'kuSKPbeKbU9LG9LjndzieKWRcfiXFuEfO0OYHXKH9J8', - slug: 'drop-in-js', scope, debug: 'all' }) diff --git a/packages/docs/stories/getting-started.mdx b/packages/docs/stories/getting-started.mdx index 4a6ed25d..d4ad0c13 100644 --- a/packages/docs/stories/getting-started.mdx +++ b/packages/docs/stories/getting-started.mdx @@ -15,7 +15,6 @@ Assuming you already have a Commerce Layer account ([sign up](https://dashboard. | Attribute | Type | Required | Description | |----------------------|--------|:--------:|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **`clientId`** | String | ✓ | Your [sales channel](https://docs.commercelayer.io/core/applications#sales-channel) client ID. You can find it in your application details page on your dashboard. | -| **`slug`** | String | ✓ | Your organization slug (i.e. the subdomain of your base endpoint, usually the slugified version of your organization's name). You can find the base endpoint in your application details page on your dashboard. | | **`scope`** | String | ✓ | Your sales channel [scope](https://docs.commercelayer.io/core/authentication#authorization-scopes) (use it to restrict the dataset of your application). You can find the allowed scopes in your application details page on your dashboard. | | `debug` | String | | The debug level. Can be one of `none` or `all`. Default is `none`. | | `languageCode` | String | | The preferred language code (ISO 639-1) to be used when communicating with the customer. If the language is supported, the hosted checkout will be localized accordingly. Default is `en`. | @@ -30,7 +29,6 @@ Assuming you already have a Commerce Layer account ([sign up](https://dashboard. diff --git a/packages/drop-in/jest.setup.ts b/packages/drop-in/jest.setup.ts index f6d35cb2..194a5870 100644 --- a/packages/drop-in/jest.setup.ts +++ b/packages/drop-in/jest.setup.ts @@ -17,7 +17,6 @@ Object.defineProperty(window, 'commercelayerConfig', { configurable: true, value: { clientId: 'kuSKPbeKbU9LG9LjndzieKWRcfiXFuEfO0OYHXKH9J8', - slug: 'drop-in-js', scope: 'market:code:usa' } }) diff --git a/packages/drop-in/jest.spec.helpers.ts b/packages/drop-in/jest.spec.helpers.ts index 3828e707..752972b2 100644 --- a/packages/drop-in/jest.spec.helpers.ts +++ b/packages/drop-in/jest.spec.helpers.ts @@ -21,3 +21,6 @@ export async function waitForMs(ms: number): Promise { }, ms) }) } + +export const mockedAccessToken = + 'eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6IjliN2JiZmVlMzQzZDVkNDQ5ZGFkODhmMjg0MGEyZTM3YzhkZWFlZTg5NjM4MGQ1ODA2YTc4NWVkMWQ1OTc5ZjAifQ.eyJvcmdhbml6YXRpb24iOnsiaWQiOiJPblZOcUZPTUpuIiwic2x1ZyI6ImRyb3AtaW4tanMiLCJlbnRlcnByaXNlIjp0cnVlLCJyZWdpb24iOiJldS13ZXN0LTEifSwiYXBwbGljYXRpb24iOnsiaWQiOiJkTm5XbWl4eEtHIiwiY2xpZW50X2lkIjoia3VTS1BiZUtiVTlMRzlMam5kemllS1dSY2ZpWEZ1RWZPME9ZSFhLSDlKOCIsImtpbmQiOiJzYWxlc19jaGFubmVsIiwicHVibGljIjp0cnVlfSwibWFya2V0Ijp7ImlkIjpbIkJvd2RHaHdYZGoiXSwic3RvY2tfbG9jYXRpb25faWRzIjpbIkRuZ2VwdU5tT2siLCJLR3lPanV5S1hNIl0sImdlb2NvZGVyX2lkIjpudWxsLCJhbGxvd3NfZXh0ZXJuYWxfcHJpY2VzIjpmYWxzZX0sInNjb3BlIjoibWFya2V0OmNvZGU6dXNhIiwiZXhwIjoxNzMzMjIxOTI2LCJ0ZXN0Ijp0cnVlLCJyYW5kIjowLjQ3ODIwMDY1NTkwOTQzNjgzLCJpYXQiOjE3MzMyMTQ3MjYsImlzcyI6Imh0dHBzOi8vYXV0aC5jb21tZXJjZWxheWVyLmlvIn0.L9FciSGb9eeV7NEZIsouLaVXFXdkscgF6Dd2pOF_alXaobQRLTevxTrudpKGAZ6b619myBR8cS4Lvw_YGm6smCHsw0VDHZrsnp-0xN4C6gjhPVC2lycX68H3s2HeI_CTHv4Cw4INrCg7lyvKjsKz2A_hm4GtpWejV1JB44qKObyi7bkXuFApUCBFChjbquI2z2ACw9mJxCf6PPfgIF7Ezb7OjbIuDnFbtxd0dnIneNlubsHAZ-lxlBqol0DmQ7i7pinYO0C0r1AcMhM1u76S7cTbOTBpYM81xfseslYOZpP8x2aJ9PIZxDjkdNMRCDyhq2fSEqCmoCLGhcsfz6ElbsiosIrdTPGDPN3i1Xtr-wxdviInK4wN1qFoG_r-y8XKsIj7EYL80fF0CQJoZPdHdeT8_QhtDKPsuyhe8arM2anSZm2fe7DmWpSeLbfTIDFB27Au8tE6gaSuaDwk8G_v7uyzhKlZaOXVj6m_o9JWRmzFu38-bwnt_Vu9cXDUx9_gyNDnoIE_qQFe0EYFx0U32arFdjZBYoUL4aeFBhkcBiCxLGEUJyqF65Tx4fhG_y62b-OJl6GCPkL4Xg9G3RAVLsQwD-Gzt8vsT63Ve9NeU10Rn-0kW3r6I3Qw9gU2wynWh3EuJfc7-YL6MQS0W25Dop3NHXKqLrd9wQ_AdIgbQkE' diff --git a/packages/drop-in/package.json b/packages/drop-in/package.json index 932f8387..0fab0f8a 100644 --- a/packages/drop-in/package.json +++ b/packages/drop-in/package.json @@ -47,18 +47,18 @@ "dependencies": { "@commercelayer/js-auth": "^6.7.0", "@commercelayer/organization-config": "^1.4.11", - "@commercelayer/sdk": "^6.25.0", + "@commercelayer/sdk": "^6.25.2", "@types/lodash": "^4.17.13", "iframe-resizer": "4.4.2", "js-cookie": "^3.0.5", "lodash": "^4.17.21", - "type-fest": "^4.26.1" + "type-fest": "^4.29.1" }, "peerDependencies": { "@stencil/core": "^4.0.0" }, "devDependencies": { - "@stencil/core": "^4.22.2", + "@stencil/core": "^4.22.3", "@stencil/sass": "^3.0.12", "@types/iframe-resizer": "^3.5.13", "@types/jest": "^29.5.14", @@ -67,10 +67,10 @@ "jest": "^29.7.0", "jest-cli": "^29.7.0", "nodemon": "^3.1.7", - "puppeteer": "23.7.1", - "sass": "^1.80.6", + "puppeteer": "23.9.0", + "sass": "^1.81.0", "ts-jest": "^29.2.5", - "typescript": "^5.6.3" + "typescript": "^5.7.2" }, "license": "MIT", "engines": { diff --git a/packages/drop-in/src/apis/commercelayer/client.ts b/packages/drop-in/src/apis/commercelayer/client.ts index 42c49586..49f2b45b 100644 --- a/packages/drop-in/src/apis/commercelayer/client.ts +++ b/packages/drop-in/src/apis/commercelayer/client.ts @@ -181,7 +181,6 @@ export async function createClient( return CommerceLayer({ accessToken: token.accessToken, - organization: config.slug, domain: config.domain }) } diff --git a/packages/drop-in/src/apis/commercelayer/config.ts b/packages/drop-in/src/apis/commercelayer/config.ts index d76f0325..558e6bde 100644 --- a/packages/drop-in/src/apis/commercelayer/config.ts +++ b/packages/drop-in/src/apis/commercelayer/config.ts @@ -15,13 +15,6 @@ export interface CommerceLayerConfig { */ clientId: string - /** - * Slug for your organization. You can find it in your dashboard. Slug is the subdomain of your base endpoint. - * @example - * Given the base endpoint `https://drop-in-js.commercelayer.io`, the slug is `drop-in-js`. - */ - slug: string - /** * Restrict the dataset of your application by specifying allowed scopes. You can find them in your dashboard. * @example 'market:code:usa' @@ -58,8 +51,6 @@ export interface CommerceLayerConfig { export type Config = CommerceLayerConfig & { debug: Exclude languageCode: Exclude - endpoint: string - appEndpoint: string } const documentationLink = @@ -80,12 +71,6 @@ export function getConfig(): Config { ) } - if (typeof commercelayerConfig.slug !== 'string') { - throw new Error( - `"window.commercelayerConfig.slug" is required.\n${documentationLink}\n` - ) - } - if (typeof commercelayerConfig.scope !== 'string') { throw new Error( `"window.commercelayerConfig.scope" is required.\n${documentationLink}\n` @@ -117,17 +102,11 @@ export function getConfig(): Config { const debug: Config['debug'] = commercelayerConfig.debug ?? 'none' const languageCode: Config['languageCode'] = commercelayerConfig.languageCode ?? 'en' - const endpoint: Config['endpoint'] = `https://${commercelayerConfig.slug}.${commercelayerConfig.domain}` - const appEndpoint = `https://${commercelayerConfig.slug}${ - commercelayerConfig.domain === 'commercelayer.co' ? '.stg' : '' - }.commercelayer.app` return { ...commercelayerConfig, debug, - languageCode, - endpoint, - appEndpoint + languageCode } } @@ -136,7 +115,6 @@ const getOrganization = memoize(async () => { const client = await createClient(config) return await client.organization.retrieve({ fields: { - // @ts-expect-error This is the resource name organizations: ['config'] } }) @@ -150,16 +128,26 @@ export async function getOrganizationConfig( const { accessToken } = await getAccessToken(config) const jwt = jwtDecode(accessToken) + if (!('organization' in jwt.payload)) { + throw new Error( + 'The access token does not contain the organization information.' + ) + } + const organization = await getOrganization() + const slug = jwt.payload.organization.slug + const domainPrefix = config.domain === 'commercelayer.co' ? '.stg' : '' + const appEndpoint = `https://${slug}${domainPrefix}.commercelayer.app` + const defaultConfig: ConfigJSONWithRequiredLinks = { mfe: { default: { links: { - cart: `${config.appEndpoint}/cart/:order_id?accessToken=:access_token`, - checkout: `${config.appEndpoint}/checkout/:order_id?accessToken=:access_token`, - my_account: `${config.appEndpoint}/my-account?accessToken=:access_token`, - identity: `${config.appEndpoint}/identity` + cart: `${appEndpoint}/cart/:order_id?accessToken=:access_token`, + checkout: `${appEndpoint}/checkout/:order_id?accessToken=:access_token`, + my_account: `${appEndpoint}/my-account?accessToken=:access_token`, + identity: `${appEndpoint}/identity` } } } diff --git a/packages/drop-in/src/cart.html b/packages/drop-in/src/cart.html index 0c629729..f49b78c2 100644 --- a/packages/drop-in/src/cart.html +++ b/packages/drop-in/src/cart.html @@ -35,7 +35,6 @@