From 8dfd4e41d02a402f618f333b2e95348663088849 Mon Sep 17 00:00:00 2001 From: ppatwal Date: Tue, 19 May 2026 03:46:11 +0530 Subject: [PATCH 1/9] feat(SITES-43695): store per-product default site in org.config.defaults Per-product default site is stored as config.defaults.{productCode}.siteId on the organization config so customers can pin a preferred domain without insertion-order dependence on getFirstEnrollment. Changes: - sites.js: resolveOrgDefaultSite reads org.getConfig()?.defaults?.[productCode]?.siteId before falling back to getFirstEnrollment; try/catch ensures TierClient errors fall through gracefully; warns on stale or cross-org config.defaults entries - organizations.js: PATCH validates config.defaults entries (product code, siteId UUID, site ownership); comment documents setConfig/updates ordering dependency - dto/organization.js: remove defaultSiteId from toJSON - docs/openapi/schemas.yaml: document defaults.{productCode}.siteId structure on OrganizationConfig; remove obsolete defaultSiteId field - tests: full edge-case coverage for both the org PATCH validation and the resolveSite config.defaults resolution paths Co-Authored-By: Claude Sonnet 4.6 --- docs/openapi/schemas.yaml | 14 ++ src/controllers/organizations.js | 29 ++++ src/controllers/sites.js | 57 ++++++++ test/controllers/organizations.test.js | 134 +++++++++++++++++ test/controllers/sites.test.js | 194 +++++++++++++++++++++++++ 5 files changed, 428 insertions(+) diff --git a/docs/openapi/schemas.yaml b/docs/openapi/schemas.yaml index 785204465..965ceefcb 100644 --- a/docs/openapi/schemas.yaml +++ b/docs/openapi/schemas.yaml @@ -370,6 +370,20 @@ CdnLogsConfig: OrganizationConfig: allOf: - $ref: '#/Config' + - type: object + properties: + defaults: + description: > + Optional. Per-product default site overrides. Keys are product codes + (e.g. "ASO"). Each entry pins a preferred site for resolveSite so + customers are not subject to insertion-order dependence. + type: object + additionalProperties: + type: object + properties: + siteId: + description: The ID of the default site for this product. Set to null to clear. + $ref: '#/Id' SiteConfig: allOf: - $ref: '#/Config' diff --git a/src/controllers/organizations.js b/src/controllers/organizations.js index 72f278d69..6f898e661 100644 --- a/src/controllers/organizations.js +++ b/src/controllers/organizations.js @@ -23,6 +23,8 @@ import { isValidUUID, } from '@adobe/spacecat-shared-utils'; +import { Entitlement as EntitlementModel } from '@adobe/spacecat-shared-data-access'; + import { OrganizationDto } from '../dto/organization.js'; import { ProjectDto } from '../dto/project.js'; import { SiteDto } from '../dto/site.js'; @@ -331,6 +333,33 @@ function OrganizationsController(ctx, env) { updates = true; } + // Validate config.defaults entries if present. setConfig/updates=true are handled by the + // isObject(requestBody.config) block above; this block only validates and may return early. + if (isObject(requestBody.config) && isObject(requestBody.config.defaults)) { + const VALID_PRODUCT_CODES = new Set(Object.values(EntitlementModel.PRODUCT_CODES)); + for (const [productCode, entry] of Object.entries(requestBody.config.defaults)) { + if (!VALID_PRODUCT_CODES.has(productCode)) { + return badRequest(`Unknown product code in config.defaults: ${productCode}`); + } + if (entry !== null && entry !== undefined) { + if (!isObject(entry)) { + return badRequest(`config.defaults.${productCode} must be an object with a siteId field`); + } + const { siteId } = entry; + if (siteId !== null && siteId !== undefined) { + if (!isValidUUID(siteId)) { + return badRequest(`Invalid siteId for product ${productCode} in config.defaults`); + } + // eslint-disable-next-line no-await-in-loop + const site = await Site.findById(siteId); + if (!site || site.getOrganizationId() !== organization.getId()) { + return badRequest(`config.defaults.${productCode}: site not found or does not belong to this organization`); + } + } + } + } + } + if (updates) { const updatedOrganization = await organization.save(); return ok(OrganizationDto.toJSON(updatedOrganization)); diff --git a/src/controllers/sites.js b/src/controllers/sites.js index 53184560d..164e3e0bf 100755 --- a/src/controllers/sites.js +++ b/src/controllers/sites.js @@ -1208,9 +1208,61 @@ function SitesController(ctx, log, env) { } } + // Resolves the org's per-product default site from config.defaults, validating it belongs + // to the org and is enrolled. Returns the resolved data object or null to fall through + // to getFirstEnrollment(). + const resolveOrgDefaultSite = async (org) => { + try { + const defaultSiteId = org.getConfig()?.defaults?.[productCode]?.siteId; + if (!hasText(defaultSiteId) || !isValidUUID(defaultSiteId)) { + return null; + } + + const defaultSite = await Site.findById(defaultSiteId); + if (!defaultSite) { + ctx.log.warn( + `[resolveSite] stale config.defaults entry: site ${defaultSiteId} not found for org ${org.getId()} product ${productCode}`, + ); + return null; + } + if (defaultSite.getOrganizationId() !== org.getId()) { + ctx.log.warn( + `[resolveSite] config.defaults cross-org mismatch: site ${defaultSiteId} belongs to org ${defaultSite.getOrganizationId()}, not ${org.getId()} — falling back`, + ); + return null; + } + + const siteTierClient = await TierClient.createForSite(context, defaultSite, productCode); + const { entitlement, enrollments } = await siteTierClient.getAllEnrollment(); + + const tierVisible = entitlement && CUSTOMER_VISIBLE_TIERS.includes(entitlement.getTier()); + if (!tierVisible || !enrollments?.length) { + return null; + } + + const isSummitPlgEnabled = await getIsSummitPlgEnabled(defaultSite, context); + return { + organization: OrganizationDto.toJSON(org), + site: SiteDto.toJSON(defaultSite), + isSummitPlgEnabled, + }; + } catch (e) { + ctx.log.warn( + `[resolveSite] resolveOrgDefaultSite failed for org ${org.getId()} product ${productCode} — falling back`, + e, + ); + return null; + } + }; + if (hasText(organizationId) && isValidUUID(organizationId)) { organization = await Organization.findById(organizationId); if (organization && await accessControlUtil.hasAccess(organization)) { + const defaultData = await resolveOrgDefaultSite(organization); + if (defaultData) { + return ok({ data: defaultData }); + } + const tierClient = TierClient.createForOrg(context, organization, productCode); const { entitlement: orgEntitlement, site: enrolledSite } = await tierClient .getFirstEnrollment(); @@ -1230,6 +1282,11 @@ function SitesController(ctx, log, env) { } else if (hasText(imsOrg)) { organization = await Organization.findByImsOrgId(imsOrg); if (organization && await accessControlUtil.hasAccess(organization)) { + const defaultData = await resolveOrgDefaultSite(organization); + if (defaultData) { + return ok({ data: defaultData }); + } + const tierClient = TierClient.createForOrg(context, organization, productCode); const { entitlement: imsOrgEntitlement, site: enrolledSite } = await tierClient .getFirstEnrollment(); diff --git a/test/controllers/organizations.test.js b/test/controllers/organizations.test.js index bc1234dda..15794087b 100755 --- a/test/controllers/organizations.test.js +++ b/test/controllers/organizations.test.js @@ -439,6 +439,140 @@ describe('Organizations Controller', () => { expect(error).to.have.property('message', 'No updates provided'); }); + it('updates config.defaults with a valid site in the org', async () => { + // Use a valid UUID; stub returns sites[0] (belongs to orgId) regardless of the exact ID + const siteId = '550e8400-e29b-41d4-a716-446655440001'; + organizations[0].save = sinon.stub().resolves(organizations[0]); + organizations[0].setConfig = sinon.stub(); + mockDataAccess.Organization.findById.resolves(organizations[0]); + // Return a site object whose getOrganizationId() equals orgId + const siteInOrg = { getOrganizationId: () => orgId }; + mockDataAccess.Site.findById.resolves(siteInOrg); + + const response = await organizationsController.updateOrganization({ + params: { organizationId: orgId }, + data: { config: { defaults: { ASO: { siteId } } } }, + ...context, + }); + + expect(organizations[0].setConfig).to.have.been.calledOnce; + expect(organizations[0].save).to.have.been.calledOnce; + expect(response.status).to.equal(200); + }); + + it('accepts config.defaults with null entry (clears a product)', async () => { + organizations[0].save = sinon.stub().resolves(organizations[0]); + organizations[0].setConfig = sinon.stub(); + mockDataAccess.Organization.findById.resolves(organizations[0]); + + const response = await organizationsController.updateOrganization({ + params: { organizationId: orgId }, + data: { config: { defaults: { ASO: null } } }, + ...context, + }); + + expect(organizations[0].save).to.have.been.calledOnce; + expect(response.status).to.equal(200); + }); + + it('accepts config.defaults with null siteId (clears just the siteId)', async () => { + organizations[0].save = sinon.stub().resolves(organizations[0]); + organizations[0].setConfig = sinon.stub(); + mockDataAccess.Organization.findById.resolves(organizations[0]); + + const response = await organizationsController.updateOrganization({ + params: { organizationId: orgId }, + data: { config: { defaults: { ASO: { siteId: null } } } }, + ...context, + }); + + expect(organizations[0].save).to.have.been.calledOnce; + expect(response.status).to.equal(200); + }); + + it('returns bad request for an unknown product code in config.defaults', async () => { + organizations[0].save = sinon.stub().resolves(organizations[0]); + mockDataAccess.Organization.findById.resolves(organizations[0]); + + const response = await organizationsController.updateOrganization({ + params: { organizationId: orgId }, + data: { config: { defaults: { UNKNOWN_PRODUCT: { siteId: 'site1' } } } }, + ...context, + }); + + expect(organizations[0].save).to.not.have.been.called; + expect(response.status).to.equal(400); + const error = await response.json(); + expect(error).to.have.property('message', 'Unknown product code in config.defaults: UNKNOWN_PRODUCT'); + }); + + it('returns bad request when config.defaults entry is not an object', async () => { + organizations[0].save = sinon.stub().resolves(organizations[0]); + mockDataAccess.Organization.findById.resolves(organizations[0]); + + const response = await organizationsController.updateOrganization({ + params: { organizationId: orgId }, + data: { config: { defaults: { ASO: 'flat-string' } } }, + ...context, + }); + + expect(organizations[0].save).to.not.have.been.called; + expect(response.status).to.equal(400); + const error = await response.json(); + expect(error).to.have.property('message', 'config.defaults.ASO must be an object with a siteId field'); + }); + + it('returns bad request when config.defaults siteId is not a valid UUID', async () => { + organizations[0].save = sinon.stub().resolves(organizations[0]); + mockDataAccess.Organization.findById.resolves(organizations[0]); + + const response = await organizationsController.updateOrganization({ + params: { organizationId: orgId }, + data: { config: { defaults: { ASO: { siteId: 'not-a-uuid' } } } }, + ...context, + }); + + expect(organizations[0].save).to.not.have.been.called; + expect(response.status).to.equal(400); + const error = await response.json(); + expect(error).to.have.property('message', 'Invalid siteId for product ASO in config.defaults'); + }); + + it('returns bad request when config.defaults siteId does not exist or belongs to another org', async () => { + organizations[0].save = sinon.stub().resolves(organizations[0]); + mockDataAccess.Organization.findById.resolves(organizations[0]); + // sites[1] belongs to a different org + mockDataAccess.Site.findById.resolves(sites[1]); + + const response = await organizationsController.updateOrganization({ + params: { organizationId: orgId }, + data: { config: { defaults: { ASO: { siteId: '550e8400-e29b-41d4-a716-446655440001' } } } }, + ...context, + }); + + expect(organizations[0].save).to.not.have.been.called; + expect(response.status).to.equal(400); + const error = await response.json(); + expect(error).to.have.property('message', 'config.defaults.ASO: site not found or does not belong to this organization'); + }); + + it('returns bad request when config.defaults siteId does not exist (null findById)', async () => { + organizations[0].save = sinon.stub().resolves(organizations[0]); + mockDataAccess.Organization.findById.resolves(organizations[0]); + mockDataAccess.Site.findById.resolves(null); + + const response = await organizationsController.updateOrganization({ + params: { organizationId: orgId }, + data: { config: { defaults: { ASO: { siteId: '550e8400-e29b-41d4-a716-446655440099' } } } }, + ...context, + }); + + expect(organizations[0].save).to.not.have.been.called; + expect(response.status).to.equal(400); + const error = await response.json(); + expect(error).to.have.property('message', 'config.defaults.ASO: site not found or does not belong to this organization'); + }); + it('gets all organizations', async () => { mockDataAccess.Organization.all.resolves(organizations); diff --git a/test/controllers/sites.test.js b/test/controllers/sites.test.js index f39abaede..8fc874ea1 100644 --- a/test/controllers/sites.test.js +++ b/test/controllers/sites.test.js @@ -5087,6 +5087,200 @@ describe('Sites Controller', () => { const body = await response.json(); expect(body.message).to.include('No site found for the provided parameters'); }); + + describe('config.defaults resolution', () => { + // The context header 'x-product' is 'abcd', so productCode = 'abcd'. + // Must include Config methods because OrganizationDto.toJSON calls Config.toDynamoItem. + const makeConfigWithDefault = (siteId) => ({ + defaults: { abcd: { siteId } }, + getSlackConfig: () => undefined, + getHandlers: () => undefined, + getContentAiConfig: () => undefined, + getImports: () => undefined, + getFetchConfig: () => undefined, + getBrandConfig: () => undefined, + getBrandProfile: () => undefined, + getCdnLogsConfig: () => undefined, + getLlmoConfig: () => undefined, + getTokowakaConfig: () => undefined, + getEdgeOptimizeConfig: () => undefined, + }); + + it('should resolve config.defaults for organizationId path and skip getFirstEnrollment', async () => { + sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[0])); + context.data = { organizationId: testOrganizations[0].getId() }; + mockDataAccess.Organization.findById.resolves(testOrganizations[0]); + mockDataAccess.Site.findById.resolves(testSites[0]); + mockTierClientStub.getAllEnrollment.resolves({ + entitlement: { getTier: () => 'FREE_TRIAL' }, + enrollments: [{ getId: () => 'enrollment-1' }], + }); + + const response = await sitesController.resolveSite(context); + + expect(response.status).to.equal(200); + const body = await response.json(); + expect(body.data.site.id).to.equal(SITE_IDS[0]); + expect(mockTierClientStub.getFirstEnrollment).to.not.have.been.called; + }); + + it('should resolve config.defaults for imsOrg path and skip getFirstEnrollment', async () => { + sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[0])); + context.data = { imsOrg: testOrganizations[0].getImsOrgId() }; + mockDataAccess.Organization.findByImsOrgId.resolves(testOrganizations[0]); + mockDataAccess.Site.findById.resolves(testSites[0]); + mockTierClientStub.getAllEnrollment.resolves({ + entitlement: { getTier: () => 'FREE_TRIAL' }, + enrollments: [{ getId: () => 'enrollment-1' }], + }); + + const response = await sitesController.resolveSite(context); + + expect(response.status).to.equal(200); + const body = await response.json(); + expect(body.data.site.id).to.equal(SITE_IDS[0]); + expect(mockTierClientStub.getFirstEnrollment).to.not.have.been.called; + }); + + it('should fall through to getFirstEnrollment if config.defaults site does not belong to org', async () => { + // testSites[1] belongs to testOrganizations[3], not testOrganizations[0] + sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[1])); + context.data = { organizationId: testOrganizations[0].getId() }; + mockDataAccess.Organization.findById.resolves(testOrganizations[0]); + mockDataAccess.Site.findById.resolves(testSites[1]); + mockTierClientStub.getFirstEnrollment.resolves({ + entitlement: { getTier: () => 'FREE_TRIAL' }, + site: testSites[0], + }); + + await sitesController.resolveSite(context); + + expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; + }); + + it('should fall through to getFirstEnrollment if config.defaults site is not found', async () => { + sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[0])); + context.data = { organizationId: testOrganizations[0].getId() }; + mockDataAccess.Organization.findById.resolves(testOrganizations[0]); + mockDataAccess.Site.findById.resolves(null); + mockTierClientStub.getFirstEnrollment.resolves({ + entitlement: { getTier: () => 'FREE_TRIAL' }, + site: testSites[0], + }); + + await sitesController.resolveSite(context); + + expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; + }); + + it('should fall through to getFirstEnrollment if config.defaults site has no valid enrollment', async () => { + sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[0])); + context.data = { organizationId: testOrganizations[0].getId() }; + mockDataAccess.Organization.findById.resolves(testOrganizations[0]); + mockDataAccess.Site.findById.resolves(testSites[0]); + mockTierClientStub.getAllEnrollment.resolves({ + entitlement: { getTier: () => 'FREE_TRIAL' }, + enrollments: [], + }); + mockTierClientStub.getFirstEnrollment.resolves({ + entitlement: { getTier: () => 'FREE_TRIAL' }, + site: testSites[0], + }); + + await sitesController.resolveSite(context); + + expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; + }); + + it('should fall through to getFirstEnrollment if config.defaults siteId is not a valid UUID', async () => { + sandbox.stub(testOrganizations[0], 'getConfig').returns( + makeConfigWithDefault('not-a-valid-uuid'), + ); + context.data = { organizationId: testOrganizations[0].getId() }; + mockDataAccess.Organization.findById.resolves(testOrganizations[0]); + mockTierClientStub.getFirstEnrollment.resolves({ + entitlement: { getTier: () => 'FREE_TRIAL' }, + site: testSites[0], + }); + + await sitesController.resolveSite(context); + + expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; + expect(mockDataAccess.Site.findById).to.not.have.been.called; + }); + + it('should fall through to getFirstEnrollment if config.defaults site has a non-customer-visible tier (PRE_ONBOARD)', async () => { + sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[0])); + context.data = { organizationId: testOrganizations[0].getId() }; + mockDataAccess.Organization.findById.resolves(testOrganizations[0]); + mockDataAccess.Site.findById.resolves(testSites[0]); + mockTierClientStub.getAllEnrollment.resolves({ + entitlement: { getTier: () => 'PRE_ONBOARD' }, + enrollments: [{ getId: () => 'enrollment-1' }], + }); + mockTierClientStub.getFirstEnrollment.resolves({ + entitlement: { getTier: () => 'FREE_TRIAL' }, + site: testSites[0], + }); + + await sitesController.resolveSite(context); + + expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; + }); + + it('should fall through to getFirstEnrollment if config.defaults site has no entitlement', async () => { + sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[0])); + context.data = { organizationId: testOrganizations[0].getId() }; + mockDataAccess.Organization.findById.resolves(testOrganizations[0]); + mockDataAccess.Site.findById.resolves(testSites[0]); + mockTierClientStub.getAllEnrollment.resolves({ + entitlement: null, + enrollments: [], + }); + mockTierClientStub.getFirstEnrollment.resolves({ + entitlement: { getTier: () => 'FREE_TRIAL' }, + site: testSites[0], + }); + + await sitesController.resolveSite(context); + + expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; + }); + + it('should fall through to getFirstEnrollment via imsOrg path if config.defaults site belongs to a different org', async () => { + // testSites[1] belongs to testOrganizations[3], not testOrganizations[0] + sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[1])); + context.data = { imsOrg: testOrganizations[0].getImsOrgId() }; + mockDataAccess.Organization.findByImsOrgId.resolves(testOrganizations[0]); + mockDataAccess.Site.findById.resolves(testSites[1]); + mockTierClientStub.getFirstEnrollment.resolves({ + entitlement: { getTier: () => 'FREE_TRIAL' }, + site: testSites[0], + }); + + await sitesController.resolveSite(context); + + expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; + }); + + it('should fall through to getFirstEnrollment if TierClient.createForSite throws', async () => { + sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[0])); + context.data = { organizationId: testOrganizations[0].getId() }; + mockDataAccess.Organization.findById.resolves(testOrganizations[0]); + mockDataAccess.Site.findById.resolves(testSites[0]); + TierClient.createForSite.throws(new Error('TierClient error')); + mockTierClientStub.getFirstEnrollment.resolves({ + entitlement: { getTier: () => 'FREE_TRIAL' }, + site: testSites[0], + }); + + const response = await sitesController.resolveSite(context); + + // Should fall through (not throw a 500) + expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; + expect(response.status).to.not.equal(500); + }); + }); }); describe('getBrandProfile', () => { From c70c9f74813914e61af108381e6519f329d6dbf3 Mon Sep 17 00:00:00 2001 From: ppatwal Date: Tue, 19 May 2026 03:57:48 +0530 Subject: [PATCH 2/9] =?UTF-8?q?chore:=20revert=20OrganizationConfig=20defa?= =?UTF-8?q?ults=20schema=20=E2=80=94=20internal=20field,=20not=20public=20?= =?UTF-8?q?API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- docs/openapi/schemas.yaml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/docs/openapi/schemas.yaml b/docs/openapi/schemas.yaml index 965ceefcb..785204465 100644 --- a/docs/openapi/schemas.yaml +++ b/docs/openapi/schemas.yaml @@ -370,20 +370,6 @@ CdnLogsConfig: OrganizationConfig: allOf: - $ref: '#/Config' - - type: object - properties: - defaults: - description: > - Optional. Per-product default site overrides. Keys are product codes - (e.g. "ASO"). Each entry pins a preferred site for resolveSite so - customers are not subject to insertion-order dependence. - type: object - additionalProperties: - type: object - properties: - siteId: - description: The ID of the default site for this product. Set to null to clear. - $ref: '#/Id' SiteConfig: allOf: - $ref: '#/Config' From 0a2e0ccd505f92b977af65ca315b122de55b725c Mon Sep 17 00:00:00 2001 From: ppatwal Date: Tue, 19 May 2026 04:02:54 +0530 Subject: [PATCH 3/9] refactor(SITES-43695): simplify config.defaults validation to product code only Remove siteId-specific validation from the PATCH org config.defaults block so the structure is not locked to a single field. Only product code membership is validated; entry shape is left to the caller. Co-Authored-By: Claude Sonnet 4.6 --- src/controllers/organizations.js | 20 +---- test/controllers/organizations.test.js | 106 +------------------------ 2 files changed, 3 insertions(+), 123 deletions(-) diff --git a/src/controllers/organizations.js b/src/controllers/organizations.js index 6f898e661..0c838ce0f 100644 --- a/src/controllers/organizations.js +++ b/src/controllers/organizations.js @@ -333,30 +333,12 @@ function OrganizationsController(ctx, env) { updates = true; } - // Validate config.defaults entries if present. setConfig/updates=true are handled by the - // isObject(requestBody.config) block above; this block only validates and may return early. if (isObject(requestBody.config) && isObject(requestBody.config.defaults)) { const VALID_PRODUCT_CODES = new Set(Object.values(EntitlementModel.PRODUCT_CODES)); - for (const [productCode, entry] of Object.entries(requestBody.config.defaults)) { + for (const [productCode] of Object.entries(requestBody.config.defaults)) { if (!VALID_PRODUCT_CODES.has(productCode)) { return badRequest(`Unknown product code in config.defaults: ${productCode}`); } - if (entry !== null && entry !== undefined) { - if (!isObject(entry)) { - return badRequest(`config.defaults.${productCode} must be an object with a siteId field`); - } - const { siteId } = entry; - if (siteId !== null && siteId !== undefined) { - if (!isValidUUID(siteId)) { - return badRequest(`Invalid siteId for product ${productCode} in config.defaults`); - } - // eslint-disable-next-line no-await-in-loop - const site = await Site.findById(siteId); - if (!site || site.getOrganizationId() !== organization.getId()) { - return badRequest(`config.defaults.${productCode}: site not found or does not belong to this organization`); - } - } - } } } diff --git a/test/controllers/organizations.test.js b/test/controllers/organizations.test.js index 15794087b..168592786 100755 --- a/test/controllers/organizations.test.js +++ b/test/controllers/organizations.test.js @@ -439,19 +439,14 @@ describe('Organizations Controller', () => { expect(error).to.have.property('message', 'No updates provided'); }); - it('updates config.defaults with a valid site in the org', async () => { - // Use a valid UUID; stub returns sites[0] (belongs to orgId) regardless of the exact ID - const siteId = '550e8400-e29b-41d4-a716-446655440001'; + it('updates config.defaults with a valid product code', async () => { organizations[0].save = sinon.stub().resolves(organizations[0]); organizations[0].setConfig = sinon.stub(); mockDataAccess.Organization.findById.resolves(organizations[0]); - // Return a site object whose getOrganizationId() equals orgId - const siteInOrg = { getOrganizationId: () => orgId }; - mockDataAccess.Site.findById.resolves(siteInOrg); const response = await organizationsController.updateOrganization({ params: { organizationId: orgId }, - data: { config: { defaults: { ASO: { siteId } } } }, + data: { config: { defaults: { ASO: { siteId: '550e8400-e29b-41d4-a716-446655440001' } } } }, ...context, }); @@ -460,36 +455,6 @@ describe('Organizations Controller', () => { expect(response.status).to.equal(200); }); - it('accepts config.defaults with null entry (clears a product)', async () => { - organizations[0].save = sinon.stub().resolves(organizations[0]); - organizations[0].setConfig = sinon.stub(); - mockDataAccess.Organization.findById.resolves(organizations[0]); - - const response = await organizationsController.updateOrganization({ - params: { organizationId: orgId }, - data: { config: { defaults: { ASO: null } } }, - ...context, - }); - - expect(organizations[0].save).to.have.been.calledOnce; - expect(response.status).to.equal(200); - }); - - it('accepts config.defaults with null siteId (clears just the siteId)', async () => { - organizations[0].save = sinon.stub().resolves(organizations[0]); - organizations[0].setConfig = sinon.stub(); - mockDataAccess.Organization.findById.resolves(organizations[0]); - - const response = await organizationsController.updateOrganization({ - params: { organizationId: orgId }, - data: { config: { defaults: { ASO: { siteId: null } } } }, - ...context, - }); - - expect(organizations[0].save).to.have.been.calledOnce; - expect(response.status).to.equal(200); - }); - it('returns bad request for an unknown product code in config.defaults', async () => { organizations[0].save = sinon.stub().resolves(organizations[0]); mockDataAccess.Organization.findById.resolves(organizations[0]); @@ -506,73 +471,6 @@ describe('Organizations Controller', () => { expect(error).to.have.property('message', 'Unknown product code in config.defaults: UNKNOWN_PRODUCT'); }); - it('returns bad request when config.defaults entry is not an object', async () => { - organizations[0].save = sinon.stub().resolves(organizations[0]); - mockDataAccess.Organization.findById.resolves(organizations[0]); - - const response = await organizationsController.updateOrganization({ - params: { organizationId: orgId }, - data: { config: { defaults: { ASO: 'flat-string' } } }, - ...context, - }); - - expect(organizations[0].save).to.not.have.been.called; - expect(response.status).to.equal(400); - const error = await response.json(); - expect(error).to.have.property('message', 'config.defaults.ASO must be an object with a siteId field'); - }); - - it('returns bad request when config.defaults siteId is not a valid UUID', async () => { - organizations[0].save = sinon.stub().resolves(organizations[0]); - mockDataAccess.Organization.findById.resolves(organizations[0]); - - const response = await organizationsController.updateOrganization({ - params: { organizationId: orgId }, - data: { config: { defaults: { ASO: { siteId: 'not-a-uuid' } } } }, - ...context, - }); - - expect(organizations[0].save).to.not.have.been.called; - expect(response.status).to.equal(400); - const error = await response.json(); - expect(error).to.have.property('message', 'Invalid siteId for product ASO in config.defaults'); - }); - - it('returns bad request when config.defaults siteId does not exist or belongs to another org', async () => { - organizations[0].save = sinon.stub().resolves(organizations[0]); - mockDataAccess.Organization.findById.resolves(organizations[0]); - // sites[1] belongs to a different org - mockDataAccess.Site.findById.resolves(sites[1]); - - const response = await organizationsController.updateOrganization({ - params: { organizationId: orgId }, - data: { config: { defaults: { ASO: { siteId: '550e8400-e29b-41d4-a716-446655440001' } } } }, - ...context, - }); - - expect(organizations[0].save).to.not.have.been.called; - expect(response.status).to.equal(400); - const error = await response.json(); - expect(error).to.have.property('message', 'config.defaults.ASO: site not found or does not belong to this organization'); - }); - - it('returns bad request when config.defaults siteId does not exist (null findById)', async () => { - organizations[0].save = sinon.stub().resolves(organizations[0]); - mockDataAccess.Organization.findById.resolves(organizations[0]); - mockDataAccess.Site.findById.resolves(null); - - const response = await organizationsController.updateOrganization({ - params: { organizationId: orgId }, - data: { config: { defaults: { ASO: { siteId: '550e8400-e29b-41d4-a716-446655440099' } } } }, - ...context, - }); - - expect(organizations[0].save).to.not.have.been.called; - expect(response.status).to.equal(400); - const error = await response.json(); - expect(error).to.have.property('message', 'config.defaults.ASO: site not found or does not belong to this organization'); - }); - it('gets all organizations', async () => { mockDataAccess.Organization.all.resolves(organizations); From 71c085cda4b05018974fb087b3bd28f472e9c025 Mon Sep 17 00:00:00 2001 From: ppatwal Date: Tue, 19 May 2026 04:04:09 +0530 Subject: [PATCH 4/9] feat(SITES-43695): validate siteId in config.defaults only when present If a config.defaults entry contains a siteId field, validate it is a valid UUID and belongs to the organization. Entries without siteId are accepted as-is, keeping the structure open to other fields per product. Co-Authored-By: Claude Sonnet 4.6 --- src/controllers/organizations.js | 12 ++++- test/controllers/organizations.test.js | 71 +++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/src/controllers/organizations.js b/src/controllers/organizations.js index 0c838ce0f..38e340922 100644 --- a/src/controllers/organizations.js +++ b/src/controllers/organizations.js @@ -335,10 +335,20 @@ function OrganizationsController(ctx, env) { if (isObject(requestBody.config) && isObject(requestBody.config.defaults)) { const VALID_PRODUCT_CODES = new Set(Object.values(EntitlementModel.PRODUCT_CODES)); - for (const [productCode] of Object.entries(requestBody.config.defaults)) { + for (const [productCode, entry] of Object.entries(requestBody.config.defaults)) { if (!VALID_PRODUCT_CODES.has(productCode)) { return badRequest(`Unknown product code in config.defaults: ${productCode}`); } + if (isObject(entry) && entry.siteId != null) { + if (!isValidUUID(entry.siteId)) { + return badRequest(`Invalid siteId for product ${productCode} in config.defaults`); + } + // eslint-disable-next-line no-await-in-loop + const site = await Site.findById(entry.siteId); + if (!site || site.getOrganizationId() !== organization.getId()) { + return badRequest(`config.defaults.${productCode}: site not found or does not belong to this organization`); + } + } } } diff --git a/test/controllers/organizations.test.js b/test/controllers/organizations.test.js index 168592786..0ba50f0d1 100755 --- a/test/controllers/organizations.test.js +++ b/test/controllers/organizations.test.js @@ -439,14 +439,16 @@ describe('Organizations Controller', () => { expect(error).to.have.property('message', 'No updates provided'); }); - it('updates config.defaults with a valid product code', async () => { + it('updates config.defaults with a valid siteId', async () => { + const siteId = '550e8400-e29b-41d4-a716-446655440001'; organizations[0].save = sinon.stub().resolves(organizations[0]); organizations[0].setConfig = sinon.stub(); mockDataAccess.Organization.findById.resolves(organizations[0]); + mockDataAccess.Site.findById.resolves({ getOrganizationId: () => orgId }); const response = await organizationsController.updateOrganization({ params: { organizationId: orgId }, - data: { config: { defaults: { ASO: { siteId: '550e8400-e29b-41d4-a716-446655440001' } } } }, + data: { config: { defaults: { ASO: { siteId } } } }, ...context, }); @@ -455,6 +457,21 @@ describe('Organizations Controller', () => { expect(response.status).to.equal(200); }); + it('updates config.defaults without siteId (other fields allowed)', async () => { + organizations[0].save = sinon.stub().resolves(organizations[0]); + organizations[0].setConfig = sinon.stub(); + mockDataAccess.Organization.findById.resolves(organizations[0]); + + const response = await organizationsController.updateOrganization({ + params: { organizationId: orgId }, + data: { config: { defaults: { ASO: { someOtherField: 'value' } } } }, + ...context, + }); + + expect(organizations[0].save).to.have.been.calledOnce; + expect(response.status).to.equal(200); + }); + it('returns bad request for an unknown product code in config.defaults', async () => { organizations[0].save = sinon.stub().resolves(organizations[0]); mockDataAccess.Organization.findById.resolves(organizations[0]); @@ -471,6 +488,56 @@ describe('Organizations Controller', () => { expect(error).to.have.property('message', 'Unknown product code in config.defaults: UNKNOWN_PRODUCT'); }); + it('returns bad request when config.defaults siteId is not a valid UUID', async () => { + organizations[0].save = sinon.stub().resolves(organizations[0]); + mockDataAccess.Organization.findById.resolves(organizations[0]); + + const response = await organizationsController.updateOrganization({ + params: { organizationId: orgId }, + data: { config: { defaults: { ASO: { siteId: 'not-a-uuid' } } } }, + ...context, + }); + + expect(organizations[0].save).to.not.have.been.called; + expect(response.status).to.equal(400); + const error = await response.json(); + expect(error).to.have.property('message', 'Invalid siteId for product ASO in config.defaults'); + }); + + it('returns bad request when config.defaults siteId does not belong to the organization', async () => { + organizations[0].save = sinon.stub().resolves(organizations[0]); + mockDataAccess.Organization.findById.resolves(organizations[0]); + mockDataAccess.Site.findById.resolves({ getOrganizationId: () => 'different-org-id' }); + + const response = await organizationsController.updateOrganization({ + params: { organizationId: orgId }, + data: { config: { defaults: { ASO: { siteId: '550e8400-e29b-41d4-a716-446655440001' } } } }, + ...context, + }); + + expect(organizations[0].save).to.not.have.been.called; + expect(response.status).to.equal(400); + const error = await response.json(); + expect(error).to.have.property('message', 'config.defaults.ASO: site not found or does not belong to this organization'); + }); + + it('returns bad request when config.defaults siteId does not exist', async () => { + organizations[0].save = sinon.stub().resolves(organizations[0]); + mockDataAccess.Organization.findById.resolves(organizations[0]); + mockDataAccess.Site.findById.resolves(null); + + const response = await organizationsController.updateOrganization({ + params: { organizationId: orgId }, + data: { config: { defaults: { ASO: { siteId: '550e8400-e29b-41d4-a716-446655440099' } } } }, + ...context, + }); + + expect(organizations[0].save).to.not.have.been.called; + expect(response.status).to.equal(400); + const error = await response.json(); + expect(error).to.have.property('message', 'config.defaults.ASO: site not found or does not belong to this organization'); + }); + it('gets all organizations', async () => { mockDataAccess.Organization.all.resolves(organizations); From b56f033a9e3f4f9419bc5868ea21550a51881c18 Mon Sep 17 00:00:00 2001 From: ppatwal Date: Tue, 19 May 2026 04:24:33 +0530 Subject: [PATCH 5/9] refactor(SITES-43695): extract resolveOrgDefaultSite to module level Move resolveOrgDefaultSite out of the resolveSite closure to reduce function complexity. The function takes ctx instead of Site and log separately so the signature stays compact. Tests are now split: resolveSite tests cover the wiring (both lookup paths), and a dedicated resolveOrgDefaultSite describe tests the resolution logic directly. Co-Authored-By: Claude Sonnet 4.6 --- src/controllers/sites.js | 106 +++++++++++--------- test/controllers/sites.test.js | 175 +++++++++++---------------------- 2 files changed, 117 insertions(+), 164 deletions(-) diff --git a/src/controllers/sites.js b/src/controllers/sites.js index 164e3e0bf..5de6bd30c 100755 --- a/src/controllers/sites.js +++ b/src/controllers/sites.js @@ -48,6 +48,61 @@ import AccessControlUtil from '../support/access-control-util.js'; import { auditTargetURLsPatchGuard } from '../support/audit-target-urls-validation.js'; import { triggerBrandProfileAgent } from '../support/brand-profile-trigger.js'; +/** + * Resolves the org's per-product default site from config.defaults, validating it belongs + * to the org and is enrolled. Returns the resolved data object or null to fall through + * to getFirstEnrollment(). + * @param {object} org - Organization model instance. + * @param {string} productCode - Product code from x-product header. + * @param {object} context - Request context. + * @param {object} ctx - Controller context (provides dataAccess.Site and log). + * @returns {Promise} Resolved data or null. + */ +export async function resolveOrgDefaultSite(org, productCode, context, ctx) { + const { dataAccess: { Site }, log } = ctx; + try { + const defaultSiteId = org.getConfig()?.defaults?.[productCode]?.siteId; + if (!hasText(defaultSiteId) || !isValidUUID(defaultSiteId)) { + return null; + } + + const defaultSite = await Site.findById(defaultSiteId); + if (!defaultSite) { + log.warn( + `[resolveSite] stale config.defaults entry: site ${defaultSiteId} not found for org ${org.getId()} product ${productCode}`, + ); + return null; + } + if (defaultSite.getOrganizationId() !== org.getId()) { + log.warn( + `[resolveSite] config.defaults cross-org mismatch: site ${defaultSiteId} belongs to org ${defaultSite.getOrganizationId()}, not ${org.getId()} — falling back`, + ); + return null; + } + + const siteTierClient = await TierClient.createForSite(context, defaultSite, productCode); + const { entitlement, enrollments } = await siteTierClient.getAllEnrollment(); + + const tierVisible = entitlement && CUSTOMER_VISIBLE_TIERS.includes(entitlement.getTier()); + if (!tierVisible || !enrollments?.length) { + return null; + } + + const isSummitPlgEnabled = await getIsSummitPlgEnabled(defaultSite, context); + return { + organization: OrganizationDto.toJSON(org), + site: SiteDto.toJSON(defaultSite), + isSummitPlgEnabled, + }; + } catch (e) { + log.warn( + `[resolveSite] resolveOrgDefaultSite failed for org ${org.getId()} product ${productCode} — falling back`, + e, + ); + return null; + } +} + /** * Sites controller. Provides methods to create, read, update and delete sites. * @param {object} ctx - Context of the request. @@ -1208,57 +1263,10 @@ function SitesController(ctx, log, env) { } } - // Resolves the org's per-product default site from config.defaults, validating it belongs - // to the org and is enrolled. Returns the resolved data object or null to fall through - // to getFirstEnrollment(). - const resolveOrgDefaultSite = async (org) => { - try { - const defaultSiteId = org.getConfig()?.defaults?.[productCode]?.siteId; - if (!hasText(defaultSiteId) || !isValidUUID(defaultSiteId)) { - return null; - } - - const defaultSite = await Site.findById(defaultSiteId); - if (!defaultSite) { - ctx.log.warn( - `[resolveSite] stale config.defaults entry: site ${defaultSiteId} not found for org ${org.getId()} product ${productCode}`, - ); - return null; - } - if (defaultSite.getOrganizationId() !== org.getId()) { - ctx.log.warn( - `[resolveSite] config.defaults cross-org mismatch: site ${defaultSiteId} belongs to org ${defaultSite.getOrganizationId()}, not ${org.getId()} — falling back`, - ); - return null; - } - - const siteTierClient = await TierClient.createForSite(context, defaultSite, productCode); - const { entitlement, enrollments } = await siteTierClient.getAllEnrollment(); - - const tierVisible = entitlement && CUSTOMER_VISIBLE_TIERS.includes(entitlement.getTier()); - if (!tierVisible || !enrollments?.length) { - return null; - } - - const isSummitPlgEnabled = await getIsSummitPlgEnabled(defaultSite, context); - return { - organization: OrganizationDto.toJSON(org), - site: SiteDto.toJSON(defaultSite), - isSummitPlgEnabled, - }; - } catch (e) { - ctx.log.warn( - `[resolveSite] resolveOrgDefaultSite failed for org ${org.getId()} product ${productCode} — falling back`, - e, - ); - return null; - } - }; - if (hasText(organizationId) && isValidUUID(organizationId)) { organization = await Organization.findById(organizationId); if (organization && await accessControlUtil.hasAccess(organization)) { - const defaultData = await resolveOrgDefaultSite(organization); + const defaultData = await resolveOrgDefaultSite(organization, productCode, context, ctx); if (defaultData) { return ok({ data: defaultData }); } @@ -1282,7 +1290,7 @@ function SitesController(ctx, log, env) { } else if (hasText(imsOrg)) { organization = await Organization.findByImsOrgId(imsOrg); if (organization && await accessControlUtil.hasAccess(organization)) { - const defaultData = await resolveOrgDefaultSite(organization); + const defaultData = await resolveOrgDefaultSite(organization, productCode, context, ctx); if (defaultData) { return ok({ data: defaultData }); } diff --git a/test/controllers/sites.test.js b/test/controllers/sites.test.js index 8fc874ea1..ce5b41cca 100644 --- a/test/controllers/sites.test.js +++ b/test/controllers/sites.test.js @@ -24,7 +24,7 @@ import nock from 'nock'; import sinonChai from 'sinon-chai'; import sinon, { stub } from 'sinon'; -import SitesController from '../../src/controllers/sites.js'; +import SitesController, { resolveOrgDefaultSite } from '../../src/controllers/sites.js'; import AccessControlUtil from '../../src/support/access-control-util.js'; use(chaiAsPromised); @@ -4522,6 +4522,22 @@ describe('Sites Controller', () => { let testOrganizations; let testSites; + // Must include Config methods because OrganizationDto.toJSON calls Config.toDynamoItem. + const makeConfigWithDefault = (siteId) => ({ + defaults: { abcd: { siteId } }, + getSlackConfig: () => undefined, + getHandlers: () => undefined, + getContentAiConfig: () => undefined, + getImports: () => undefined, + getFetchConfig: () => undefined, + getBrandConfig: () => undefined, + getBrandProfile: () => undefined, + getCdnLogsConfig: () => undefined, + getLlmoConfig: () => undefined, + getTokowakaConfig: () => undefined, + getEdgeOptimizeConfig: () => undefined, + }); + beforeEach(() => { accessControlStub = sandbox.stub(AccessControlUtil.prototype, 'hasAccess').resolves(true); testOrganizations = [ @@ -5089,24 +5105,7 @@ describe('Sites Controller', () => { }); describe('config.defaults resolution', () => { - // The context header 'x-product' is 'abcd', so productCode = 'abcd'. - // Must include Config methods because OrganizationDto.toJSON calls Config.toDynamoItem. - const makeConfigWithDefault = (siteId) => ({ - defaults: { abcd: { siteId } }, - getSlackConfig: () => undefined, - getHandlers: () => undefined, - getContentAiConfig: () => undefined, - getImports: () => undefined, - getFetchConfig: () => undefined, - getBrandConfig: () => undefined, - getBrandProfile: () => undefined, - getCdnLogsConfig: () => undefined, - getLlmoConfig: () => undefined, - getTokowakaConfig: () => undefined, - getEdgeOptimizeConfig: () => undefined, - }); - - it('should resolve config.defaults for organizationId path and skip getFirstEnrollment', async () => { + it('uses config.defaults site when organizationId is provided', async () => { sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[0])); context.data = { organizationId: testOrganizations[0].getId() }; mockDataAccess.Organization.findById.resolves(testOrganizations[0]); @@ -5124,7 +5123,7 @@ describe('Sites Controller', () => { expect(mockTierClientStub.getFirstEnrollment).to.not.have.been.called; }); - it('should resolve config.defaults for imsOrg path and skip getFirstEnrollment', async () => { + it('uses config.defaults site when imsOrg is provided', async () => { sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[0])); context.data = { imsOrg: testOrganizations[0].getImsOrgId() }; mockDataAccess.Organization.findByImsOrgId.resolves(testOrganizations[0]); @@ -5142,12 +5141,10 @@ describe('Sites Controller', () => { expect(mockTierClientStub.getFirstEnrollment).to.not.have.been.called; }); - it('should fall through to getFirstEnrollment if config.defaults site does not belong to org', async () => { - // testSites[1] belongs to testOrganizations[3], not testOrganizations[0] - sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[1])); + it('falls back to getFirstEnrollment when config.defaults returns null', async () => { + sandbox.stub(testOrganizations[0], 'getConfig').returns({ defaults: {} }); context.data = { organizationId: testOrganizations[0].getId() }; mockDataAccess.Organization.findById.resolves(testOrganizations[0]); - mockDataAccess.Site.findById.resolves(testSites[1]); mockTierClientStub.getFirstEnrollment.resolves({ entitlement: { getTier: () => 'FREE_TRIAL' }, site: testSites[0], @@ -5157,128 +5154,76 @@ describe('Sites Controller', () => { expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; }); + }); - it('should fall through to getFirstEnrollment if config.defaults site is not found', async () => { - sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[0])); - context.data = { organizationId: testOrganizations[0].getId() }; - mockDataAccess.Organization.findById.resolves(testOrganizations[0]); - mockDataAccess.Site.findById.resolves(null); - mockTierClientStub.getFirstEnrollment.resolves({ - entitlement: { getTier: () => 'FREE_TRIAL' }, - site: testSites[0], - }); - - await sitesController.resolveSite(context); - - expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; - }); + describe('resolveOrgDefaultSite', () => { + const productCode = 'abcd'; + let mockCtx; + let org; - it('should fall through to getFirstEnrollment if config.defaults site has no valid enrollment', async () => { - sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[0])); - context.data = { organizationId: testOrganizations[0].getId() }; - mockDataAccess.Organization.findById.resolves(testOrganizations[0]); + beforeEach(() => { + [org] = testOrganizations; + mockCtx = { dataAccess: mockDataAccess, log: { warn: sandbox.stub() } }; + sandbox.stub(org, 'getConfig').returns(makeConfigWithDefault(SITE_IDS[0])); mockDataAccess.Site.findById.resolves(testSites[0]); mockTierClientStub.getAllEnrollment.resolves({ entitlement: { getTier: () => 'FREE_TRIAL' }, - enrollments: [], - }); - mockTierClientStub.getFirstEnrollment.resolves({ - entitlement: { getTier: () => 'FREE_TRIAL' }, - site: testSites[0], + enrollments: [{ getId: () => 'enrollment-1' }], }); + }); - await sitesController.resolveSite(context); + it('returns site data when the configured default site is valid and enrolled', async () => { + const result = await resolveOrgDefaultSite(org, productCode, context, mockCtx); - expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; + expect(result).to.not.be.null; + expect(result.site.id).to.equal(SITE_IDS[0]); }); - it('should fall through to getFirstEnrollment if config.defaults siteId is not a valid UUID', async () => { - sandbox.stub(testOrganizations[0], 'getConfig').returns( - makeConfigWithDefault('not-a-valid-uuid'), - ); - context.data = { organizationId: testOrganizations[0].getId() }; - mockDataAccess.Organization.findById.resolves(testOrganizations[0]); - mockTierClientStub.getFirstEnrollment.resolves({ - entitlement: { getTier: () => 'FREE_TRIAL' }, - site: testSites[0], - }); + it('returns null when org has no default configured for the product', async () => { + org.getConfig.returns({ defaults: {} }); - await sitesController.resolveSite(context); + const result = await resolveOrgDefaultSite(org, productCode, context, mockCtx); - expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; + expect(result).to.be.null; expect(mockDataAccess.Site.findById).to.not.have.been.called; }); - it('should fall through to getFirstEnrollment if config.defaults site has a non-customer-visible tier (PRE_ONBOARD)', async () => { - sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[0])); - context.data = { organizationId: testOrganizations[0].getId() }; - mockDataAccess.Organization.findById.resolves(testOrganizations[0]); - mockDataAccess.Site.findById.resolves(testSites[0]); - mockTierClientStub.getAllEnrollment.resolves({ - entitlement: { getTier: () => 'PRE_ONBOARD' }, - enrollments: [{ getId: () => 'enrollment-1' }], - }); - mockTierClientStub.getFirstEnrollment.resolves({ - entitlement: { getTier: () => 'FREE_TRIAL' }, - site: testSites[0], - }); + it('returns null and warns when the configured site no longer exists', async () => { + mockDataAccess.Site.findById.resolves(null); - await sitesController.resolveSite(context); + const result = await resolveOrgDefaultSite(org, productCode, context, mockCtx); - expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; + expect(result).to.be.null; + expect(mockCtx.log.warn).to.have.been.called; }); - it('should fall through to getFirstEnrollment if config.defaults site has no entitlement', async () => { - sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[0])); - context.data = { organizationId: testOrganizations[0].getId() }; - mockDataAccess.Organization.findById.resolves(testOrganizations[0]); - mockDataAccess.Site.findById.resolves(testSites[0]); - mockTierClientStub.getAllEnrollment.resolves({ - entitlement: null, - enrollments: [], - }); - mockTierClientStub.getFirstEnrollment.resolves({ - entitlement: { getTier: () => 'FREE_TRIAL' }, - site: testSites[0], - }); + it('returns null and warns when the configured site belongs to a different org', async () => { + mockDataAccess.Site.findById.resolves(testSites[1]); - await sitesController.resolveSite(context); + const result = await resolveOrgDefaultSite(org, productCode, context, mockCtx); - expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; + expect(result).to.be.null; + expect(mockCtx.log.warn).to.have.been.called; }); - it('should fall through to getFirstEnrollment via imsOrg path if config.defaults site belongs to a different org', async () => { - // testSites[1] belongs to testOrganizations[3], not testOrganizations[0] - sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[1])); - context.data = { imsOrg: testOrganizations[0].getImsOrgId() }; - mockDataAccess.Organization.findByImsOrgId.resolves(testOrganizations[0]); - mockDataAccess.Site.findById.resolves(testSites[1]); - mockTierClientStub.getFirstEnrollment.resolves({ + it('returns null when the configured site is not actively enrolled', async () => { + mockTierClientStub.getAllEnrollment.resolves({ entitlement: { getTier: () => 'FREE_TRIAL' }, - site: testSites[0], + enrollments: [], }); - await sitesController.resolveSite(context); + const result = await resolveOrgDefaultSite(org, productCode, context, mockCtx); - expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; + expect(result).to.be.null; }); - it('should fall through to getFirstEnrollment if TierClient.createForSite throws', async () => { - sandbox.stub(testOrganizations[0], 'getConfig').returns(makeConfigWithDefault(SITE_IDS[0])); - context.data = { organizationId: testOrganizations[0].getId() }; - mockDataAccess.Organization.findById.resolves(testOrganizations[0]); - mockDataAccess.Site.findById.resolves(testSites[0]); - TierClient.createForSite.throws(new Error('TierClient error')); - mockTierClientStub.getFirstEnrollment.resolves({ - entitlement: { getTier: () => 'FREE_TRIAL' }, - site: testSites[0], - }); + it('returns null gracefully when TierClient throws', async () => { + TierClient.createForSite.throws(new Error('tier service unavailable')); - const response = await sitesController.resolveSite(context); + const result = await resolveOrgDefaultSite(org, productCode, context, mockCtx); - // Should fall through (not throw a 500) - expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; - expect(response.status).to.not.equal(500); + expect(result).to.be.null; + expect(mockCtx.log.warn).to.have.been.called; }); }); }); From 02bb42bba31ddc513b7b3bcc22c261b464362660 Mon Sep 17 00:00:00 2001 From: ppatwal Date: Tue, 19 May 2026 05:14:22 +0530 Subject: [PATCH 6/9] refactor(SITES-43695): eliminate duplicated resolve-data building and redundant config guard Extract buildResolveData helper used in resolveOrgDefaultSite, resolveByOrg, and the siteId path instead of repeating the same three-field response construction. Nest config.defaults validation inside the existing isObject(config) branch in organizations.js to remove the duplicated guard and validate before mutating. Co-Authored-By: Claude Sonnet 4.6 --- src/controllers/organizations.js | 33 ++++++++++++++-------------- src/controllers/sites.js | 37 +++++++++++++------------------- 2 files changed, 31 insertions(+), 39 deletions(-) diff --git a/src/controllers/organizations.js b/src/controllers/organizations.js index 6227ed719..03af03c8b 100644 --- a/src/controllers/organizations.js +++ b/src/controllers/organizations.js @@ -358,27 +358,26 @@ function OrganizationsController(ctx, env) { } if (isObject(requestBody.config)) { - organization.setConfig(requestBody.config); - updates = true; - } - - if (isObject(requestBody.config) && isObject(requestBody.config.defaults)) { - const VALID_PRODUCT_CODES = new Set(Object.values(EntitlementModel.PRODUCT_CODES)); - for (const [productCode, entry] of Object.entries(requestBody.config.defaults)) { - if (!VALID_PRODUCT_CODES.has(productCode)) { - return badRequest(`Unknown product code in config.defaults: ${productCode}`); - } - if (isObject(entry) && entry.siteId != null) { - if (!isValidUUID(entry.siteId)) { - return badRequest(`Invalid siteId for product ${productCode} in config.defaults`); + if (isObject(requestBody.config.defaults)) { + const VALID_PRODUCT_CODES = new Set(Object.values(EntitlementModel.PRODUCT_CODES)); + for (const [productCode, entry] of Object.entries(requestBody.config.defaults)) { + if (!VALID_PRODUCT_CODES.has(productCode)) { + return badRequest(`Unknown product code in config.defaults: ${productCode}`); } - // eslint-disable-next-line no-await-in-loop - const site = await Site.findById(entry.siteId); - if (!site || site.getOrganizationId() !== organization.getId()) { - return badRequest(`config.defaults.${productCode}: site not found or does not belong to this organization`); + if (isObject(entry) && entry.siteId != null) { + if (!isValidUUID(entry.siteId)) { + return badRequest(`Invalid siteId for product ${productCode} in config.defaults`); + } + // eslint-disable-next-line no-await-in-loop + const site = await Site.findById(entry.siteId); + if (!site || site.getOrganizationId() !== organization.getId()) { + return badRequest(`config.defaults.${productCode}: site not found or does not belong to this organization`); + } } } } + organization.setConfig(requestBody.config); + updates = true; } if (updates) { diff --git a/src/controllers/sites.js b/src/controllers/sites.js index e9d0da20a..83b5a4256 100755 --- a/src/controllers/sites.js +++ b/src/controllers/sites.js @@ -50,6 +50,18 @@ import { auditTargetURLsPatchGuard } from '../support/audit-target-urls-validati import { updateRumConfig } from '../support/rum-config-service.js'; import { triggerBrandProfileAgent } from '../support/brand-profile-trigger.js'; +/** + * Builds the standard resolve-site success payload. + */ +async function buildResolveData(org, site, context) { + const isSummitPlgEnabled = await getIsSummitPlgEnabled(site, context); + return { + organization: OrganizationDto.toJSON(org), + site: SiteDto.toJSON(site), + isSummitPlgEnabled, + }; +} + /** * Resolves the org's per-product default site from config.defaults, validating it belongs * to the org and is enrolled. Returns the resolved data object or null to fall through @@ -90,12 +102,7 @@ export async function resolveOrgDefaultSite(org, productCode, context, ctx) { return null; } - const isSummitPlgEnabled = await getIsSummitPlgEnabled(defaultSite, context); - return { - organization: OrganizationDto.toJSON(org), - site: SiteDto.toJSON(defaultSite), - isSummitPlgEnabled, - }; + return buildResolveData(org, defaultSite, context); } catch (e) { log.warn( `[resolveSite] resolveOrgDefaultSite failed for org ${org.getId()} product ${productCode} — falling back`, @@ -1312,14 +1319,7 @@ function SitesController(ctx, log, env) { if (enrolledSite && (accessControlUtil.hasAdminAccess() || CUSTOMER_VISIBLE_TIERS.includes(entitlement.getTier()))) { - const isSummitPlgEnabled = await getIsSummitPlgEnabled(enrolledSite, context); - return ok({ - data: { - organization: OrganizationDto.toJSON(org), - site: SiteDto.toJSON(enrolledSite), - isSummitPlgEnabled, - }, - }); + return ok({ data: await buildResolveData(org, enrolledSite, context) }); } return resolveFailure('No site found for the provided parameters', 'site_not_enrolled', failureDetails); @@ -1372,14 +1372,7 @@ function SitesController(ctx, log, env) { return resolveFailure('No site found for the provided parameters', 'site_not_enrolled', failureDetails); } - const isSummitPlgEnabled = await getIsSummitPlgEnabled(site, context); - return ok({ - data: { - organization: OrganizationDto.toJSON(organization), - site: SiteDto.toJSON(site), - isSummitPlgEnabled, - }, - }); + return ok({ data: await buildResolveData(organization, site, context) }); } } } From 9dd20cbbdc013d07c97e3f024984192436ae58d7 Mon Sep 17 00:00:00 2001 From: ppatwal Date: Tue, 19 May 2026 05:41:27 +0530 Subject: [PATCH 7/9] chore: sync package-lock.json with package.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit package.json already required 3.65.0 of several shared packages but the lock file still referenced older versions, causing npm ci to fail. No dependency changes — lock file regenerated to match existing package.json requirements. Co-Authored-By: Claude Sonnet 4.6 --- package-lock.json | 1741 ++++++++------------------------------------- 1 file changed, 278 insertions(+), 1463 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6961e2441..c6222edc6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,25 +16,25 @@ "@adobe/helix-shared-wrap": "2.0.2", "@adobe/helix-status": "10.1.5", "@adobe/helix-universal-logger": "3.0.29", - "@adobe/mysticat-shared-seo-client": "1.3.0", + "@adobe/mysticat-shared-seo-client": "1.3.1", "@adobe/spacecat-helix-content-sdk": "1.4.33", - "@adobe/spacecat-shared-athena-client": "1.9.11", - "@adobe/spacecat-shared-brand-client": "1.1.41", - "@adobe/spacecat-shared-content-client": "1.8.23", - "@adobe/spacecat-shared-data-access": "3.63.0", + "@adobe/spacecat-shared-athena-client": "1.9.12", + "@adobe/spacecat-shared-brand-client": "1.1.42", + "@adobe/spacecat-shared-content-client": "1.8.24", + "@adobe/spacecat-shared-data-access": "3.65.0", "@adobe/spacecat-shared-data-access-v2": "npm:@adobe/spacecat-shared-data-access@2.109.0", - "@adobe/spacecat-shared-drs-client": "1.7.1", - "@adobe/spacecat-shared-gpt-client": "1.6.22", - "@adobe/spacecat-shared-http-utils": "1.27.1", - "@adobe/spacecat-shared-ims-client": "1.12.6", + "@adobe/spacecat-shared-drs-client": "1.7.2", + "@adobe/spacecat-shared-gpt-client": "1.6.23", + "@adobe/spacecat-shared-http-utils": "1.27.2", + "@adobe/spacecat-shared-ims-client": "1.12.7", "@adobe/spacecat-shared-launchdarkly-client": "^1.1.0", - "@adobe/spacecat-shared-rum-api-client": "2.40.12", - "@adobe/spacecat-shared-scrape-client": "2.6.2", - "@adobe/spacecat-shared-slack-client": "1.6.6", - "@adobe/spacecat-shared-tier-client": "1.5.0", - "@adobe/spacecat-shared-tokowaka-client": "1.16.1", + "@adobe/spacecat-shared-rum-api-client": "2.40.13", + "@adobe/spacecat-shared-scrape-client": "2.6.3", + "@adobe/spacecat-shared-slack-client": "1.6.7", + "@adobe/spacecat-shared-tier-client": "1.5.1", + "@adobe/spacecat-shared-tokowaka-client": "1.16.2", "@adobe/spacecat-shared-utils": "1.115.4", - "@adobe/spacecat-shared-vault-secrets": "1.3.4", + "@adobe/spacecat-shared-vault-secrets": "1.3.5", "@aws-sdk/client-s3": "3.1045.0", "@aws-sdk/client-secrets-manager": "3.1045.0", "@aws-sdk/client-sfn": "3.1045.0", @@ -56,6 +56,7 @@ "date-fns": "4.1.0", "fuse.js": "7.3.0", "iso-639-3": "3.0.1", + "isomorphic-git": "^1.38.1", "js-yaml": "4.1.1", "node-html-parser": "7.1.0", "package-lock.json": "^1.0.0", @@ -97,10 +98,10 @@ "mocha": "11.7.5", "mocha-multi-reporters": "1.5.1", "mocha-suppress-logs": "0.6.0", - "nock": "14.0.15", + "nock": "^14.0.15", "nodemon": "3.1.14", "semantic-release": "^25.0.3", - "sinon": "22.0.0", + "sinon": "^22.0.0", "sinon-chai": "4.0.1", "yaml": "2.8.4" }, @@ -469,6 +470,32 @@ "tslib": "^2.6.2" } }, + "node_modules/@adobe/helix-deploy/node_modules/isomorphic-git": { + "version": "1.37.6", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.37.6.tgz", + "integrity": "sha512-qr1NFCPsVTZ6YGqTXw0CzamnsHyH9QQ1OTEfeXIweSljRUMzuHFCJdUn0wc6OcjtTDns6knxjPb7N6LmJeftOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-lock": "^1.4.1", + "clean-git-ref": "^2.0.1", + "crc-32": "^1.2.0", + "diff3": "0.0.3", + "ignore": "^5.1.4", + "minimisted": "^2.0.0", + "pako": "^1.0.10", + "pify": "^4.0.1", + "readable-stream": "^4.0.0", + "sha.js": "^2.4.12", + "simple-get": "^4.0.1" + }, + "bin": { + "isogit": "cli.cjs" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/@adobe/helix-docx2md": { "version": "1.9.7", "resolved": "https://registry.npmjs.org/@adobe/helix-docx2md/-/helix-docx2md-1.9.7.tgz", @@ -799,9 +826,9 @@ } }, "node_modules/@adobe/mysticat-shared-seo-client": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@adobe/mysticat-shared-seo-client/-/mysticat-shared-seo-client-1.3.0.tgz", - "integrity": "sha512-ivkhI+W2HlCQEMPhHLzSTQXmlkLU4EDZld/6ThFXKAskGsW9phLCe4+SLnsJ5hISjBp/quI8VO/gBHhlPjHeSw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@adobe/mysticat-shared-seo-client/-/mysticat-shared-seo-client-1.3.1.tgz", + "integrity": "sha512-z3p42HCkN4Cbg06g4dX/XWfcYb74WM/CqDREWGlqLAch/qptzeOSprI8nb22ck4EJikNgScEvhZgv1kKPyzfIQ==", "license": "Apache-2.0", "dependencies": { "@adobe/fetch": "4.3.0", @@ -1464,13 +1491,13 @@ } }, "node_modules/@adobe/spacecat-shared-athena-client": { - "version": "1.9.11", - "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-athena-client/-/spacecat-shared-athena-client-1.9.11.tgz", - "integrity": "sha512-YWyQR7FRh404zOG+9WSbhLkJAd55i1lyzctBR9Garcyf8Hhn9U/snEh7SkSeneEbm7LcCOOo6XypfcFE51U6Fw==", + "version": "1.9.12", + "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-athena-client/-/spacecat-shared-athena-client-1.9.12.tgz", + "integrity": "sha512-TWeJHY7KpVmb+k/XCJ2xXdpQ5cHAY4LRZfXVoxDShVCPwqzcZQcRvfM8VvOXGmZa5CB7fOwkEwKEZLq/It9j9g==", "license": "Apache-2.0", "dependencies": { "@adobe/spacecat-shared-utils": "1.96.3", - "@aws-sdk/client-athena": "3.1024.0" + "@aws-sdk/client-athena": "3.1045.0" }, "engines": { "node": ">=22.0.0 <25.0.0", @@ -2058,9 +2085,9 @@ } }, "node_modules/@adobe/spacecat-shared-brand-client": { - "version": "1.1.41", - "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-brand-client/-/spacecat-shared-brand-client-1.1.41.tgz", - "integrity": "sha512-ZT+AT9WTrZdu2zwvulaGbsEjQGoA7ZQh/VjRaYhWIMtqweqF/Mw+g/2AEjQ27QyRMil9OWSKykKlDBf+8p5qIA==", + "version": "1.1.42", + "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-brand-client/-/spacecat-shared-brand-client-1.1.42.tgz", + "integrity": "sha512-8OgJ+zEaQs4nSY6yx2ZeOfTX7D7dC2nEC5ynWkfynanqIItFfz+CMhr+bYGOBtRRmlpdbznN3sO2AbrYW9V95Q==", "license": "Apache-2.0", "dependencies": { "@adobe/helix-universal": "5.4.1", @@ -2729,15 +2756,15 @@ } }, "node_modules/@adobe/spacecat-shared-content-client": { - "version": "1.8.23", - "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-content-client/-/spacecat-shared-content-client-1.8.23.tgz", - "integrity": "sha512-OYxjXrPbO2wikU08EOOLwiMkV4/jwWCrNTRfwhf2vNqx4yoLdpHZbMTCu+KZI5vRTxwkZWWe0II20QLQgcMVJQ==", + "version": "1.8.24", + "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-content-client/-/spacecat-shared-content-client-1.8.24.tgz", + "integrity": "sha512-6UirRPJ+IcVWdA1GG068OAC87L1i0fpADYjQVf8N0yAYO1Xd5m+akpIDxIgbQEjTYjTW7wYrj0ZblsRr7UQ8Yw==", "license": "Apache-2.0", "dependencies": { "@adobe/helix-universal": "5.4.1", "@adobe/spacecat-helix-content-sdk": "1.4.33", "@adobe/spacecat-shared-utils": "1.81.1", - "@aws-sdk/client-secrets-manager": "3.1024.0", + "@aws-sdk/client-secrets-manager": "3.1045.0", "aws-xray-sdk": "3.12.0", "graph-data-structure": "4.5.0" }, @@ -2836,465 +2863,6 @@ "node": ">=18.0.0" } }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager": { - "version": "3.1024.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.1024.0.tgz", - "integrity": "sha512-EXbgMqueA5gw/jqpE2zMWAfBnzn6cZWqCISGdfn1201Um9IAIoTcHjyWoQMALQm0f8Lu1NF6yRtngs6zpZcagQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.26", - "@aws-sdk/credential-provider-node": "^3.972.29", - "@aws-sdk/middleware-host-header": "^3.972.8", - "@aws-sdk/middleware-logger": "^3.972.8", - "@aws-sdk/middleware-recursion-detection": "^3.972.9", - "@aws-sdk/middleware-user-agent": "^3.972.28", - "@aws-sdk/region-config-resolver": "^3.972.10", - "@aws-sdk/types": "^3.973.6", - "@aws-sdk/util-endpoints": "^3.996.5", - "@aws-sdk/util-user-agent-browser": "^3.972.8", - "@aws-sdk/util-user-agent-node": "^3.973.14", - "@smithy/config-resolver": "^4.4.13", - "@smithy/core": "^3.23.13", - "@smithy/fetch-http-handler": "^5.3.15", - "@smithy/hash-node": "^4.2.12", - "@smithy/invalid-dependency": "^4.2.12", - "@smithy/middleware-content-length": "^4.2.12", - "@smithy/middleware-endpoint": "^4.4.28", - "@smithy/middleware-retry": "^4.4.46", - "@smithy/middleware-serde": "^4.2.16", - "@smithy/middleware-stack": "^4.2.12", - "@smithy/node-config-provider": "^4.3.12", - "@smithy/node-http-handler": "^4.5.1", - "@smithy/protocol-http": "^5.3.12", - "@smithy/smithy-client": "^4.12.8", - "@smithy/types": "^4.13.1", - "@smithy/url-parser": "^4.2.12", - "@smithy/util-base64": "^4.3.2", - "@smithy/util-body-length-browser": "^4.2.2", - "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.44", - "@smithy/util-defaults-mode-node": "^4.2.48", - "@smithy/util-endpoints": "^3.3.3", - "@smithy/util-middleware": "^4.2.12", - "@smithy/util-retry": "^4.2.13", - "@smithy/util-utf8": "^4.2.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/core": { - "version": "3.973.27", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.27.tgz", - "integrity": "sha512-CUZ5m8hwMCH6OYI4Li/WgMfIEx10Q2PLI9Y3XOUTPGZJ53aZ0007jCv+X/ywsaERyKPdw5MRZWk877roQksQ4A==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/xml-builder": "^3.972.17", - "@smithy/core": "^3.23.14", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/property-provider": "^4.2.13", - "@smithy/protocol-http": "^5.3.13", - "@smithy/signature-v4": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", - "@smithy/util-base64": "^4.3.2", - "@smithy/util-middleware": "^4.2.13", - "@smithy/util-utf8": "^4.2.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-env": { - "version": "3.972.25", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.25.tgz", - "integrity": "sha512-6QfI0wv4jpG5CrdO/AO0JfZ2ux+tKwJPrUwmvxXF50vI5KIypKVGNF6b4vlkYEnKumDTI1NX2zUBi8JoU5QU3A==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-http": { - "version": "3.972.27", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.27.tgz", - "integrity": "sha512-3V3Usj9Gs93h865DqN4M2NWJhC5kXU9BvZskfN3+69omuYlE3TZxOEcVQtBGLOloJB7BVfJKXVLqeNhOzHqSlQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/types": "^3.973.7", - "@smithy/fetch-http-handler": "^5.3.16", - "@smithy/node-http-handler": "^4.5.2", - "@smithy/property-provider": "^4.2.13", - "@smithy/protocol-http": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", - "@smithy/util-stream": "^4.5.22", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.972.29", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.29.tgz", - "integrity": "sha512-SiBuAnXecCbT/OpAf3vqyI/AVE3mTaYr9ShXLybxZiPLBiPCCOIWSGAtYYGQWMRvobBTiqOewaB+wcgMMZI2Aw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/credential-provider-env": "^3.972.25", - "@aws-sdk/credential-provider-http": "^3.972.27", - "@aws-sdk/credential-provider-login": "^3.972.29", - "@aws-sdk/credential-provider-process": "^3.972.25", - "@aws-sdk/credential-provider-sso": "^3.972.29", - "@aws-sdk/credential-provider-web-identity": "^3.972.29", - "@aws-sdk/nested-clients": "^3.996.19", - "@aws-sdk/types": "^3.973.7", - "@smithy/credential-provider-imds": "^4.2.13", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-login": { - "version": "3.972.29", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.29.tgz", - "integrity": "sha512-OGOslTbOlxXexKMqhxCEbBQbUIfuhGxU5UXw3Fm56ypXHvrXH4aTt/xb5Y884LOoteP1QST1lVZzHfcTnWhiPQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/nested-clients": "^3.996.19", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/protocol-http": "^5.3.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-node": { - "version": "3.972.30", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.30.tgz", - "integrity": "sha512-FMnAnWxc8PG+ZrZ2OBKzY4luCUJhe9CG0B9YwYr4pzrYGLXBS2rl+UoUvjGbAwiptxRL6hyA3lFn03Bv1TLqTw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/credential-provider-env": "^3.972.25", - "@aws-sdk/credential-provider-http": "^3.972.27", - "@aws-sdk/credential-provider-ini": "^3.972.29", - "@aws-sdk/credential-provider-process": "^3.972.25", - "@aws-sdk/credential-provider-sso": "^3.972.29", - "@aws-sdk/credential-provider-web-identity": "^3.972.29", - "@aws-sdk/types": "^3.973.7", - "@smithy/credential-provider-imds": "^4.2.13", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-process": { - "version": "3.972.25", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.25.tgz", - "integrity": "sha512-HR7ynNRdNhNsdVCOCegy1HsfsRzozCOPtD3RzzT1JouuaHobWyRfJzCBue/3jP7gECHt+kQyZUvwg/cYLWurNQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.972.29", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.29.tgz", - "integrity": "sha512-HWv4SEq3jZDYPlwryZVef97+U8CxxRos5mK8sgGO1dQaFZpV5giZLzqGE5hkDmh2csYcBO2uf5XHjPTpZcJlig==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/nested-clients": "^3.996.19", - "@aws-sdk/token-providers": "3.1026.0", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.972.29", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.29.tgz", - "integrity": "sha512-PdMBza1WEKEUPFEmMGCfnU2RYCz9MskU2e8JxjyUOsMKku7j9YaDKvbDi2dzC0ihFoM6ods2SbhfAAro+Gwlew==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/nested-clients": "^3.996.19", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/middleware-host-header": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.9.tgz", - "integrity": "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/protocol-http": "^5.3.13", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/middleware-logger": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.9.tgz", - "integrity": "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.972.10", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.10.tgz", - "integrity": "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@aws/lambda-invoke-store": "^0.2.2", - "@smithy/protocol-http": "^5.3.13", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.972.29", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.29.tgz", - "integrity": "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/util-endpoints": "^3.996.6", - "@smithy/core": "^3.23.14", - "@smithy/protocol-http": "^5.3.13", - "@smithy/types": "^4.14.0", - "@smithy/util-retry": "^4.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/nested-clients": { - "version": "3.996.19", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.19.tgz", - "integrity": "sha512-uFkmCDXvmQYLanlYdOFS0+MQWkrj9wPMt/ZCc/0J0fjPim6F5jBVBmEomvGY/j77ILW6GTPwN22Jc174Mhkw6Q==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/middleware-host-header": "^3.972.9", - "@aws-sdk/middleware-logger": "^3.972.9", - "@aws-sdk/middleware-recursion-detection": "^3.972.10", - "@aws-sdk/middleware-user-agent": "^3.972.29", - "@aws-sdk/region-config-resolver": "^3.972.11", - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/util-endpoints": "^3.996.6", - "@aws-sdk/util-user-agent-browser": "^3.972.9", - "@aws-sdk/util-user-agent-node": "^3.973.15", - "@smithy/config-resolver": "^4.4.14", - "@smithy/core": "^3.23.14", - "@smithy/fetch-http-handler": "^5.3.16", - "@smithy/hash-node": "^4.2.13", - "@smithy/invalid-dependency": "^4.2.13", - "@smithy/middleware-content-length": "^4.2.13", - "@smithy/middleware-endpoint": "^4.4.29", - "@smithy/middleware-retry": "^4.5.0", - "@smithy/middleware-serde": "^4.2.17", - "@smithy/middleware-stack": "^4.2.13", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/node-http-handler": "^4.5.2", - "@smithy/protocol-http": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", - "@smithy/url-parser": "^4.2.13", - "@smithy/util-base64": "^4.3.2", - "@smithy/util-body-length-browser": "^4.2.2", - "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.45", - "@smithy/util-defaults-mode-node": "^4.2.49", - "@smithy/util-endpoints": "^3.3.4", - "@smithy/util-middleware": "^4.2.13", - "@smithy/util-retry": "^4.3.0", - "@smithy/util-utf8": "^4.2.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/region-config-resolver": { - "version": "3.972.11", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.11.tgz", - "integrity": "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/config-resolver": "^4.4.14", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/token-providers": { - "version": "3.1026.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1026.0.tgz", - "integrity": "sha512-Ieq/HiRrbEtrYP387Nes0XlR7H1pJiJOZKv+QyQzMYpvTiDs0VKy2ZB3E2Zf+aFovWmeE7lRE4lXyF7dYM6GgA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/nested-clients": "^3.996.19", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/types": { - "version": "3.973.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.7.tgz", - "integrity": "sha512-reXRwoJ6CfChoqAsBszUYajAF8Z2LRE+CRcKocvFSMpIiLOtYU3aJ9trmn6VVPAzbbY5LXF+FfmUslbXk1SYFg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/util-endpoints": { - "version": "3.996.6", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.6.tgz", - "integrity": "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/types": "^4.14.0", - "@smithy/url-parser": "^4.2.13", - "@smithy/util-endpoints": "^3.3.4", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.9.tgz", - "integrity": "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/types": "^4.14.0", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.973.15", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.15.tgz", - "integrity": "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/middleware-user-agent": "^3.972.29", - "@aws-sdk/types": "^3.973.7", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/types": "^4.14.0", - "@smithy/util-config-provider": "^4.2.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "aws-crt": ">=1.0.0" - }, - "peerDependenciesMeta": { - "aws-crt": { - "optional": true - } - } - }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/xml-builder": { - "version": "3.972.17", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.17.tgz", - "integrity": "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.14.0", - "fast-xml-parser": "5.5.8", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, "node_modules/@adobe/spacecat-shared-content-client/node_modules/@aws-sdk/client-sqs": { "version": "3.940.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.940.0.tgz", @@ -3775,26 +3343,6 @@ } } }, - "node_modules/@adobe/spacecat-shared-content-client/node_modules/fast-xml-parser": { - "version": "5.5.8", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.8.tgz", - "integrity": "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "dependencies": { - "fast-xml-builder": "^1.1.4", - "path-expression-matcher": "^1.2.0", - "strnum": "^2.2.0" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, "node_modules/@adobe/spacecat-shared-content-client/node_modules/zod": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", @@ -3805,9 +3353,9 @@ } }, "node_modules/@adobe/spacecat-shared-data-access": { - "version": "3.63.0", - "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-data-access/-/spacecat-shared-data-access-3.63.0.tgz", - "integrity": "sha512-3ZjwhQig41OuhEhRpAO+LyBmViz31E4nb18rFDVIZ2md1Fn0eyGmCaTAvlO49f2dziMBdJUcHeO7TOkF4+RlGw==", + "version": "3.65.0", + "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-data-access/-/spacecat-shared-data-access-3.65.0.tgz", + "integrity": "sha512-if0tvFUn4BjL5ABwwk0PyK8KBkEgsavafDePC5TnG3WF8KdBAvjS8Ef485grrZyHsyfx7HA5o5bd/IKE66rJ3Q==", "license": "Apache-2.0", "dependencies": { "@adobe/fetch": "^4.2.3", @@ -4732,9 +4280,9 @@ } }, "node_modules/@adobe/spacecat-shared-drs-client": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-drs-client/-/spacecat-shared-drs-client-1.7.1.tgz", - "integrity": "sha512-5XusGrHHSXtiaR0MPnMsT35KWulyhroyuOk35zGvQGD4S0gady3acZ0+6S35Bh8Gl000G6dHqFL9ZTg+MGYg0A==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-drs-client/-/spacecat-shared-drs-client-1.7.2.tgz", + "integrity": "sha512-ENlvz/0Q4Kp5gsU2kbbYudVAk+Qk8ex5a2Ld0ryWH+4uNL1BWBR1AFtaa0CsTVcWRGkD+cFjV3gHP7QkdC41UA==", "license": "Apache-2.0", "dependencies": { "@adobe/spacecat-shared-utils": "1.98.1", @@ -5035,9 +4583,9 @@ } }, "node_modules/@adobe/spacecat-shared-gpt-client": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-gpt-client/-/spacecat-shared-gpt-client-1.6.22.tgz", - "integrity": "sha512-BMzdR+5VPVHNDbtgqfkXn/k7Kfsy6MqARkYUEgFGN3+KydRzDBPp9bTPPM7bI0rMPNhrhgyiijACZX08vpzUtQ==", + "version": "1.6.23", + "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-gpt-client/-/spacecat-shared-gpt-client-1.6.23.tgz", + "integrity": "sha512-R8YiqPAs8aim1jehbaKZrMmnLydcc1yGHtgSEIePPlRiMyWfNz4Ydn9UuQ+pSmvAhRsiiPpcTUP96lHCdurfnw==", "license": "Apache-2.0", "dependencies": { "@adobe/fetch": "4.3.0", @@ -5707,15 +5255,15 @@ } }, "node_modules/@adobe/spacecat-shared-http-utils": { - "version": "1.27.1", - "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-http-utils/-/spacecat-shared-http-utils-1.27.1.tgz", - "integrity": "sha512-f8HcDcff8ywX3U+mz1IzemAKqOAYgvnFX6e5INUgHsJvxSZDayMCFpcQdSc8yZluZXfXwJ4SZfDbjjIKYBtyNA==", + "version": "1.27.2", + "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-http-utils/-/spacecat-shared-http-utils-1.27.2.tgz", + "integrity": "sha512-/uZRBhLFuBTViSX15v57c1QTld3etzMyku2PMkGHQ5fYU05nEdbx5AVF5E0Bq0DbiQPKFfVS41MLhygJoYRftQ==", "license": "Apache-2.0", "dependencies": { "@adobe/fetch": "4.3.0", "@adobe/spacecat-shared-launchdarkly-client": "1.0.4", "@adobe/spacecat-shared-utils": "1.81.1", - "jose": "6.2.2" + "jose": "6.2.3" }, "engines": { "node": ">=22.0.0 <25.0.0", @@ -6317,15 +5865,6 @@ } } }, - "node_modules/@adobe/spacecat-shared-http-utils/node_modules/jose": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.2.tgz", - "integrity": "sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, "node_modules/@adobe/spacecat-shared-http-utils/node_modules/zod": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", @@ -6336,15 +5875,15 @@ } }, "node_modules/@adobe/spacecat-shared-ims-client": { - "version": "1.12.6", - "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-ims-client/-/spacecat-shared-ims-client-1.12.6.tgz", - "integrity": "sha512-yVU3hjcsXMBEWVWp/Q/w5agHrjbWQWmThwSMJe9bt4Y8G6qoaXDoV4uOdeU+NA5YlX1f4drH2RT/EaKodGXm2w==", + "version": "1.12.7", + "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-ims-client/-/spacecat-shared-ims-client-1.12.7.tgz", + "integrity": "sha512-mkO5tLod8s1V0WiLnsK2oikPgOmADd5A3PFA5XGVjIKKMo5ewxVpPIV/Q3mTfi1CvcWYdDMdZCs4Ltxl1PaobQ==", "license": "Apache-2.0", "dependencies": { "@adobe/fetch": "4.3.0", "@adobe/helix-universal": "5.4.1", "@adobe/spacecat-shared-utils": "1.81.1", - "@aws-sdk/client-secrets-manager": "3.1024.0", + "@aws-sdk/client-secrets-manager": "3.1045.0", "aws-xray-sdk": "3.12.0" }, "engines": { @@ -6442,465 +5981,6 @@ "node": ">=18.0.0" } }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager": { - "version": "3.1024.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.1024.0.tgz", - "integrity": "sha512-EXbgMqueA5gw/jqpE2zMWAfBnzn6cZWqCISGdfn1201Um9IAIoTcHjyWoQMALQm0f8Lu1NF6yRtngs6zpZcagQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.26", - "@aws-sdk/credential-provider-node": "^3.972.29", - "@aws-sdk/middleware-host-header": "^3.972.8", - "@aws-sdk/middleware-logger": "^3.972.8", - "@aws-sdk/middleware-recursion-detection": "^3.972.9", - "@aws-sdk/middleware-user-agent": "^3.972.28", - "@aws-sdk/region-config-resolver": "^3.972.10", - "@aws-sdk/types": "^3.973.6", - "@aws-sdk/util-endpoints": "^3.996.5", - "@aws-sdk/util-user-agent-browser": "^3.972.8", - "@aws-sdk/util-user-agent-node": "^3.973.14", - "@smithy/config-resolver": "^4.4.13", - "@smithy/core": "^3.23.13", - "@smithy/fetch-http-handler": "^5.3.15", - "@smithy/hash-node": "^4.2.12", - "@smithy/invalid-dependency": "^4.2.12", - "@smithy/middleware-content-length": "^4.2.12", - "@smithy/middleware-endpoint": "^4.4.28", - "@smithy/middleware-retry": "^4.4.46", - "@smithy/middleware-serde": "^4.2.16", - "@smithy/middleware-stack": "^4.2.12", - "@smithy/node-config-provider": "^4.3.12", - "@smithy/node-http-handler": "^4.5.1", - "@smithy/protocol-http": "^5.3.12", - "@smithy/smithy-client": "^4.12.8", - "@smithy/types": "^4.13.1", - "@smithy/url-parser": "^4.2.12", - "@smithy/util-base64": "^4.3.2", - "@smithy/util-body-length-browser": "^4.2.2", - "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.44", - "@smithy/util-defaults-mode-node": "^4.2.48", - "@smithy/util-endpoints": "^3.3.3", - "@smithy/util-middleware": "^4.2.12", - "@smithy/util-retry": "^4.2.13", - "@smithy/util-utf8": "^4.2.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/core": { - "version": "3.973.27", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.27.tgz", - "integrity": "sha512-CUZ5m8hwMCH6OYI4Li/WgMfIEx10Q2PLI9Y3XOUTPGZJ53aZ0007jCv+X/ywsaERyKPdw5MRZWk877roQksQ4A==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/xml-builder": "^3.972.17", - "@smithy/core": "^3.23.14", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/property-provider": "^4.2.13", - "@smithy/protocol-http": "^5.3.13", - "@smithy/signature-v4": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", - "@smithy/util-base64": "^4.3.2", - "@smithy/util-middleware": "^4.2.13", - "@smithy/util-utf8": "^4.2.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-env": { - "version": "3.972.25", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.25.tgz", - "integrity": "sha512-6QfI0wv4jpG5CrdO/AO0JfZ2ux+tKwJPrUwmvxXF50vI5KIypKVGNF6b4vlkYEnKumDTI1NX2zUBi8JoU5QU3A==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-http": { - "version": "3.972.27", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.27.tgz", - "integrity": "sha512-3V3Usj9Gs93h865DqN4M2NWJhC5kXU9BvZskfN3+69omuYlE3TZxOEcVQtBGLOloJB7BVfJKXVLqeNhOzHqSlQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/types": "^3.973.7", - "@smithy/fetch-http-handler": "^5.3.16", - "@smithy/node-http-handler": "^4.5.2", - "@smithy/property-provider": "^4.2.13", - "@smithy/protocol-http": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", - "@smithy/util-stream": "^4.5.22", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.972.29", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.29.tgz", - "integrity": "sha512-SiBuAnXecCbT/OpAf3vqyI/AVE3mTaYr9ShXLybxZiPLBiPCCOIWSGAtYYGQWMRvobBTiqOewaB+wcgMMZI2Aw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/credential-provider-env": "^3.972.25", - "@aws-sdk/credential-provider-http": "^3.972.27", - "@aws-sdk/credential-provider-login": "^3.972.29", - "@aws-sdk/credential-provider-process": "^3.972.25", - "@aws-sdk/credential-provider-sso": "^3.972.29", - "@aws-sdk/credential-provider-web-identity": "^3.972.29", - "@aws-sdk/nested-clients": "^3.996.19", - "@aws-sdk/types": "^3.973.7", - "@smithy/credential-provider-imds": "^4.2.13", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-login": { - "version": "3.972.29", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.29.tgz", - "integrity": "sha512-OGOslTbOlxXexKMqhxCEbBQbUIfuhGxU5UXw3Fm56ypXHvrXH4aTt/xb5Y884LOoteP1QST1lVZzHfcTnWhiPQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/nested-clients": "^3.996.19", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/protocol-http": "^5.3.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-node": { - "version": "3.972.30", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.30.tgz", - "integrity": "sha512-FMnAnWxc8PG+ZrZ2OBKzY4luCUJhe9CG0B9YwYr4pzrYGLXBS2rl+UoUvjGbAwiptxRL6hyA3lFn03Bv1TLqTw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/credential-provider-env": "^3.972.25", - "@aws-sdk/credential-provider-http": "^3.972.27", - "@aws-sdk/credential-provider-ini": "^3.972.29", - "@aws-sdk/credential-provider-process": "^3.972.25", - "@aws-sdk/credential-provider-sso": "^3.972.29", - "@aws-sdk/credential-provider-web-identity": "^3.972.29", - "@aws-sdk/types": "^3.973.7", - "@smithy/credential-provider-imds": "^4.2.13", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-process": { - "version": "3.972.25", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.25.tgz", - "integrity": "sha512-HR7ynNRdNhNsdVCOCegy1HsfsRzozCOPtD3RzzT1JouuaHobWyRfJzCBue/3jP7gECHt+kQyZUvwg/cYLWurNQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.972.29", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.29.tgz", - "integrity": "sha512-HWv4SEq3jZDYPlwryZVef97+U8CxxRos5mK8sgGO1dQaFZpV5giZLzqGE5hkDmh2csYcBO2uf5XHjPTpZcJlig==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/nested-clients": "^3.996.19", - "@aws-sdk/token-providers": "3.1026.0", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.972.29", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.29.tgz", - "integrity": "sha512-PdMBza1WEKEUPFEmMGCfnU2RYCz9MskU2e8JxjyUOsMKku7j9YaDKvbDi2dzC0ihFoM6ods2SbhfAAro+Gwlew==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/nested-clients": "^3.996.19", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/middleware-host-header": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.9.tgz", - "integrity": "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/protocol-http": "^5.3.13", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/middleware-logger": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.9.tgz", - "integrity": "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.972.10", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.10.tgz", - "integrity": "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@aws/lambda-invoke-store": "^0.2.2", - "@smithy/protocol-http": "^5.3.13", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.972.29", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.29.tgz", - "integrity": "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/util-endpoints": "^3.996.6", - "@smithy/core": "^3.23.14", - "@smithy/protocol-http": "^5.3.13", - "@smithy/types": "^4.14.0", - "@smithy/util-retry": "^4.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/nested-clients": { - "version": "3.996.19", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.19.tgz", - "integrity": "sha512-uFkmCDXvmQYLanlYdOFS0+MQWkrj9wPMt/ZCc/0J0fjPim6F5jBVBmEomvGY/j77ILW6GTPwN22Jc174Mhkw6Q==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/middleware-host-header": "^3.972.9", - "@aws-sdk/middleware-logger": "^3.972.9", - "@aws-sdk/middleware-recursion-detection": "^3.972.10", - "@aws-sdk/middleware-user-agent": "^3.972.29", - "@aws-sdk/region-config-resolver": "^3.972.11", - "@aws-sdk/types": "^3.973.7", - "@aws-sdk/util-endpoints": "^3.996.6", - "@aws-sdk/util-user-agent-browser": "^3.972.9", - "@aws-sdk/util-user-agent-node": "^3.973.15", - "@smithy/config-resolver": "^4.4.14", - "@smithy/core": "^3.23.14", - "@smithy/fetch-http-handler": "^5.3.16", - "@smithy/hash-node": "^4.2.13", - "@smithy/invalid-dependency": "^4.2.13", - "@smithy/middleware-content-length": "^4.2.13", - "@smithy/middleware-endpoint": "^4.4.29", - "@smithy/middleware-retry": "^4.5.0", - "@smithy/middleware-serde": "^4.2.17", - "@smithy/middleware-stack": "^4.2.13", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/node-http-handler": "^4.5.2", - "@smithy/protocol-http": "^5.3.13", - "@smithy/smithy-client": "^4.12.9", - "@smithy/types": "^4.14.0", - "@smithy/url-parser": "^4.2.13", - "@smithy/util-base64": "^4.3.2", - "@smithy/util-body-length-browser": "^4.2.2", - "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.45", - "@smithy/util-defaults-mode-node": "^4.2.49", - "@smithy/util-endpoints": "^3.3.4", - "@smithy/util-middleware": "^4.2.13", - "@smithy/util-retry": "^4.3.0", - "@smithy/util-utf8": "^4.2.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/region-config-resolver": { - "version": "3.972.11", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.11.tgz", - "integrity": "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/config-resolver": "^4.4.14", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/token-providers": { - "version": "3.1026.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1026.0.tgz", - "integrity": "sha512-Ieq/HiRrbEtrYP387Nes0XlR7H1pJiJOZKv+QyQzMYpvTiDs0VKy2ZB3E2Zf+aFovWmeE7lRE4lXyF7dYM6GgA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.27", - "@aws-sdk/nested-clients": "^3.996.19", - "@aws-sdk/types": "^3.973.7", - "@smithy/property-provider": "^4.2.13", - "@smithy/shared-ini-file-loader": "^4.4.8", - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/types": { - "version": "3.973.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.7.tgz", - "integrity": "sha512-reXRwoJ6CfChoqAsBszUYajAF8Z2LRE+CRcKocvFSMpIiLOtYU3aJ9trmn6VVPAzbbY5LXF+FfmUslbXk1SYFg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.14.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/util-endpoints": { - "version": "3.996.6", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.6.tgz", - "integrity": "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/types": "^4.14.0", - "@smithy/url-parser": "^4.2.13", - "@smithy/util-endpoints": "^3.3.4", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.9.tgz", - "integrity": "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.7", - "@smithy/types": "^4.14.0", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.973.15", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.15.tgz", - "integrity": "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/middleware-user-agent": "^3.972.29", - "@aws-sdk/types": "^3.973.7", - "@smithy/node-config-provider": "^4.3.13", - "@smithy/types": "^4.14.0", - "@smithy/util-config-provider": "^4.2.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "aws-crt": ">=1.0.0" - }, - "peerDependenciesMeta": { - "aws-crt": { - "optional": true - } - } - }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/xml-builder": { - "version": "3.972.17", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.17.tgz", - "integrity": "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.14.0", - "fast-xml-parser": "5.5.8", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, "node_modules/@adobe/spacecat-shared-ims-client/node_modules/@aws-sdk/client-sqs": { "version": "3.940.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.940.0.tgz", @@ -7381,26 +6461,6 @@ } } }, - "node_modules/@adobe/spacecat-shared-ims-client/node_modules/fast-xml-parser": { - "version": "5.5.8", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.8.tgz", - "integrity": "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "dependencies": { - "fast-xml-builder": "^1.1.4", - "path-expression-matcher": "^1.2.0", - "strnum": "^2.2.0" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, "node_modules/@adobe/spacecat-shared-ims-client/node_modules/zod": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", @@ -8005,9 +7065,9 @@ } }, "node_modules/@adobe/spacecat-shared-rum-api-client": { - "version": "2.40.12", - "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-rum-api-client/-/spacecat-shared-rum-api-client-2.40.12.tgz", - "integrity": "sha512-96hwODD1Fn9DU3u3GszE3HjtHTs5vI0LOj9FgrNwVE6HdzFNnCgR1h3qckdNgmn6YP4YHCjCw56BPloiYJhoVw==", + "version": "2.40.13", + "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-rum-api-client/-/spacecat-shared-rum-api-client-2.40.13.tgz", + "integrity": "sha512-UcgbDOvUAmuN32WuTAgwRYxXCfN5C8xyD170KBXRn0pPK4Zlp1xQU3p3nEcZd8+iarDzX4LQsfL+jv6PNTj7xA==", "license": "Apache-2.0", "dependencies": { "@adobe/fetch": "4.3.0", @@ -8603,9 +7663,9 @@ } }, "node_modules/@adobe/spacecat-shared-scrape-client": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-scrape-client/-/spacecat-shared-scrape-client-2.6.2.tgz", - "integrity": "sha512-4zqI5P6CuXjh6wxg+W43BQGhF3O4QMjywDMTVh2y9EmLhsZ79ickQeR+mqCaS/PwRuhFkQ/+ex/IkoXamft40Q==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-scrape-client/-/spacecat-shared-scrape-client-2.6.3.tgz", + "integrity": "sha512-osYG7IkFwUIvTvH368uAuEvrnNiphzyOLnuxgATeoHQo+CcmsPVBu5zLKfy2soTeHjjjLD8xE2Q5/lFDgKFUAw==", "license": "Apache-2.0", "dependencies": { "@adobe/helix-universal": "5.4.1", @@ -9197,14 +8257,14 @@ } }, "node_modules/@adobe/spacecat-shared-slack-client": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-slack-client/-/spacecat-shared-slack-client-1.6.6.tgz", - "integrity": "sha512-+M2NCwrJqUMLggoOIa1ZJ/sMnyc8xNGFYTl5ePwiyzIH1XFbHDf2gsgN44ABj3FW0xap7mX2ohoXe/EMdePvKQ==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-slack-client/-/spacecat-shared-slack-client-1.6.7.tgz", + "integrity": "sha512-zchiSmBcg3ck4Lw4WhoL6/kESw0oSaE6etr7K1+gH/+W1gLBDGPV8AfE292YdWYT8tvS8qCWTur/opxKGsOiKA==", "license": "Apache-2.0", "dependencies": { "@adobe/helix-universal": "5.4.1", "@adobe/spacecat-shared-utils": "1.81.1", - "@slack/web-api": "7.15.0" + "@slack/web-api": "7.15.2" }, "engines": { "node": ">=22.0.0 <25.0.0", @@ -9781,30 +8841,6 @@ } } }, - "node_modules/@adobe/spacecat-shared-slack-client/node_modules/@slack/web-api": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-7.15.0.tgz", - "integrity": "sha512-va7zYIt3QHG1x9M/jqXXRPFMoOVlVSSRHC5YH+DzKYsrz5xUKOA3lR4THsu/Zxha9N1jOndbKFKLtr0WOPW1Vw==", - "license": "MIT", - "dependencies": { - "@slack/logger": "^4.0.1", - "@slack/types": "^2.20.1", - "@types/node": ">=18", - "@types/retry": "0.12.0", - "axios": "^1.13.5", - "eventemitter3": "^5.0.1", - "form-data": "^4.0.4", - "is-electron": "2.2.2", - "is-stream": "^2", - "p-queue": "^6", - "p-retry": "^4", - "retry": "^0.13.1" - }, - "engines": { - "node": ">= 18", - "npm": ">= 8.6.0" - } - }, "node_modules/@adobe/spacecat-shared-slack-client/node_modules/zod": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", @@ -9815,9 +8851,9 @@ } }, "node_modules/@adobe/spacecat-shared-tier-client": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-tier-client/-/spacecat-shared-tier-client-1.5.0.tgz", - "integrity": "sha512-+OPIzMyeEnsHjvdqZGnKoSygxpO7j1JvfS8TWy2pUnGg7aqEBpH9vRfzEEIfWVFIjFhVtIn8b/3OKlEFCjI6YA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-tier-client/-/spacecat-shared-tier-client-1.5.1.tgz", + "integrity": "sha512-fNvpkvqaDoatYNnP2XUGdHOVRLil90H4qKQVzoIhhFRogRIRT8vs2rUNjTQvZywBc7NRZfmoXf0oYHzE3OAXMA==", "license": "Apache-2.0", "dependencies": { "@adobe/spacecat-shared-utils": "1.81.1", @@ -10408,14 +9444,14 @@ } }, "node_modules/@adobe/spacecat-shared-tokowaka-client": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-tokowaka-client/-/spacecat-shared-tokowaka-client-1.16.1.tgz", - "integrity": "sha512-VFEtClbLTWwLaF/sGf/OaYgyd0W3arl5kdZl/UkGoEj7/Oeq9pT0UQBupgy65W3kgpwQja5XQYXjzW/I5S1uOQ==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-tokowaka-client/-/spacecat-shared-tokowaka-client-1.16.2.tgz", + "integrity": "sha512-l39q27onNu9B7J76NtZypr+8quH7rFhnwHpW8z0Hc4VDKhZ7KRJoCNGzzGpkMEPOE6iRNBxppqZgJVsIBhcbKw==", "license": "Apache-2.0", "dependencies": { "@adobe/spacecat-shared-utils": "1.81.1", - "@aws-sdk/client-cloudfront": "3.1024.0", - "@aws-sdk/client-s3": "3.1024.0", + "@aws-sdk/client-cloudfront": "3.1045.0", + "@aws-sdk/client-s3": "3.1045.0", "hast-util-from-html": "2.0.3", "mdast-util-from-markdown": "2.0.3", "mdast-util-to-hast": "13.2.1", @@ -10732,174 +9768,6 @@ } } }, - "node_modules/@adobe/spacecat-shared-tokowaka-client/node_modules/@aws-sdk/client-s3": { - "version": "3.1024.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1024.0.tgz", - "integrity": "sha512-8qdO5aLCzaf9l0RdrSBW1iIroRKP2QBqtZ6lkrtHKiaaH0B18xEn+lrEgiN/eCf3uRAYk4cqbnI2XcWzm+7dDQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha1-browser": "5.2.0", - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.26", - "@aws-sdk/credential-provider-node": "^3.972.29", - "@aws-sdk/middleware-bucket-endpoint": "^3.972.8", - "@aws-sdk/middleware-expect-continue": "^3.972.8", - "@aws-sdk/middleware-flexible-checksums": "^3.974.6", - "@aws-sdk/middleware-host-header": "^3.972.8", - "@aws-sdk/middleware-location-constraint": "^3.972.8", - "@aws-sdk/middleware-logger": "^3.972.8", - "@aws-sdk/middleware-recursion-detection": "^3.972.9", - "@aws-sdk/middleware-sdk-s3": "^3.972.27", - "@aws-sdk/middleware-ssec": "^3.972.8", - "@aws-sdk/middleware-user-agent": "^3.972.28", - "@aws-sdk/region-config-resolver": "^3.972.10", - "@aws-sdk/signature-v4-multi-region": "^3.996.15", - "@aws-sdk/types": "^3.973.6", - "@aws-sdk/util-endpoints": "^3.996.5", - "@aws-sdk/util-user-agent-browser": "^3.972.8", - "@aws-sdk/util-user-agent-node": "^3.973.14", - "@smithy/config-resolver": "^4.4.13", - "@smithy/core": "^3.23.13", - "@smithy/eventstream-serde-browser": "^4.2.12", - "@smithy/eventstream-serde-config-resolver": "^4.3.12", - "@smithy/eventstream-serde-node": "^4.2.12", - "@smithy/fetch-http-handler": "^5.3.15", - "@smithy/hash-blob-browser": "^4.2.13", - "@smithy/hash-node": "^4.2.12", - "@smithy/hash-stream-node": "^4.2.12", - "@smithy/invalid-dependency": "^4.2.12", - "@smithy/md5-js": "^4.2.12", - "@smithy/middleware-content-length": "^4.2.12", - "@smithy/middleware-endpoint": "^4.4.28", - "@smithy/middleware-retry": "^4.4.46", - "@smithy/middleware-serde": "^4.2.16", - "@smithy/middleware-stack": "^4.2.12", - "@smithy/node-config-provider": "^4.3.12", - "@smithy/node-http-handler": "^4.5.1", - "@smithy/protocol-http": "^5.3.12", - "@smithy/smithy-client": "^4.12.8", - "@smithy/types": "^4.13.1", - "@smithy/url-parser": "^4.2.12", - "@smithy/util-base64": "^4.3.2", - "@smithy/util-body-length-browser": "^4.2.2", - "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.44", - "@smithy/util-defaults-mode-node": "^4.2.48", - "@smithy/util-endpoints": "^3.3.3", - "@smithy/util-middleware": "^4.2.12", - "@smithy/util-retry": "^4.2.13", - "@smithy/util-stream": "^4.5.21", - "@smithy/util-utf8": "^4.2.2", - "@smithy/util-waiter": "^4.2.14", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-tokowaka-client/node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-host-header": { - "version": "3.972.10", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.10.tgz", - "integrity": "sha512-IJSsIMeVQ8MMCPbuh1AbltkFhLBLXn7aejzfX5YKT/VLDHn++Dcz8886tXckE+wQssyPUhaXrJhdakO2VilRhg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.8", - "@smithy/protocol-http": "^5.3.14", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-tokowaka-client/node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-logger": { - "version": "3.972.10", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.10.tgz", - "integrity": "sha512-OOuGvvz1Dm20SjZo5oEBePFqxt5nf8AwkNDSyUHvD9/bfNASmstcYxFAHUowy4n6Io7mWUZ04JURZwSBvyQanQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.8", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-tokowaka-client/node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.972.11", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.11.tgz", - "integrity": "sha512-+zz6f79Kj9V5qFK2P+D8Ehjnw4AhphAlCAsPjUqEcInA9umtSSKMrHbSagEeOIsDNuvVrH98bjRHcyQukTrhaQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.8", - "@aws/lambda-invoke-store": "^0.2.2", - "@smithy/protocol-http": "^5.3.14", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-tokowaka-client/node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/region-config-resolver": { - "version": "3.972.13", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.13.tgz", - "integrity": "sha512-CvJ2ZIjK/jVD/lbOpowBVElJyC1YxLTIJ13yM0AEo0t2v7swOzGjSA6lJGH+DwZXQhcjUjoYwc8bVYCX5MDr1A==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.8", - "@smithy/config-resolver": "^4.4.17", - "@smithy/node-config-provider": "^4.3.14", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-tokowaka-client/node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/types": { - "version": "3.973.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.8.tgz", - "integrity": "sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-tokowaka-client/node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/util-endpoints": { - "version": "3.996.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.8.tgz", - "integrity": "sha512-oOZHcRDihk5iEe5V25NVWg45b3qEA8OpHWVdU/XQh8Zj4heVPAJqWvMphQnU7LkufmUo10EpvFPZuQMiFLJK3g==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.8", - "@smithy/types": "^4.14.1", - "@smithy/url-parser": "^4.2.14", - "@smithy/util-endpoints": "^3.4.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@adobe/spacecat-shared-tokowaka-client/node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.972.10", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.10.tgz", - "integrity": "sha512-FAzqXvfEssGdSIz8ejatan0bOdx1qefBWKF/gWmVBXIP1HkS7v/wjjaqrAGGKvyihrXTXW00/2/1nTJtxpXz7g==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.8", - "@smithy/types": "^4.14.1", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - } - }, "node_modules/@adobe/spacecat-shared-tokowaka-client/node_modules/@aws-sdk/client-sqs": { "version": "3.940.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.940.0.tgz", @@ -11633,9 +10501,9 @@ } }, "node_modules/@adobe/spacecat-shared-vault-secrets": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-vault-secrets/-/spacecat-shared-vault-secrets-1.3.4.tgz", - "integrity": "sha512-GWnAsaeComj6i55PE/S4SxVlaYqrgbtXtqNbXS/FIsLe01JQhBxaHHxgB6m6mhf58WGpobe5EDa44n6nDGvy7w==", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@adobe/spacecat-shared-vault-secrets/-/spacecat-shared-vault-secrets-1.3.5.tgz", + "integrity": "sha512-Cki+INCuViMQFEKARcHQ97Z6iHRA91tQkHIsfslnLhIzK9jUWY2yFGy5o0/DBogeX7j6ldy0DBTZEc6RdcoBeA==", "license": "Apache-2.0", "dependencies": { "@adobe/fetch": "4.3.0", @@ -12019,48 +10887,48 @@ } }, "node_modules/@aws-sdk/client-athena": { - "version": "3.1024.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-athena/-/client-athena-3.1024.0.tgz", - "integrity": "sha512-kKnsdeh58Se7GL+9HX56KWtjS55W3OuzZwGVXq20PXgY2N53d6+NI9I1w+X0cZJo2pz3JijiJ+3S76YYCBoprw==", + "version": "3.1045.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-athena/-/client-athena-3.1045.0.tgz", + "integrity": "sha512-g5E7Bt9FFZSMloQeLlEE1JabVvLh5k9749sv95UPz7r0Lwj6mT0WkMgDZ/3q/YgafeM4Ug+Ttoxpje+0gc5hRQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.26", - "@aws-sdk/credential-provider-node": "^3.972.29", - "@aws-sdk/middleware-host-header": "^3.972.8", - "@aws-sdk/middleware-logger": "^3.972.8", - "@aws-sdk/middleware-recursion-detection": "^3.972.9", - "@aws-sdk/middleware-user-agent": "^3.972.28", - "@aws-sdk/region-config-resolver": "^3.972.10", - "@aws-sdk/types": "^3.973.6", - "@aws-sdk/util-endpoints": "^3.996.5", - "@aws-sdk/util-user-agent-browser": "^3.972.8", - "@aws-sdk/util-user-agent-node": "^3.973.14", - "@smithy/config-resolver": "^4.4.13", - "@smithy/core": "^3.23.13", - "@smithy/fetch-http-handler": "^5.3.15", - "@smithy/hash-node": "^4.2.12", - "@smithy/invalid-dependency": "^4.2.12", - "@smithy/middleware-content-length": "^4.2.12", - "@smithy/middleware-endpoint": "^4.4.28", - "@smithy/middleware-retry": "^4.4.46", - "@smithy/middleware-serde": "^4.2.16", - "@smithy/middleware-stack": "^4.2.12", - "@smithy/node-config-provider": "^4.3.12", - "@smithy/node-http-handler": "^4.5.1", - "@smithy/protocol-http": "^5.3.12", - "@smithy/smithy-client": "^4.12.8", - "@smithy/types": "^4.13.1", - "@smithy/url-parser": "^4.2.12", + "@aws-sdk/core": "^3.974.8", + "@aws-sdk/credential-provider-node": "^3.972.39", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.38", + "@aws-sdk/region-config-resolver": "^3.972.13", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.8", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.24", + "@smithy/config-resolver": "^4.4.17", + "@smithy/core": "^3.23.17", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.32", + "@smithy/middleware-retry": "^4.5.7", + "@smithy/middleware-serde": "^4.2.20", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.44", - "@smithy/util-defaults-mode-node": "^4.2.48", - "@smithy/util-endpoints": "^3.3.3", - "@smithy/util-middleware": "^4.2.12", - "@smithy/util-retry": "^4.2.13", + "@smithy/util-defaults-mode-browser": "^4.3.49", + "@smithy/util-defaults-mode-node": "^4.2.54", + "@smithy/util-endpoints": "^3.4.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.6", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, @@ -12069,14 +10937,12 @@ } }, "node_modules/@aws-sdk/client-athena/node_modules/@aws-sdk/middleware-host-header": { - "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.8.tgz", - "integrity": "sha512-wAr2REfKsqoKQ+OkNqvOShnBoh+nkPurDKW7uAeVSu6kUECnWlSJiPvnoqxGlfousEY/v9LfS9sNc46hjSYDIQ==", + "version": "3.972.13", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.13.tgz", + "integrity": "sha512-EA3+u2LD3kGcfRNmCSjyJuzX4XvG4zYv57i4ZksH+1IEciuSyHQGvzivEz7vZ+jbRPdAAe7WWKy/4M8InCKDcw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.6", - "@smithy/protocol-http": "^5.3.12", - "@smithy/types": "^4.13.1", + "@aws-sdk/core": "^3.974.12", "tslib": "^2.6.2" }, "engines": { @@ -12084,13 +10950,12 @@ } }, "node_modules/@aws-sdk/client-athena/node_modules/@aws-sdk/middleware-logger": { - "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.8.tgz", - "integrity": "sha512-CWl5UCM57WUFaFi5kB7IBY1UmOeLvNZAZ2/OZ5l20ldiJ3TiIz1pC65gYj8X0BCPWkeR1E32mpsCk1L1I4n+lA==", + "version": "3.972.12", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.12.tgz", + "integrity": "sha512-NxB2dS4/mV3380hNkC72TkhMaLLjWGGBeTAEucqlJptVVovTbNmQWZLwaMC74ICo9NZHmFiBVVTHzDfAh/3y6Q==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.6", - "@smithy/types": "^4.13.1", + "@aws-sdk/core": "^3.974.12", "tslib": "^2.6.2" }, "engines": { @@ -12098,15 +10963,12 @@ } }, "node_modules/@aws-sdk/client-athena/node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.9.tgz", - "integrity": "sha512-/Wt5+CT8dpTFQxEJ9iGy/UGrXr7p2wlIOEHvIr/YcHYByzoLjrqkYqXdJjd9UIgWjv7eqV2HnFJen93UTuwfTQ==", + "version": "3.972.14", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.14.tgz", + "integrity": "sha512-bqL+upATpOJ/7px4IVfMVxcM6Lyt9uRizmEx3mNg4N6+IQlnOaYXXOJ4TNX6P0mKPPW0lwn9ZW8QEhXwQuCH9A==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.6", - "@aws/lambda-invoke-store": "^0.2.2", - "@smithy/protocol-http": "^5.3.12", - "@smithy/types": "^4.13.1", + "@aws-sdk/core": "^3.974.12", "tslib": "^2.6.2" }, "engines": { @@ -12114,15 +10976,12 @@ } }, "node_modules/@aws-sdk/client-athena/node_modules/@aws-sdk/region-config-resolver": { - "version": "3.972.10", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.10.tgz", - "integrity": "sha512-1dq9ToC6e070QvnVhhbAs3bb5r6cQ10gTVc6cyRV5uvQe7P138TV2uG2i6+Yok4bAkVAcx5AqkTEBUvWEtBlsQ==", + "version": "3.972.16", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.16.tgz", + "integrity": "sha512-/YaivCvKUkEeMN9VTKBSvBn5w/4osAM1YboM58DKaLF/vqFGf/FdJCLmppqiPPJWZaXcASqByVjc3evE7KHKdA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.6", - "@smithy/config-resolver": "^4.4.13", - "@smithy/node-config-provider": "^4.3.12", - "@smithy/types": "^4.13.1", + "@aws-sdk/core": "^3.974.12", "tslib": "^2.6.2" }, "engines": { @@ -12130,12 +10989,12 @@ } }, "node_modules/@aws-sdk/client-athena/node_modules/@aws-sdk/types": { - "version": "3.973.6", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.6.tgz", - "integrity": "sha512-Atfcy4E++beKtwJHiDln2Nby8W/mam64opFPTiHEqgsthqeydFS1pY+OUlN1ouNOmf8ArPU/6cDS65anOP3KQw==", + "version": "3.973.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.8.tgz", + "integrity": "sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.13.1", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -12143,15 +11002,13 @@ } }, "node_modules/@aws-sdk/client-athena/node_modules/@aws-sdk/util-endpoints": { - "version": "3.996.5", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.5.tgz", - "integrity": "sha512-Uh93L5sXFNbyR5sEPMzUU8tJ++Ku97EY4udmC01nB8Zu+xfBPwpIwJ6F7snqQeq8h2pf+8SGN5/NoytfKgYPIw==", + "version": "3.996.11", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.11.tgz", + "integrity": "sha512-BUMJ6VoL54r6Udj/wKy8uKRIndL04rGbaS/wTIV0dM1ewxSrR8yARBHdvZKQsK55ZSW2JrmAPk3KP15kBDxJMw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.6", - "@smithy/types": "^4.13.1", - "@smithy/url-parser": "^4.2.12", - "@smithy/util-endpoints": "^3.3.3", + "@aws-sdk/core": "^3.974.12", + "@smithy/core": "^3.24.2", "tslib": "^2.6.2" }, "engines": { @@ -12159,63 +11016,61 @@ } }, "node_modules/@aws-sdk/client-athena/node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.8.tgz", - "integrity": "sha512-B3KGXJviV2u6Cdw2SDY2aDhoJkVfY/Q/Trwk2CMSkikE1Oi6gRzxhvhIfiRpHfmIsAhV4EA54TVEX8K6CbHbkA==", + "version": "3.972.13", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.13.tgz", + "integrity": "sha512-wfk9ZdVwh187gdGXB1EyAoprwjSMt/bSfVtva+OaZx+LyNdKD7smlZf611yMd42UpfQ9vaS8NOftjSajgpdd+w==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.6", - "@smithy/types": "^4.13.1", - "bowser": "^2.11.0", + "@aws-sdk/core": "^3.974.12", "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/client-cloudfront": { - "version": "3.1024.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudfront/-/client-cloudfront-3.1024.0.tgz", - "integrity": "sha512-jd3Mva86RKznPndyzlISIJt6seqc55gBuJprGKFraOq8KDbWjXniFLuz6QTG0qvTA82nVp5+6PX45Yzuye7ArQ==", + "version": "3.1045.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudfront/-/client-cloudfront-3.1045.0.tgz", + "integrity": "sha512-84RIiLrMXcinBK1JXnP1bOavvQ+jxTxN4xsB20e39MfOZMyr7wIxMNn35kTYTg8UTJgN7zwEgzGJo64sU3mtPw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.26", - "@aws-sdk/credential-provider-node": "^3.972.29", - "@aws-sdk/middleware-host-header": "^3.972.8", - "@aws-sdk/middleware-logger": "^3.972.8", - "@aws-sdk/middleware-recursion-detection": "^3.972.9", - "@aws-sdk/middleware-user-agent": "^3.972.28", - "@aws-sdk/region-config-resolver": "^3.972.10", - "@aws-sdk/types": "^3.973.6", - "@aws-sdk/util-endpoints": "^3.996.5", - "@aws-sdk/util-user-agent-browser": "^3.972.8", - "@aws-sdk/util-user-agent-node": "^3.973.14", - "@smithy/config-resolver": "^4.4.13", - "@smithy/core": "^3.23.13", - "@smithy/fetch-http-handler": "^5.3.15", - "@smithy/hash-node": "^4.2.12", - "@smithy/invalid-dependency": "^4.2.12", - "@smithy/middleware-content-length": "^4.2.12", - "@smithy/middleware-endpoint": "^4.4.28", - "@smithy/middleware-retry": "^4.4.46", - "@smithy/middleware-serde": "^4.2.16", - "@smithy/middleware-stack": "^4.2.12", - "@smithy/node-config-provider": "^4.3.12", - "@smithy/node-http-handler": "^4.5.1", - "@smithy/protocol-http": "^5.3.12", - "@smithy/smithy-client": "^4.12.8", - "@smithy/types": "^4.13.1", - "@smithy/url-parser": "^4.2.12", + "@aws-sdk/core": "^3.974.8", + "@aws-sdk/credential-provider-node": "^3.972.39", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.38", + "@aws-sdk/region-config-resolver": "^3.972.13", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.8", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.24", + "@smithy/config-resolver": "^4.4.17", + "@smithy/core": "^3.23.17", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.32", + "@smithy/middleware-retry": "^4.5.7", + "@smithy/middleware-serde": "^4.2.20", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.44", - "@smithy/util-defaults-mode-node": "^4.2.48", - "@smithy/util-endpoints": "^3.3.3", - "@smithy/util-middleware": "^4.2.12", - "@smithy/util-retry": "^4.2.13", - "@smithy/util-stream": "^4.5.21", + "@smithy/util-defaults-mode-browser": "^4.3.49", + "@smithy/util-defaults-mode-node": "^4.2.54", + "@smithy/util-endpoints": "^3.4.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.6", + "@smithy/util-stream": "^4.5.25", "@smithy/util-utf8": "^4.2.2", - "@smithy/util-waiter": "^4.2.14", + "@smithy/util-waiter": "^4.3.0", "tslib": "^2.6.2" }, "engines": { @@ -12223,14 +11078,12 @@ } }, "node_modules/@aws-sdk/client-cloudfront/node_modules/@aws-sdk/middleware-host-header": { - "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.8.tgz", - "integrity": "sha512-wAr2REfKsqoKQ+OkNqvOShnBoh+nkPurDKW7uAeVSu6kUECnWlSJiPvnoqxGlfousEY/v9LfS9sNc46hjSYDIQ==", + "version": "3.972.13", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.13.tgz", + "integrity": "sha512-EA3+u2LD3kGcfRNmCSjyJuzX4XvG4zYv57i4ZksH+1IEciuSyHQGvzivEz7vZ+jbRPdAAe7WWKy/4M8InCKDcw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.6", - "@smithy/protocol-http": "^5.3.12", - "@smithy/types": "^4.13.1", + "@aws-sdk/core": "^3.974.12", "tslib": "^2.6.2" }, "engines": { @@ -12238,13 +11091,12 @@ } }, "node_modules/@aws-sdk/client-cloudfront/node_modules/@aws-sdk/middleware-logger": { - "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.8.tgz", - "integrity": "sha512-CWl5UCM57WUFaFi5kB7IBY1UmOeLvNZAZ2/OZ5l20ldiJ3TiIz1pC65gYj8X0BCPWkeR1E32mpsCk1L1I4n+lA==", + "version": "3.972.12", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.12.tgz", + "integrity": "sha512-NxB2dS4/mV3380hNkC72TkhMaLLjWGGBeTAEucqlJptVVovTbNmQWZLwaMC74ICo9NZHmFiBVVTHzDfAh/3y6Q==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.6", - "@smithy/types": "^4.13.1", + "@aws-sdk/core": "^3.974.12", "tslib": "^2.6.2" }, "engines": { @@ -12252,15 +11104,12 @@ } }, "node_modules/@aws-sdk/client-cloudfront/node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.9.tgz", - "integrity": "sha512-/Wt5+CT8dpTFQxEJ9iGy/UGrXr7p2wlIOEHvIr/YcHYByzoLjrqkYqXdJjd9UIgWjv7eqV2HnFJen93UTuwfTQ==", + "version": "3.972.14", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.14.tgz", + "integrity": "sha512-bqL+upATpOJ/7px4IVfMVxcM6Lyt9uRizmEx3mNg4N6+IQlnOaYXXOJ4TNX6P0mKPPW0lwn9ZW8QEhXwQuCH9A==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.6", - "@aws/lambda-invoke-store": "^0.2.2", - "@smithy/protocol-http": "^5.3.12", - "@smithy/types": "^4.13.1", + "@aws-sdk/core": "^3.974.12", "tslib": "^2.6.2" }, "engines": { @@ -12268,15 +11117,12 @@ } }, "node_modules/@aws-sdk/client-cloudfront/node_modules/@aws-sdk/region-config-resolver": { - "version": "3.972.10", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.10.tgz", - "integrity": "sha512-1dq9ToC6e070QvnVhhbAs3bb5r6cQ10gTVc6cyRV5uvQe7P138TV2uG2i6+Yok4bAkVAcx5AqkTEBUvWEtBlsQ==", + "version": "3.972.16", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.16.tgz", + "integrity": "sha512-/YaivCvKUkEeMN9VTKBSvBn5w/4osAM1YboM58DKaLF/vqFGf/FdJCLmppqiPPJWZaXcASqByVjc3evE7KHKdA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.6", - "@smithy/config-resolver": "^4.4.13", - "@smithy/node-config-provider": "^4.3.12", - "@smithy/types": "^4.13.1", + "@aws-sdk/core": "^3.974.12", "tslib": "^2.6.2" }, "engines": { @@ -12284,12 +11130,12 @@ } }, "node_modules/@aws-sdk/client-cloudfront/node_modules/@aws-sdk/types": { - "version": "3.973.6", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.6.tgz", - "integrity": "sha512-Atfcy4E++beKtwJHiDln2Nby8W/mam64opFPTiHEqgsthqeydFS1pY+OUlN1ouNOmf8ArPU/6cDS65anOP3KQw==", + "version": "3.973.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.8.tgz", + "integrity": "sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.13.1", + "@smithy/types": "^4.14.1", "tslib": "^2.6.2" }, "engines": { @@ -12297,15 +11143,13 @@ } }, "node_modules/@aws-sdk/client-cloudfront/node_modules/@aws-sdk/util-endpoints": { - "version": "3.996.5", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.5.tgz", - "integrity": "sha512-Uh93L5sXFNbyR5sEPMzUU8tJ++Ku97EY4udmC01nB8Zu+xfBPwpIwJ6F7snqQeq8h2pf+8SGN5/NoytfKgYPIw==", + "version": "3.996.11", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.11.tgz", + "integrity": "sha512-BUMJ6VoL54r6Udj/wKy8uKRIndL04rGbaS/wTIV0dM1ewxSrR8yARBHdvZKQsK55ZSW2JrmAPk3KP15kBDxJMw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.6", - "@smithy/types": "^4.13.1", - "@smithy/url-parser": "^4.2.12", - "@smithy/util-endpoints": "^3.3.3", + "@aws-sdk/core": "^3.974.12", + "@smithy/core": "^3.24.2", "tslib": "^2.6.2" }, "engines": { @@ -12313,14 +11157,12 @@ } }, "node_modules/@aws-sdk/client-cloudfront/node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.8.tgz", - "integrity": "sha512-B3KGXJviV2u6Cdw2SDY2aDhoJkVfY/Q/Trwk2CMSkikE1Oi6gRzxhvhIfiRpHfmIsAhV4EA54TVEX8K6CbHbkA==", + "version": "3.972.13", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.13.tgz", + "integrity": "sha512-wfk9ZdVwh187gdGXB1EyAoprwjSMt/bSfVtva+OaZx+LyNdKD7smlZf611yMd42UpfQ9vaS8NOftjSajgpdd+w==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.6", - "@smithy/types": "^4.13.1", - "bowser": "^2.11.0", + "@aws-sdk/core": "^3.974.12", "tslib": "^2.6.2" } }, @@ -14030,24 +12872,18 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.974.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.8.tgz", - "integrity": "sha512-njR2qoG6ZuB0kvAS2FyICsFZJ6gmCcf2X/7JcD14sUvGDm26wiZ5BrA6LOiUxKFEF+IVe7kdroxyE00YlkiYsw==", + "version": "3.974.12", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.12.tgz", + "integrity": "sha512-qrqgioqYFjwR6LatVNS1L2Vk++EwRIxqSQXPKNv5Ofux2D8UNgqMQ1znnMyEImXquVPTtbf71fc128pvmU6y9A==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.8", - "@aws-sdk/xml-builder": "^3.972.22", - "@smithy/core": "^3.23.17", - "@smithy/node-config-provider": "^4.3.14", - "@smithy/property-provider": "^4.2.14", - "@smithy/protocol-http": "^5.3.14", - "@smithy/signature-v4": "^5.3.14", - "@smithy/smithy-client": "^4.12.13", + "@aws-sdk/xml-builder": "^3.972.24", + "@aws/lambda-invoke-store": "^0.2.2", + "@smithy/core": "^3.24.2", + "@smithy/signature-v4": "^5.4.2", "@smithy/types": "^4.14.1", - "@smithy/util-base64": "^4.3.2", - "@smithy/util-middleware": "^4.2.14", - "@smithy/util-retry": "^4.3.6", - "@smithy/util-utf8": "^4.2.2", + "bowser": "^2.11.0", "tslib": "^2.6.2" }, "engines": { @@ -14068,14 +12904,14 @@ } }, "node_modules/@aws-sdk/core/node_modules/@aws-sdk/xml-builder": { - "version": "3.972.22", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.22.tgz", - "integrity": "sha512-PMYKKtJd70IsSG0yHrdAbxBr+ZWBKLvzFZfD3/urxgf6hXVMzuU5M+3MJ5G67RpOmLBu1fAUN65SbWuKUCOlAA==", + "version": "3.972.24", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.24.tgz", + "integrity": "sha512-V8z5YcDPfsvzrBlj0xR1vhRtocblhYbqdreCJB/voGd4Sr5zjNAeWxexbnqVtskTJe0vFb5KMqbSL++ePl+zRw==", "license": "Apache-2.0", "dependencies": { "@nodable/entities": "2.1.0", "@smithy/types": "^4.14.1", - "fast-xml-parser": "5.7.2", + "fast-xml-parser": "5.7.3", "tslib": "^2.6.2" }, "engines": { @@ -14083,9 +12919,9 @@ } }, "node_modules/@aws-sdk/core/node_modules/fast-xml-parser": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.2.tgz", - "integrity": "sha512-P7oW7tLbYnhOLQk/Gv7cZgzgMPP/XN03K02/Jy6Y/NHzyIAIpxuZIM/YqAkfiXFPxA2CTm7NtCijK9EDu09u2w==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.3.tgz", + "integrity": "sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg==", "funding": [ { "type": "github", @@ -14095,7 +12931,7 @@ "license": "MIT", "dependencies": { "@nodable/entities": "^2.1.0", - "fast-xml-builder": "^1.1.5", + "fast-xml-builder": "^1.1.7", "path-expression-matcher": "^1.5.0", "strnum": "^2.2.3" }, @@ -18250,20 +17086,13 @@ } }, "node_modules/@smithy/core": { - "version": "3.23.17", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.17.tgz", - "integrity": "sha512-x7BlLbUFL8NWCGjMF9C+1N5cVCxcPa7g6Tv9B4A2luWx3be3oU8hQ96wIwxe/s7OhIzvoJH73HAUSg5JXVlEtQ==", + "version": "3.24.3", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.24.3.tgz", + "integrity": "sha512-Ep/7tPamGY8mgESE3LyLKtxJyy6U52WWAqr/3wial47Sj4u3PiIF73AOGI27UyLy9duTkhZbgzodOfLV4TduZg==", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.14", - "@smithy/types": "^4.14.1", - "@smithy/url-parser": "^4.2.14", - "@smithy/util-base64": "^4.3.2", - "@smithy/util-body-length-browser": "^4.2.2", - "@smithy/util-middleware": "^4.2.14", - "@smithy/util-stream": "^4.5.25", - "@smithy/util-utf8": "^4.2.2", - "@smithy/uuid": "^1.1.2", + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^4.14.2", "tslib": "^2.6.2" }, "engines": { @@ -18646,18 +17475,13 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "5.3.14", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.14.tgz", - "integrity": "sha512-1D9Y/nmlVjCeSivCbhZ7hgEpmHyY1h0GvpSZt3l0xcD9JjmjVC1CHOozS6+Gh+/ldMH8JuJ6cujObQqfayAVFA==", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.4.3.tgz", + "integrity": "sha512-53+75QuPl6DL+ct6vVEB51FDO5oulXr20TPV46VvJZg76lIlXNWfxi8j+G2V/t0I2qxCBOa3vX/8bmjrpFVo9g==", "license": "Apache-2.0", "dependencies": { - "@smithy/is-array-buffer": "^4.2.2", - "@smithy/protocol-http": "^5.3.14", - "@smithy/types": "^4.14.1", - "@smithy/util-hex-encoding": "^4.2.2", - "@smithy/util-middleware": "^4.2.14", - "@smithy/util-uri-escape": "^4.2.2", - "@smithy/util-utf8": "^4.2.2", + "@smithy/core": "^3.24.3", + "@smithy/types": "^4.14.2", "tslib": "^2.6.2" }, "engines": { @@ -18683,9 +17507,9 @@ } }, "node_modules/@smithy/types": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.14.1.tgz", - "integrity": "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg==", + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.14.2.tgz", + "integrity": "sha512-P+otAxbV4CqBybp7EkcJCrig63yE2E7PuNVOmilVMRcx/O+QDzGULTrKsq4DV13gSfak9ObPrWaHl/9bL5YcWw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -19210,7 +18034,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" @@ -19701,7 +18524,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.1.tgz", "integrity": "sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==", - "dev": true, "license": "MIT" }, "node_modules/async-retry": { @@ -20087,7 +18909,6 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, "funding": [ { "type": "github", @@ -20639,7 +19460,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/clean-git-ref/-/clean-git-ref-2.0.1.tgz", "integrity": "sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==", - "dev": true, "license": "Apache-2.0" }, "node_modules/clean-stack": { @@ -21391,7 +20211,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true, "license": "Apache-2.0", "bin": { "crc32": "bin/crc32.njs" @@ -21709,7 +20528,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, "license": "MIT", "dependencies": { "mimic-response": "^3.1.0" @@ -21866,7 +20684,6 @@ "version": "0.0.3", "resolved": "https://registry.npmjs.org/diff3/-/diff3-0.0.3.tgz", "integrity": "sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g==", - "dev": true, "license": "MIT" }, "node_modules/dingbat-to-unicode": { @@ -22971,7 +21788,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -22987,7 +21803,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.8.x" @@ -23171,9 +21986,9 @@ "license": "BSD-3-Clause" }, "node_modules/fast-xml-builder": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.5.tgz", - "integrity": "sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz", + "integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==", "funding": [ { "type": "github", @@ -23182,7 +21997,8 @@ ], "license": "MIT", "dependencies": { - "path-expression-matcher": "^1.1.3" + "path-expression-matcher": "^1.5.0", + "xml-naming": "^0.1.0" } }, "node_modules/fast-xml-parser": { @@ -24776,7 +23592,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, "funding": [ { "type": "github", @@ -24797,7 +23612,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 4" @@ -25417,7 +24231,6 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", - "dev": true, "license": "MIT", "dependencies": { "which-typed-array": "^1.1.16" @@ -25509,10 +24322,9 @@ } }, "node_modules/isomorphic-git": { - "version": "1.37.6", - "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.37.6.tgz", - "integrity": "sha512-qr1NFCPsVTZ6YGqTXw0CzamnsHyH9QQ1OTEfeXIweSljRUMzuHFCJdUn0wc6OcjtTDns6knxjPb7N6LmJeftOA==", - "dev": true, + "version": "1.38.1", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.38.1.tgz", + "integrity": "sha512-Vd2u5qDLa04fA/h5nUMU5UuffPXqg+3D3bJIV3n7Sno2qS3XMinUXRvNHrGPVy2kkC1ad5SPCC3WcpXjn0L9oQ==", "license": "MIT", "dependencies": { "async-lock": "^1.4.1", @@ -25628,7 +24440,6 @@ "version": "6.2.3", "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz", "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" @@ -27568,7 +26379,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -27609,7 +26419,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/minimisted/-/minimisted-2.0.1.tgz", "integrity": "sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA==", - "dev": true, "license": "MIT", "dependencies": { "minimist": "^1.2.5" @@ -31440,7 +30249,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -31680,7 +30488,6 @@ "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6.0" @@ -32080,7 +30887,6 @@ "version": "4.7.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", - "dev": true, "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -33095,7 +31901,6 @@ "version": "2.4.12", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", - "dev": true, "license": "(MIT AND BSD-3-Clause)", "dependencies": { "inherits": "^2.0.4", @@ -33393,7 +32198,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true, "funding": [ { "type": "github", @@ -33414,7 +32218,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "dev": true, "funding": [ { "type": "github", @@ -33820,7 +32623,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -34652,7 +33454,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", - "dev": true, "license": "MIT", "dependencies": { "isarray": "^2.0.5", @@ -34882,7 +33683,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -35863,6 +34663,21 @@ "xml-js": "bin/cli.js" } }, + "node_modules/xml-naming": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz", + "integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/xmlbuilder": { "version": "10.1.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-10.1.1.tgz", From d0f570354b6cc328d3d59beb70a31d20e29f7302 Mon Sep 17 00:00:00 2001 From: ppatwal Date: Tue, 19 May 2026 05:47:14 +0530 Subject: [PATCH 8/9] test(SITES-43695): replace implementation spy with behavioral assertion; drop redundant happy path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'falls back' test was asserting getFirstEnrollment was called (spy) instead of asserting the response returned the enrolled site (behavior). Also removed the resolveOrgDefaultSite happy-path unit test — it duplicated the wiring already proven by the 'uses config.defaults site when organizationId is provided' test. Co-Authored-By: Claude Sonnet 4.6 --- test/controllers/sites.test.js | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/test/controllers/sites.test.js b/test/controllers/sites.test.js index 0f1e3686b..851f6c10a 100644 --- a/test/controllers/sites.test.js +++ b/test/controllers/sites.test.js @@ -5421,7 +5421,7 @@ describe('Sites Controller', () => { expect(mockTierClientStub.getFirstEnrollment).to.not.have.been.called; }); - it('falls back to getFirstEnrollment when config.defaults returns null', async () => { + it('falls back to first-enrolled site when config.defaults has no entry for the product', async () => { sandbox.stub(testOrganizations[0], 'getConfig').returns(Config({})); context.data = { organizationId: testOrganizations[0].getId() }; mockDataAccess.Organization.findById.resolves(testOrganizations[0]); @@ -5430,9 +5430,11 @@ describe('Sites Controller', () => { site: testSites[0], }); - await sitesController.resolveSite(context); + const response = await sitesController.resolveSite(context); - expect(mockTierClientStub.getFirstEnrollment).to.have.been.called; + expect(response.status).to.equal(200); + const body = await response.json(); + expect(body.data.site.id).to.equal(SITE_IDS[0]); }); }); @@ -5452,13 +5454,6 @@ describe('Sites Controller', () => { }); }); - it('returns site data when the configured default site is valid and enrolled', async () => { - const result = await resolveOrgDefaultSite(org, productCode, context, mockCtx); - - expect(result).to.not.be.null; - expect(result.site.id).to.equal(SITE_IDS[0]); - }); - it('returns null when org has no default configured for the product', async () => { org.getConfig.returns({ defaults: {} }); From 8a0fe2d8ec474672147e1fe907a4f8373a379871 Mon Sep 17 00:00:00 2001 From: ppatwal Date: Tue, 19 May 2026 05:58:34 +0530 Subject: [PATCH 9/9] test(SITES-43695): strengthen setConfig calledWith assertion; add PRE_ONBOARD tier test Co-Authored-By: Claude Sonnet 4.6 --- test/controllers/organizations.test.js | 3 ++- test/controllers/sites.test.js | 13 ++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/test/controllers/organizations.test.js b/test/controllers/organizations.test.js index 957e417f2..fc6398658 100755 --- a/test/controllers/organizations.test.js +++ b/test/controllers/organizations.test.js @@ -499,7 +499,8 @@ describe('Organizations Controller', () => { ...context, }); - expect(organizations[0].setConfig).to.have.been.calledOnce; + const expectedConfig = { defaults: { ASO: { siteId } } }; + expect(organizations[0].setConfig).to.have.been.calledOnceWith(expectedConfig); expect(organizations[0].save).to.have.been.calledOnce; expect(response.status).to.equal(200); }); diff --git a/test/controllers/sites.test.js b/test/controllers/sites.test.js index 851f6c10a..0eb332875 100644 --- a/test/controllers/sites.test.js +++ b/test/controllers/sites.test.js @@ -5481,7 +5481,7 @@ describe('Sites Controller', () => { expect(mockCtx.log.warn).to.have.been.called; }); - it('returns null when the configured site is not actively enrolled', async () => { + it('returns null when the configured site has no active enrollments', async () => { mockTierClientStub.getAllEnrollment.resolves({ entitlement: { getTier: () => 'FREE_TRIAL' }, enrollments: [], @@ -5492,6 +5492,17 @@ describe('Sites Controller', () => { expect(result).to.be.null; }); + it('returns null when the configured site is on a non-customer-visible tier', async () => { + mockTierClientStub.getAllEnrollment.resolves({ + entitlement: { getTier: () => 'PRE_ONBOARD' }, + enrollments: [{ getId: () => 'enrollment-1' }], + }); + + const result = await resolveOrgDefaultSite(org, productCode, context, mockCtx); + + expect(result).to.be.null; + }); + it('returns null gracefully when TierClient throws', async () => { TierClient.createForSite.throws(new Error('tier service unavailable'));