From 7c270bc7722c93c9917f011291e5b7ca187fb2cf Mon Sep 17 00:00:00 2001 From: Aparna Goyal Date: Tue, 22 Sep 2026 03:08:40 +0530 Subject: [PATCH 1/2] feat: deploy dataspace-scoped components with their retrieveWith closure --- src/utils/deploy.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/utils/deploy.ts b/src/utils/deploy.ts index 5c5d8134..4485986f 100644 --- a/src/utils/deploy.ts +++ b/src/utils/deploy.ts @@ -24,6 +24,7 @@ import { ComponentStatus, DeployResult, DestructiveChangesType, + expandDataspaceScopedComponentSet, FileResponseSuccess, MetadataApiDeploy, MetadataApiDeployOptions, @@ -119,6 +120,25 @@ export async function buildComponentSet(opts: Partial, stl?: Sour }); } +/** True when the deploy includes at least one Data Cloud dataspace-scoped component. */ +const hasDataspaceScopedComponents = (requested: ComponentSet): boolean => + [...requested.getSourceComponents()].some((c) => c.type.strategies?.adapter === 'dataspaceScoped'); + +/** + * A dataspace-scoped component's sidecar lists the peers it has to be deployed alongside, under + * `retrieveWith`. So when someone deploys one of these, we also pull in those peers (and their peers, + * and so on) — but nothing else from the project. To find them we resolve the whole project once, + * then hand back the requested set plus that closure. + */ +async function expandDataspaceScopedClosure( + requested: ComponentSet, + registry?: RegistryAccess +): Promise { + // Resolve the whole project so we can look up the retrieveWith peers by their sidecar componentName. + const full = await ComponentSetBuilder.build({ sourcepath: await getPackageDirs() }); + return expandDataspaceScopedComponentSet(full, requested, registry); +} + export async function executeDeploy( opts: Partial, project?: SfProject, @@ -166,6 +186,11 @@ export async function executeDeploy( registry = stl.registry; componentSet = await buildComponentSet(opts, stl); + // Dataspace-scoped components need their retrieveWith peers in the same deploy, so pull those in. + // Every other deploy leaves the component set untouched. + if (hasDataspaceScopedComponents(componentSet)) { + componentSet = await expandDataspaceScopedClosure(componentSet, registry); + } if (componentSet.size === 0) { if (opts['source-dir'] ?? opts.manifest ?? opts.metadata ?? throwOnEmpty) { // the user specified something to deploy, but there isn't anything From 9a6836b8905a46033cfc88d5721019158887b897 Mon Sep 17 00:00:00 2001 From: Aparna Goyal Date: Wed, 23 Sep 2026 02:01:43 +0530 Subject: [PATCH 2/2] refactor: follow SDR rename to d360 strategy and expandD360ComponentSet --- src/utils/deploy.ts | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/utils/deploy.ts b/src/utils/deploy.ts index 4485986f..76d3792c 100644 --- a/src/utils/deploy.ts +++ b/src/utils/deploy.ts @@ -24,7 +24,7 @@ import { ComponentStatus, DeployResult, DestructiveChangesType, - expandDataspaceScopedComponentSet, + expandD360ComponentSet, FileResponseSuccess, MetadataApiDeploy, MetadataApiDeployOptions, @@ -121,8 +121,8 @@ export async function buildComponentSet(opts: Partial, stl?: Sour } /** True when the deploy includes at least one Data Cloud dataspace-scoped component. */ -const hasDataspaceScopedComponents = (requested: ComponentSet): boolean => - [...requested.getSourceComponents()].some((c) => c.type.strategies?.adapter === 'dataspaceScoped'); +const hasD360Components = (requested: ComponentSet): boolean => + [...requested.getSourceComponents()].some((c) => c.type.strategies?.adapter === 'd360'); /** * A dataspace-scoped component's sidecar lists the peers it has to be deployed alongside, under @@ -130,13 +130,10 @@ const hasDataspaceScopedComponents = (requested: ComponentSet): boolean => * and so on) — but nothing else from the project. To find them we resolve the whole project once, * then hand back the requested set plus that closure. */ -async function expandDataspaceScopedClosure( - requested: ComponentSet, - registry?: RegistryAccess -): Promise { +async function expandD360Closure(requested: ComponentSet, registry?: RegistryAccess): Promise { // Resolve the whole project so we can look up the retrieveWith peers by their sidecar componentName. const full = await ComponentSetBuilder.build({ sourcepath: await getPackageDirs() }); - return expandDataspaceScopedComponentSet(full, requested, registry); + return expandD360ComponentSet(full, requested, registry); } export async function executeDeploy( @@ -188,8 +185,8 @@ export async function executeDeploy( componentSet = await buildComponentSet(opts, stl); // Dataspace-scoped components need their retrieveWith peers in the same deploy, so pull those in. // Every other deploy leaves the component set untouched. - if (hasDataspaceScopedComponents(componentSet)) { - componentSet = await expandDataspaceScopedClosure(componentSet, registry); + if (hasD360Components(componentSet)) { + componentSet = await expandD360Closure(componentSet, registry); } if (componentSet.size === 0) { if (opts['source-dir'] ?? opts.manifest ?? opts.metadata ?? throwOnEmpty) {