MCPcopy Index your code
hub / github.com/simstudioai/sim / duplicateWorkflow

Function duplicateWorkflow

apps/sim/lib/workflows/persistence/duplicate.ts:100–521  ·  view source on GitHub ↗
(
  options: DuplicateWorkflowOptions
)

Source from the content-addressed store, hash-verified

98 * This is a shared helper used by both the workflow duplicate API and folder duplicate API
99 */
100export async function duplicateWorkflow(
101 options: DuplicateWorkflowOptions
102): Promise<DuplicateWorkflowResult> {
103 const {
104 sourceWorkflowId,
105 userId,
106 name,
107 description,
108 workspaceId,
109 folderId,
110 requestId = 'unknown',
111 newWorkflowId: clientNewWorkflowId,
112 tx: providedTx,
113 workflowIdMap,
114 } = options
115
116 const newWorkflowId = clientNewWorkflowId || workflowIdMap?.get(sourceWorkflowId) || generateId()
117 const now = new Date()
118
119 // Authorization runs before the transaction opens so its global-pool
120 // queries never execute while a pooled connection is held. Callers that
121 // pass `tx` authorize the workspace themselves (see DuplicateWorkflowOptions).
122 if (!providedTx) {
123 const sourceAuthorization = await authorizeWorkflowByWorkspacePermission({
124 workflowId: sourceWorkflowId,
125 userId,
126 action: 'read',
127 })
128 if (!sourceAuthorization.allowed || !sourceAuthorization.workflow) {
129 throw new Error('Source workflow not found or access denied')
130 }
131
132 const sourceWorkspaceId = sourceAuthorization.workflow.workspaceId
133 if (!sourceWorkspaceId) {
134 throw new Error(
135 'This workflow is not attached to a workspace. Personal workflows are deprecated and cannot be duplicated.'
136 )
137 }
138
139 const targetWorkspaceId = workspaceId || sourceWorkspaceId
140 if (targetWorkspaceId !== sourceWorkspaceId) {
141 throw new Error('Cross-workspace workflow duplication is not supported')
142 }
143
144 // The target workspace equals the source workspace, so the permission
145 // resolved by the authorization above is the target permission.
146 if (
147 sourceAuthorization.workspacePermission !== 'admin' &&
148 sourceAuthorization.workspacePermission !== 'write'
149 ) {
150 throw new Error('Write or admin access required for target workspace')
151 }
152 }
153
154 const duplicateWithinTransaction = async (tx: DbOrTx) => {
155 // First verify the source workflow exists
156 const sourceWorkflowRow = await tx
157 .select()

Callers 3

duplicate.test.tsFile · 0.90
route.tsFile · 0.90

Calls 4

generateIdFunction · 0.90
getMethod · 0.65

Tested by

no test coverage detected