Files
simstudioai--sim/apps/sim/ee/workspace-forking/lib/promote/sync-blockers.ts
T
wehub-resource-sync d25d482dc2
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:20:55 +08:00

64 lines
2.7 KiB
TypeScript

import {
type ForkClearedRef,
type ForkSyncBlocker,
type ForkSyncBlockerReason,
forkCopyableKindSchema,
} from '@/lib/api/contracts/workspace-fork'
/**
* Pure sync-blocker taxonomy, shared by the server gate (promote) and the modal's blocker
* rendering. A sync is allowed only when ZERO references would clear in any synced target
* workflow; every would-clear entry of cause `reference` or `workflow` is a blocker with an
* actionable reason. `dependent`-cause entries are NOT blockers - the dependent/reconfigure
* flow owns them (its own required gating), and a credential-anchored dependent clears on any
* parent remap, so blocking on it would be unresolvable.
*/
/** Copyable kinds derived from the wire contract, so the reason split can never drift. */
const COPYABLE_BLOCKER_KINDS: ReadonlySet<string> = new Set(forkCopyableKindSchema.options)
/**
* The blocker reason for a would-clear entry, or null when the entry does not block
* (`dependent` cause, and - defensively - any kind the cleared-ref collector excludes):
* - `workflow` cause -> `workflow-missing` (deploy the referenced workflow in the source, or
* remove the reference).
* - `reference` + source deleted -> `source-deleted` (map the dead id to a live target
* resource, or fix/archive the source workflow).
* - `reference` + copyable kind (incl. external MCP servers) -> `unmapped-copyable` (map it
* or select it for copy).
*/
export function forkSyncBlockerReasonFor(ref: ForkClearedRef): ForkSyncBlockerReason | null {
if (ref.cause === 'workflow') return 'workflow-missing'
if (ref.cause !== 'reference') return null
if (ref.sourceDeleted) return 'source-deleted'
if (COPYABLE_BLOCKER_KINDS.has(ref.kind)) return 'unmapped-copyable'
// Credential / env-var / knowledge-document never reach the cleared list (excluded by the
// collector; the first two gate via the kind-level required gate, documents follow their KB).
return null
}
/** The would-clear entries that BLOCK the sync, paired with their reason. */
export function selectForkSyncBlockingRefs(
clearedRefs: ForkClearedRef[]
): Array<{ ref: ForkClearedRef; reason: ForkSyncBlockerReason }> {
return clearedRefs.flatMap((ref) => {
const reason = forkSyncBlockerReasonFor(ref)
return reason ? [{ ref, reason }] : []
})
}
/** Map blocking entries to the wire {@link ForkSyncBlocker} shape of the promote gate error. */
export function toForkSyncBlockers(
blocking: Array<{ ref: ForkClearedRef; reason: ForkSyncBlockerReason }>
): ForkSyncBlocker[] {
return blocking.map(({ ref, reason }) => ({
workflowName: ref.workflowName,
blockLabel: ref.blockLabel,
fieldLabel: ref.fieldLabel,
kind: ref.kind,
sourceId: ref.sourceId,
sourceLabel: ref.sourceLabel,
reason,
}))
}