From 037311b13d31e56732db3ede65583b70e1c0eb86 Mon Sep 17 00:00:00 2001 From: Marco Montalbano Date: Mon, 2 Feb 2026 15:12:25 +0100 Subject: [PATCH] feat(organization-config): manage defaults for links --- packages/organization-config/biome.json | 5 +- packages/organization-config/package.json | 1 + .../src/getMfeConfig.test.ts | 98 +++++++++++++++++++ .../organization-config/src/getMfeConfig.ts | 62 ++++++++++-- pnpm-lock.yaml | 9 ++ 5 files changed, 168 insertions(+), 7 deletions(-) diff --git a/packages/organization-config/biome.json b/packages/organization-config/biome.json index 0bfb29b..d3e53d2 100644 --- a/packages/organization-config/biome.json +++ b/packages/organization-config/biome.json @@ -18,7 +18,10 @@ "linter": { "enabled": true, "rules": { - "recommended": true + "recommended": true, + "style": { + "useBlockStatements": "warn" + } } }, "javascript": { diff --git a/packages/organization-config/package.json b/packages/organization-config/package.json index 3c3b75f..f5a30ed 100644 --- a/packages/organization-config/package.json +++ b/packages/organization-config/package.json @@ -58,6 +58,7 @@ "vitest": "^4.0.10" }, "dependencies": { + "@commercelayer/js-auth": "^7.2.0", "merge-anything": "^5.1.7" } } diff --git a/packages/organization-config/src/getMfeConfig.test.ts b/packages/organization-config/src/getMfeConfig.test.ts index e188bea..d48cf3d 100644 --- a/packages/organization-config/src/getMfeConfig.test.ts +++ b/packages/organization-config/src/getMfeConfig.test.ts @@ -18,6 +18,22 @@ describe("getMfeConfig function", () => { params: {}, }), ).toBeNull() + + expect( + getMfeConfig({ + jsonConfig: null, + market: "market:id:ZKcv13rT", + params: {}, + }), + ).toBeNull() + + expect( + getMfeConfig({ + jsonConfig: undefined, + market: "market:id:ZKcv13rT", + params: {}, + }), + ).toBeNull() }) it("should return the default config if there is no override", () => { @@ -294,4 +310,86 @@ describe("getMfeConfig function", () => { }) expect(config?.language).toBe("it-IT") }) + + it("should use default links set to our official build-in apps (microstore as list)", () => { + const config = getMfeConfig({ + jsonConfig: null, + params: { + accessToken: ioAccessToken, + orderId: "order123", + skuListId: "skuList123", + }, + market: "market:id:ZKcv13rT", + }) + expect(config).toMatchObject({ + links: { + cart: `https://demo-store.commercelayer.app/cart/order123?accessToken=${ioAccessToken}`, + checkout: `https://demo-store.commercelayer.app/checkout/order123?accessToken=${ioAccessToken}`, + identity: `https://demo-store.commercelayer.app/identity`, + microstore: `https://demo-store.commercelayer.app/microstore/list/skuList123?accessToken=${ioAccessToken}`, + my_account: `https://demo-store.commercelayer.app/my-account?accessToken=${ioAccessToken}`, + }, + }) + }) + + it("should use default links set to our official build-in apps (microstore as sku)", () => { + const config = getMfeConfig({ + jsonConfig: null, + params: { + accessToken: ioAccessToken, + orderId: "order123", + skuId: "sku123", + }, + market: "market:id:ZKcv13rT", + }) + expect(config).toMatchObject({ + links: { + cart: `https://demo-store.commercelayer.app/cart/order123?accessToken=${ioAccessToken}`, + checkout: `https://demo-store.commercelayer.app/checkout/order123?accessToken=${ioAccessToken}`, + identity: `https://demo-store.commercelayer.app/identity`, + microstore: `https://demo-store.commercelayer.app/microstore/sku/sku123?accessToken=${ioAccessToken}`, + my_account: `https://demo-store.commercelayer.app/my-account?accessToken=${ioAccessToken}`, + }, + }) + }) + + it("should use default links set to our official build-in apps with the ability to extend", () => { + const config = getMfeConfig({ + jsonConfig: { + mfe: { + default: { + links: { + cart: "https://custom-cart.example.com/:order_id?accessToken=:access_token", + checkout: + "https://custom-checkout.example.com/:order_id?accessToken=:access_token", + }, + }, + "market:id:ZKcv13rT": { + links: { + cart: "https://market-cart.example.com/:order_id?accessToken=:access_token", + identity: "https://custom-identity.example.com", + }, + }, + }, + }, + params: { + accessToken: ioAccessToken, + orderId: "order123", + skuListId: "skuList123", + }, + market: "market:id:ZKcv13rT", + }) + expect(config).toMatchObject({ + links: { + cart: `https://market-cart.example.com/order123?accessToken=${ioAccessToken}`, + checkout: `https://custom-checkout.example.com/order123?accessToken=${ioAccessToken}`, + identity: `https://custom-identity.example.com`, + microstore: `https://demo-store.commercelayer.app/microstore/list/skuList123?accessToken=${ioAccessToken}`, + my_account: `https://demo-store.commercelayer.app/my-account?accessToken=${ioAccessToken}`, + }, + }) + }) }) + +const ioAccessToken = + "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6IjliN2JiZmVlMzQzZDVkNDQ5ZGFkODhmMjg0MGEyZTM3YzhkZWFlZTg5NjM4MGQ1ODA2YTc4NWVkMWQ1OTc5ZjAifQ.eyJvcmdhbml6YXRpb24iOnsiaWQiOiJleW9aT0Z2UHBSIiwic2x1ZyI6ImRlbW8tc3RvcmUiLCJlbnRlcnByaXNlIjp0cnVlLCJyZWdpb24iOiJldS13ZXN0LTEifSwiYXBwbGljYXRpb24iOnsiaWQiOiJwWWRxaVBBUW5NIiwiY2xpZW50X2lkIjoiQklTRzhiYjNHV3BDOF9EN050MVN1V1dkaWVTNWJKcTgzMUE1MExnQl9JZyIsImtpbmQiOiJzYWxlc19jaGFubmVsIiwicHVibGljIjp0cnVlLCJjb25maWRlbnRpYWwiOmZhbHNlfSwibWFya2V0Ijp7ImlkIjpbIktvYUpZaE1WVmoiXSwic3RvY2tfbG9jYXRpb25faWRzIjpbIkRHekFvdXBwd24iLCJva2RZenVZWXZNIl0sImdlb2NvZGVyX2lkIjpudWxsLCJhbGxvd3NfZXh0ZXJuYWxfcHJpY2VzIjpmYWxzZX0sInNjb3BlIjoibWFya2V0OmlkOktvYUpZaE1WVmoiLCJleHAiOjE3NzAwMzg1NTIsInRlc3QiOnRydWUsInJhbmQiOjAuOTk0OTg2OTM3MzE4MzUxMywiaWF0IjoxNzcwMDMxMzUyLCJpc3MiOiJodHRwczovL2F1dGguY29tbWVyY2VsYXllci5pbyJ9.YoOSos--J0BBEVWnOWDPcF7EgDVMK2ieyzjpOEnR8z7G89PfURv6NX34vexUsYu7HxKwUCd7jrZHBON7Ya1jE8YD5L17eikTxGqm5sDcbLf2eQSVA3tvWcIKrkgAw-t1A_XfD2qCttBuINIM43A8umTQC6ABH3Bprfg5EpFCEfButhdABTb6gf_RAISo-qG3IryLew02x-0xXAJcOfZKvSOkh3CcPZF6IrSfdsFN0Lts2R5-W5u8nXXP2XTmA8kmjCmvH-aEdHDjxJ5wR_AKlNu2Z7IOsTsrrQl_GkLgzGunZcaphCdn7qzWcSwQuhJqR9awOGpEMOFpzaGmrot1pwDfKnuXEhl1VLDUrQXQwm1im0kGopkx_GwnVSmSlhB9FKOK7nIQ4NnBu22vn8kdAcJv8qdyyK4nJlpWeUHyzZW6HxbXCC_RIdqt7P0Q7cDfFIOv0gUO0hs4IhU4r5CCifT8Vkzxss1lWHJPrUrO26B7eUmhiy_0_XKH71xWQ4O2jl2pdb7dqp9wr_vDTM1NteBhV0-xgkkw6FLUz2jwTxnNsNrbtHRiXCWaeD_AgrTFxy_oeHQerP_vcqfK4GwIMfb6GXRxE_e6CR1awz12LoX7k64NGZwAQUVGHCpLjLfr4GXDdRK97RyChnDVvb8eq1GGq1aa9P525egRG0dQ4C0" diff --git a/packages/organization-config/src/getMfeConfig.ts b/packages/organization-config/src/getMfeConfig.ts index c0a12fb..79fc8d4 100644 --- a/packages/organization-config/src/getMfeConfig.ts +++ b/packages/organization-config/src/getMfeConfig.ts @@ -1,3 +1,4 @@ +import { jwtDecode } from "@commercelayer/js-auth" import { merge } from "merge-anything" import type { ValidConfigForOrganizationsInCommerceLayer } from "./schema/types" @@ -45,7 +46,7 @@ interface GetMfeConfigProps { /** * `config` attribute of the organization */ - jsonConfig?: { mfe?: MfeConfigs } + jsonConfig?: { mfe?: MfeConfigs } | null /** * Market identifier for fetching specific configuration overrides. (`market:id:hashid`) */ @@ -78,12 +79,12 @@ export function getMfeConfig({ market, params, }: GetMfeConfigProps): DefaultMfeConfig | null { - if (jsonConfig?.mfe == null) { - return null - } + const defaultConfig = merge( + getDefaults({ params }), + jsonConfig?.mfe?.default ?? {}, + ) - const defaultConfig = jsonConfig?.mfe?.default ?? {} - const overrideConfig = market != null ? (jsonConfig?.mfe[market] ?? {}) : {} + const overrideConfig = market != null ? (jsonConfig?.mfe?.[market] ?? {}) : {} // Replace placeholders in all string values within the object function replacePlaceholders(config: DefaultMfeConfig): DefaultMfeConfig { @@ -103,5 +104,54 @@ export function getMfeConfig({ JSON.parse(JSON.stringify(defaultConfig)), overrideConfig, ) + + if (Object.keys(mergedConfig).length === 0) { + return null + } + return replacePlaceholders(mergedConfig) } + +/** + * Provides default MFE configuration. + */ +function getDefaults({ params }: GetMfeConfigProps): DefaultMfeConfig { + if (params?.accessToken == null) { + return {} + } + + try { + const jwt = jwtDecode(params.accessToken) + const slug = + params.slug ?? + ("organization" in jwt.payload ? jwt.payload.organization.slug : null) + + if (slug == null) { + return {} + } + + const domainPrefix = jwt.payload.iss.endsWith("commercelayer.co") + ? ".stg" + : "" + + const appEndpoint = `https://${slug}${domainPrefix}.commercelayer.app` + + const defaultConfig: DefaultMfeConfig = { + links: { + 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`, + microstore: + params.skuListId != null + ? `${appEndpoint}/microstore/list/:sku_list_id?accessToken=:access_token` + : `${appEndpoint}/microstore/sku/:sku_id?accessToken=:access_token`, + }, + } + + return defaultConfig + } catch (_error) { + console.log(_error) + return {} + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2604f15..0cdf8af 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -85,6 +85,9 @@ importers: packages/organization-config: dependencies: + '@commercelayer/js-auth': + specifier: ^7.2.0 + version: 7.2.0 merge-anything: specifier: ^5.1.7 version: 5.1.7 @@ -194,6 +197,10 @@ packages: cpu: [x64] os: [win32] + '@commercelayer/js-auth@7.2.0': + resolution: {integrity: sha512-p6GLDsDz2C9I8Mq8bZtDhTqMPco2Vi7emuIy+sAWr1fEnu66JMwMi7hrM+NBMcEOnFAjYBh2B2R+1KZsp+bMTA==} + engines: {node: '>=20.0.0'} + '@emnapi/core@1.3.1': resolution: {integrity: sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog==} @@ -4467,6 +4474,8 @@ snapshots: '@biomejs/cli-win32-x64@2.3.9': optional: true + '@commercelayer/js-auth@7.2.0': {} + '@emnapi/core@1.3.1': dependencies: '@emnapi/wasi-threads': 1.0.1