powerautomate-mcp 0.7.9 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +219 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1134,6 +1134,28 @@ async function createAuthProviderFromConfig(clientId, tenantId, cachePath, silen
|
|
|
1134
1134
|
};
|
|
1135
1135
|
return createWamAuthProvider(config, silentOnly);
|
|
1136
1136
|
}
|
|
1137
|
+
|
|
1138
|
+
// src/utils/jwt-claims.ts
|
|
1139
|
+
function decodeJwtClaims(token) {
|
|
1140
|
+
try {
|
|
1141
|
+
const parts = token.split(".");
|
|
1142
|
+
if (parts.length < 2 || !parts[1]) return {};
|
|
1143
|
+
const padded = parts[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
1144
|
+
const padding = padded.length % 4 === 0 ? "" : "=".repeat(4 - padded.length % 4);
|
|
1145
|
+
const json = Buffer.from(padded + padding, "base64").toString("utf-8");
|
|
1146
|
+
const claims = JSON.parse(json);
|
|
1147
|
+
return claims && typeof claims === "object" ? claims : {};
|
|
1148
|
+
} catch {
|
|
1149
|
+
return {};
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
function getOidFromToken(token) {
|
|
1153
|
+
const claims = decodeJwtClaims(token);
|
|
1154
|
+
const oid = claims.oid;
|
|
1155
|
+
return typeof oid === "string" && oid.length > 0 ? oid : void 0;
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
// src/api/flow-management.ts
|
|
1137
1159
|
var apiLogger = createChildLogger({ module: "flow-api" });
|
|
1138
1160
|
var FlowManagementApi = class {
|
|
1139
1161
|
authProvider;
|
|
@@ -1142,6 +1164,18 @@ var FlowManagementApi = class {
|
|
|
1142
1164
|
this.authProvider = config.authProvider;
|
|
1143
1165
|
this.defaultEnvironmentId = config.defaultEnvironmentId;
|
|
1144
1166
|
}
|
|
1167
|
+
/**
|
|
1168
|
+
* Return the current user's Azure AD object ID derived from the access token.
|
|
1169
|
+
* Used for client-side ownership filtering. Returns undefined if extraction fails.
|
|
1170
|
+
*/
|
|
1171
|
+
async getCurrentUserOid() {
|
|
1172
|
+
try {
|
|
1173
|
+
const token = await this.authProvider.getToken();
|
|
1174
|
+
return getOidFromToken(token);
|
|
1175
|
+
} catch {
|
|
1176
|
+
return void 0;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1145
1179
|
/**
|
|
1146
1180
|
* Get authorization header with bearer token
|
|
1147
1181
|
*/
|
|
@@ -4212,11 +4246,15 @@ var listFlowsInputSchema = z.object({
|
|
|
4212
4246
|
environment: z.string().optional().describe("Environment name or GUID. Uses default if omitted."),
|
|
4213
4247
|
search: z.string().optional().describe("Search flows by display name (case-insensitive substring match). Applied client-side after fetching."),
|
|
4214
4248
|
filter: z.string().optional().describe(`OData filter expression (e.g., "properties/state eq 'Started'")`),
|
|
4215
|
-
top: z.number().min(1).max(250).optional().describe("Maximum number of results to return (default 50, max 250)")
|
|
4249
|
+
top: z.number().min(1).max(250).optional().describe("Maximum number of results to return (default 50, max 250)"),
|
|
4250
|
+
scope: z.enum(["owned", "shared", "all"]).optional().default("all").describe(
|
|
4251
|
+
"Filter by ownership: 'owned' = only flows you created, 'shared' = only flows shared with you, 'all' = both (default)."
|
|
4252
|
+
),
|
|
4253
|
+
includeOwner: z.boolean().optional().default(true).describe("Include owner/creator name in the output (default true).")
|
|
4216
4254
|
});
|
|
4217
4255
|
var listFlowsTool = {
|
|
4218
4256
|
name: "list_flows",
|
|
4219
|
-
description: "List Power Automate flows in an environment. Returns flow names, IDs, state (Started/Stopped),
|
|
4257
|
+
description: "List Power Automate flows in an environment. Returns flow names, IDs, state (Started/Stopped), last modified dates, and owners. Use scope='shared' to find flows shared with you, scope='owned' for your flows only. Use this to discover what flows exist before getting details or making changes.",
|
|
4220
4258
|
inputSchema: {
|
|
4221
4259
|
type: "object",
|
|
4222
4260
|
properties: {
|
|
@@ -4237,6 +4275,17 @@ var listFlowsTool = {
|
|
|
4237
4275
|
description: "Maximum number of results to return (default 50, max 250)",
|
|
4238
4276
|
minimum: 1,
|
|
4239
4277
|
maximum: 250
|
|
4278
|
+
},
|
|
4279
|
+
scope: {
|
|
4280
|
+
type: "string",
|
|
4281
|
+
enum: ["owned", "shared", "all"],
|
|
4282
|
+
description: "Filter by ownership: 'owned' = only flows you created, 'shared' = only flows shared with you, 'all' = both (default).",
|
|
4283
|
+
default: "all"
|
|
4284
|
+
},
|
|
4285
|
+
includeOwner: {
|
|
4286
|
+
type: "boolean",
|
|
4287
|
+
description: "Include owner/creator name in the output (default true).",
|
|
4288
|
+
default: true
|
|
4240
4289
|
}
|
|
4241
4290
|
}
|
|
4242
4291
|
}
|
|
@@ -4262,14 +4311,39 @@ async function handleListFlows(api, input) {
|
|
|
4262
4311
|
const needle = parsed.search.toLowerCase();
|
|
4263
4312
|
flows = flows.filter((f) => f.properties.displayName.toLowerCase().includes(needle));
|
|
4264
4313
|
}
|
|
4314
|
+
let currentUserOid;
|
|
4315
|
+
if (parsed.scope !== "all" || parsed.includeOwner) {
|
|
4316
|
+
currentUserOid = await api.getCurrentUserOid();
|
|
4317
|
+
if (parsed.scope !== "all" && !currentUserOid) {
|
|
4318
|
+
logger.warn("list_flows: could not derive current user OID; scope filter will not apply");
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4321
|
+
if (parsed.scope !== "all" && currentUserOid) {
|
|
4322
|
+
flows = flows.filter((f) => {
|
|
4323
|
+
const creatorId = f.properties.creator?.id;
|
|
4324
|
+
if (!creatorId) return false;
|
|
4325
|
+
const isOwned = creatorId === currentUserOid;
|
|
4326
|
+
return parsed.scope === "owned" ? isOwned : !isOwned;
|
|
4327
|
+
});
|
|
4328
|
+
}
|
|
4265
4329
|
if (flows.length === 0) {
|
|
4266
|
-
return "No flows found";
|
|
4330
|
+
return parsed.scope === "shared" ? "No flows shared with you in this environment." : parsed.scope === "owned" ? "No flows you own in this environment." : "No flows found";
|
|
4267
4331
|
}
|
|
4268
|
-
const
|
|
4332
|
+
const scopeLabel = parsed.scope === "owned" ? "Owned" : parsed.scope === "shared" ? "Shared with you" : "Flows";
|
|
4333
|
+
const lines = [`${scopeLabel} (${flows.length}):`];
|
|
4269
4334
|
for (const flow of flows) {
|
|
4270
4335
|
const state = flow.properties.state === "Started" ? "\u25B6" : "\u23F9";
|
|
4271
4336
|
const modified = new Date(flow.properties.lastModifiedTime).toLocaleDateString();
|
|
4272
|
-
|
|
4337
|
+
let line = ` ${state} ${flow.properties.displayName} (${flow.name}) - ${modified}`;
|
|
4338
|
+
if (parsed.includeOwner) {
|
|
4339
|
+
const creator = flow.properties.creator;
|
|
4340
|
+
const ownerName = creator?.displayName ?? creator?.email;
|
|
4341
|
+
const isOwnedTag = currentUserOid && creator?.id === currentUserOid ? " [owned]" : creator ? " [shared]" : "";
|
|
4342
|
+
if (ownerName) {
|
|
4343
|
+
line += ` \u2014 ${ownerName}${isOwnedTag}`;
|
|
4344
|
+
}
|
|
4345
|
+
}
|
|
4346
|
+
lines.push(line);
|
|
4273
4347
|
}
|
|
4274
4348
|
if (result.nextLink) {
|
|
4275
4349
|
lines.push(`
|
|
@@ -4280,11 +4354,14 @@ async function handleListFlows(api, input) {
|
|
|
4280
4354
|
var getFlowInputSchema = z.object({
|
|
4281
4355
|
flowId: z.string().describe("The flow ID (GUID) to retrieve"),
|
|
4282
4356
|
environment: z.string().optional().describe("Environment name or GUID. Uses default if omitted."),
|
|
4283
|
-
includeDefinition: z.boolean().optional().default(true).describe("Include the full flow definition JSON (default true)")
|
|
4357
|
+
includeDefinition: z.boolean().optional().default(true).describe("Include the full flow definition JSON (default true)"),
|
|
4358
|
+
format: z.enum(["summary", "json", "both"]).optional().default("summary").describe(
|
|
4359
|
+
"Output format: 'summary' = human-readable top-level overview (default), 'json' = full raw flow.properties.definition with all nested actions, 'both' = summary followed by full JSON. Use 'json' or 'both' to capture nested actions inside Switch/If/Foreach/Scope."
|
|
4360
|
+
)
|
|
4284
4361
|
});
|
|
4285
4362
|
var getFlowTool = {
|
|
4286
4363
|
name: "get_flow",
|
|
4287
|
-
description: "Get the complete definition of a Power Automate flow including triggers, actions,
|
|
4364
|
+
description: "Get the complete definition of a Power Automate flow including triggers, actions, connection references, and description. Use list_flows first to find flow IDs. Set format='json' or format='both' to capture the FULL definition including nested actions inside Switch/If/Foreach/Scope (the default 'summary' format only shows top-level actions).",
|
|
4288
4365
|
inputSchema: {
|
|
4289
4366
|
type: "object",
|
|
4290
4367
|
properties: {
|
|
@@ -4300,6 +4377,12 @@ var getFlowTool = {
|
|
|
4300
4377
|
type: "boolean",
|
|
4301
4378
|
description: "Include the full flow definition JSON (default true)",
|
|
4302
4379
|
default: true
|
|
4380
|
+
},
|
|
4381
|
+
format: {
|
|
4382
|
+
type: "string",
|
|
4383
|
+
enum: ["summary", "json", "both"],
|
|
4384
|
+
description: "Output format: 'summary' = top-level overview (default), 'json' = full raw definition with all nested actions, 'both' = summary plus full JSON.",
|
|
4385
|
+
default: "summary"
|
|
4303
4386
|
}
|
|
4304
4387
|
},
|
|
4305
4388
|
required: ["flowId"]
|
|
@@ -4307,7 +4390,7 @@ var getFlowTool = {
|
|
|
4307
4390
|
};
|
|
4308
4391
|
async function handleGetFlow(api, input) {
|
|
4309
4392
|
const parsed = getFlowInputSchema.parse(input);
|
|
4310
|
-
logger.info({ flowId: parsed.flowId }, "Executing get_flow");
|
|
4393
|
+
logger.info({ flowId: parsed.flowId, format: parsed.format }, "Executing get_flow");
|
|
4311
4394
|
const flow = await api.getFlow(parsed.flowId, parsed.environment);
|
|
4312
4395
|
const triggers = flow.properties.definition.triggers;
|
|
4313
4396
|
const actions = flow.properties.definition.actions;
|
|
@@ -4320,6 +4403,22 @@ async function handleGetFlow(api, input) {
|
|
|
4320
4403
|
tier: ref.tier
|
|
4321
4404
|
})
|
|
4322
4405
|
);
|
|
4406
|
+
const description = flow.properties.description;
|
|
4407
|
+
const creator = flow.properties.creator;
|
|
4408
|
+
if (parsed.format === "json") {
|
|
4409
|
+
const payload = {
|
|
4410
|
+
id: flow.name,
|
|
4411
|
+
displayName: flow.properties.displayName,
|
|
4412
|
+
description,
|
|
4413
|
+
state: flow.properties.state,
|
|
4414
|
+
createdTime: flow.properties.createdTime,
|
|
4415
|
+
lastModifiedTime: flow.properties.lastModifiedTime,
|
|
4416
|
+
creator,
|
|
4417
|
+
connectionReferences: flow.properties.connectionReferences,
|
|
4418
|
+
definition: flow.properties.definition
|
|
4419
|
+
};
|
|
4420
|
+
return JSON.stringify(payload, null, 2);
|
|
4421
|
+
}
|
|
4323
4422
|
const lines = [
|
|
4324
4423
|
`## ${flow.properties.displayName}`,
|
|
4325
4424
|
``,
|
|
@@ -4329,6 +4428,12 @@ async function handleGetFlow(api, input) {
|
|
|
4329
4428
|
`**Actions:** ${Object.keys(actions).length}`,
|
|
4330
4429
|
`**Modified:** ${new Date(flow.properties.lastModifiedTime).toLocaleDateString()}`
|
|
4331
4430
|
];
|
|
4431
|
+
if (description) {
|
|
4432
|
+
lines.push(`**Description:** ${description}`);
|
|
4433
|
+
}
|
|
4434
|
+
if (creator?.displayName || creator?.email) {
|
|
4435
|
+
lines.push(`**Owner:** ${creator.displayName ?? creator.email}${creator.id ? ` (${creator.id})` : ""}`);
|
|
4436
|
+
}
|
|
4332
4437
|
if (connectionRefs.length > 0) {
|
|
4333
4438
|
lines.push(``, `### Connections`);
|
|
4334
4439
|
for (const conn of connectionRefs) {
|
|
@@ -4337,7 +4442,7 @@ async function handleGetFlow(api, input) {
|
|
|
4337
4442
|
}
|
|
4338
4443
|
}
|
|
4339
4444
|
if (parsed.includeDefinition !== false) {
|
|
4340
|
-
lines.push(``, `### Actions`);
|
|
4445
|
+
lines.push(``, `### Actions (top-level)`);
|
|
4341
4446
|
for (const [name, action] of Object.entries(actions)) {
|
|
4342
4447
|
const act = action;
|
|
4343
4448
|
const deps = act.runAfter ? Object.keys(act.runAfter).join(", ") : "trigger";
|
|
@@ -4346,6 +4451,11 @@ async function handleGetFlow(api, input) {
|
|
|
4346
4451
|
lines.push(` inputs: ${JSON.stringify(act.inputs, null, 2).split("\n").join("\n ")}`);
|
|
4347
4452
|
}
|
|
4348
4453
|
}
|
|
4454
|
+
lines.push(``);
|
|
4455
|
+
lines.push(`_Note: Nested actions inside Switch/If/Foreach/Scope are not expanded in this view. Call get_flow with format="json" or format="both" to capture them._`);
|
|
4456
|
+
}
|
|
4457
|
+
if (parsed.format === "both") {
|
|
4458
|
+
lines.push(``, `### Full Definition (JSON)`, "```json", JSON.stringify(flow.properties.definition, null, 2), "```");
|
|
4349
4459
|
}
|
|
4350
4460
|
return lines.join("\n");
|
|
4351
4461
|
}
|
|
@@ -5802,6 +5912,7 @@ var connectionRefSchema = z.object({
|
|
|
5802
5912
|
});
|
|
5803
5913
|
var createFlowInputSchema = z.object({
|
|
5804
5914
|
displayName: z.string().describe("The display name for the new flow"),
|
|
5915
|
+
description: z.string().optional().describe("Optional description for the flow"),
|
|
5805
5916
|
trigger: triggerSchema.describe("The trigger definition"),
|
|
5806
5917
|
triggerName: z.string().optional().default("manual").describe("Name for the trigger (default: 'manual')"),
|
|
5807
5918
|
actions: z.record(actionSchema).describe("Actions in the flow, keyed by action name"),
|
|
@@ -5819,6 +5930,10 @@ var createFlowTool = {
|
|
|
5819
5930
|
type: "string",
|
|
5820
5931
|
description: "The display name for the new flow"
|
|
5821
5932
|
},
|
|
5933
|
+
description: {
|
|
5934
|
+
type: "string",
|
|
5935
|
+
description: "Optional description shown in the Power Automate UI"
|
|
5936
|
+
},
|
|
5822
5937
|
trigger: {
|
|
5823
5938
|
type: "object",
|
|
5824
5939
|
description: "The trigger definition with type, kind, inputs, and optional recurrence",
|
|
@@ -5946,7 +6061,8 @@ async function handleCreateFlow(api, input) {
|
|
|
5946
6061
|
properties: {
|
|
5947
6062
|
displayName: parsed.displayName,
|
|
5948
6063
|
definition,
|
|
5949
|
-
connectionReferences: Object.keys(connectionReferences).length > 0 ? connectionReferences : void 0
|
|
6064
|
+
connectionReferences: Object.keys(connectionReferences).length > 0 ? connectionReferences : void 0,
|
|
6065
|
+
...parsed.description !== void 0 ? { description: parsed.description } : {}
|
|
5950
6066
|
}
|
|
5951
6067
|
};
|
|
5952
6068
|
try {
|
|
@@ -6008,16 +6124,25 @@ var connectionRefSchema2 = z.object({
|
|
|
6008
6124
|
var updateFlowInputSchema = z.object({
|
|
6009
6125
|
flowId: z.string().describe("The flow ID (GUID) to update"),
|
|
6010
6126
|
displayName: z.string().optional().describe("New display name for the flow"),
|
|
6127
|
+
description: z.string().optional().describe("New description (set to empty string to clear)"),
|
|
6011
6128
|
trigger: triggerSchema2.optional().describe("New trigger definition (replaces existing)"),
|
|
6012
6129
|
triggerName: z.string().optional().describe("Name for the trigger"),
|
|
6013
|
-
actions: z.record(actionSchema2).optional().describe(
|
|
6130
|
+
actions: z.record(actionSchema2).optional().describe(
|
|
6131
|
+
"Actions. By default REPLACES all existing actions (you must include every action you want kept). When mergeActions=true, only the named actions are added/updated; everything else stays. Use patchActions for surgical edits to a single nested branch (smallest payload)."
|
|
6132
|
+
),
|
|
6133
|
+
mergeActions: z.boolean().optional().default(false).describe(
|
|
6134
|
+
"When true, deep-merge the provided 'actions' onto the current flow's actions instead of replacing wholesale. Recurses into nested actions/cases/else/foreach. Lets you patch a sub-tree without resending the entire flow."
|
|
6135
|
+
),
|
|
6136
|
+
patchActions: z.record(actionSchema2.nullable()).optional().describe(
|
|
6137
|
+
"Path-based patch map. Keys are slash-separated paths into the action tree, e.g. 'If_Recognized_Form/cases/Default/actions/Compose'. Set value to null to delete a node. Smallest payload \u2014 only the changed branches travel. Applied AFTER mergeActions."
|
|
6138
|
+
),
|
|
6014
6139
|
connectionReferences: z.record(connectionRefSchema2).optional().describe("New connection references (replaces existing)"),
|
|
6015
6140
|
environment: z.string().optional().describe("Environment name or GUID"),
|
|
6016
6141
|
validateBeforeUpdate: z.boolean().optional().default(true).describe("Validate before updating")
|
|
6017
6142
|
});
|
|
6018
6143
|
var updateFlowTool = {
|
|
6019
6144
|
name: "update_flow",
|
|
6020
|
-
description: "Update an existing Power Automate flow.
|
|
6145
|
+
description: "Update an existing Power Automate flow. Three update modes: (1) full replace \u2014 pass 'actions' to replace all top-level actions (default; you must include nested actions you want kept), (2) merge \u2014 set mergeActions=true to deep-merge only the actions you provide, leaving the rest intact, (3) patch \u2014 use patchActions with path keys (e.g. 'If/cases/Default/actions/Compose') for surgical edits with the smallest payload. Use get_flow with format='json' first to see the full nested action tree.",
|
|
6021
6146
|
inputSchema: {
|
|
6022
6147
|
type: "object",
|
|
6023
6148
|
properties: {
|
|
@@ -6029,6 +6154,10 @@ var updateFlowTool = {
|
|
|
6029
6154
|
type: "string",
|
|
6030
6155
|
description: "New display name for the flow"
|
|
6031
6156
|
},
|
|
6157
|
+
description: {
|
|
6158
|
+
type: "string",
|
|
6159
|
+
description: "New description for the flow (empty string clears)"
|
|
6160
|
+
},
|
|
6032
6161
|
trigger: {
|
|
6033
6162
|
type: "object",
|
|
6034
6163
|
description: "New trigger definition (replaces existing)"
|
|
@@ -6039,7 +6168,16 @@ var updateFlowTool = {
|
|
|
6039
6168
|
},
|
|
6040
6169
|
actions: {
|
|
6041
6170
|
type: "object",
|
|
6042
|
-
description: "
|
|
6171
|
+
description: "Actions. By default replaces all existing top-level actions. With mergeActions=true, deep-merges instead."
|
|
6172
|
+
},
|
|
6173
|
+
mergeActions: {
|
|
6174
|
+
type: "boolean",
|
|
6175
|
+
description: "When true, deep-merge 'actions' onto current flow instead of replacing. Recurses into nested actions/cases/else/foreach.",
|
|
6176
|
+
default: false
|
|
6177
|
+
},
|
|
6178
|
+
patchActions: {
|
|
6179
|
+
type: "object",
|
|
6180
|
+
description: "Path-based patch map. Keys: slash-separated paths like 'If/cases/Default/actions/Compose'. Value=null deletes the node. Smallest payload."
|
|
6043
6181
|
},
|
|
6044
6182
|
connectionReferences: {
|
|
6045
6183
|
type: "object",
|
|
@@ -6057,17 +6195,80 @@ var updateFlowTool = {
|
|
|
6057
6195
|
required: ["flowId"]
|
|
6058
6196
|
}
|
|
6059
6197
|
};
|
|
6198
|
+
function deepMerge(base, patch) {
|
|
6199
|
+
const out = { ...base };
|
|
6200
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
6201
|
+
if (value === void 0) continue;
|
|
6202
|
+
const baseVal = out[key];
|
|
6203
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value) && baseVal !== null && typeof baseVal === "object" && !Array.isArray(baseVal)) {
|
|
6204
|
+
out[key] = deepMerge(
|
|
6205
|
+
baseVal,
|
|
6206
|
+
value
|
|
6207
|
+
);
|
|
6208
|
+
} else {
|
|
6209
|
+
out[key] = value;
|
|
6210
|
+
}
|
|
6211
|
+
}
|
|
6212
|
+
return out;
|
|
6213
|
+
}
|
|
6214
|
+
function applyPathPatch(actions, path, value) {
|
|
6215
|
+
const segments = path.split("/").filter(Boolean);
|
|
6216
|
+
if (segments.length === 0) return actions;
|
|
6217
|
+
const result = JSON.parse(JSON.stringify(actions));
|
|
6218
|
+
let cursor = result;
|
|
6219
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
6220
|
+
const seg = segments[i];
|
|
6221
|
+
const next = cursor[seg];
|
|
6222
|
+
if (next === null || typeof next !== "object" || Array.isArray(next)) {
|
|
6223
|
+
cursor[seg] = {};
|
|
6224
|
+
}
|
|
6225
|
+
cursor = cursor[seg];
|
|
6226
|
+
}
|
|
6227
|
+
const lastSeg = segments[segments.length - 1];
|
|
6228
|
+
if (value === null) {
|
|
6229
|
+
delete cursor[lastSeg];
|
|
6230
|
+
} else {
|
|
6231
|
+
cursor[lastSeg] = value;
|
|
6232
|
+
}
|
|
6233
|
+
return result;
|
|
6234
|
+
}
|
|
6060
6235
|
async function handleUpdateFlow(api, input) {
|
|
6061
6236
|
const parsed = updateFlowInputSchema.parse(input);
|
|
6062
|
-
logger.info(
|
|
6237
|
+
logger.info(
|
|
6238
|
+
{
|
|
6239
|
+
flowId: parsed.flowId,
|
|
6240
|
+
mergeActions: parsed.mergeActions,
|
|
6241
|
+
hasPatch: !!parsed.patchActions
|
|
6242
|
+
},
|
|
6243
|
+
"Executing update_flow"
|
|
6244
|
+
);
|
|
6063
6245
|
const currentFlow = await api.getFlow(parsed.flowId, parsed.environment);
|
|
6064
6246
|
const currentDef = currentFlow.properties.definition;
|
|
6065
6247
|
const currentConnRefs = currentFlow.properties.connectionReferences;
|
|
6066
6248
|
const newDisplayName = parsed.displayName ?? currentFlow.properties.displayName;
|
|
6249
|
+
const newDescription = parsed.description !== void 0 ? parsed.description : currentFlow.properties.description;
|
|
6067
6250
|
let newDefinition;
|
|
6068
|
-
|
|
6251
|
+
let resolvedActions;
|
|
6252
|
+
if (parsed.actions || parsed.patchActions) {
|
|
6253
|
+
if (parsed.mergeActions && parsed.actions) {
|
|
6254
|
+
resolvedActions = deepMerge(
|
|
6255
|
+
currentDef.actions,
|
|
6256
|
+
parsed.actions
|
|
6257
|
+
);
|
|
6258
|
+
} else if (parsed.actions) {
|
|
6259
|
+
resolvedActions = parsed.actions;
|
|
6260
|
+
} else {
|
|
6261
|
+
resolvedActions = JSON.parse(JSON.stringify(currentDef.actions));
|
|
6262
|
+
}
|
|
6263
|
+
if (parsed.patchActions) {
|
|
6264
|
+
for (const [path, value] of Object.entries(parsed.patchActions)) {
|
|
6265
|
+
resolvedActions = applyPathPatch(resolvedActions, path, value);
|
|
6266
|
+
}
|
|
6267
|
+
}
|
|
6268
|
+
}
|
|
6269
|
+
if (parsed.trigger || resolvedActions) {
|
|
6069
6270
|
const triggerName = parsed.triggerName ?? Object.keys(currentDef.triggers)[0] ?? "manual";
|
|
6070
|
-
const processedActions =
|
|
6271
|
+
const processedActions = resolvedActions ? preprocessFlowActions(resolvedActions) : currentDef.actions;
|
|
6071
6272
|
newDefinition = {
|
|
6072
6273
|
$schema: currentDef.$schema,
|
|
6073
6274
|
contentVersion: currentDef.contentVersion,
|
|
@@ -6121,7 +6322,8 @@ async function handleUpdateFlow(api, input) {
|
|
|
6121
6322
|
properties: {
|
|
6122
6323
|
displayName: newDisplayName,
|
|
6123
6324
|
definition: newDefinition,
|
|
6124
|
-
connectionReferences: newConnRefs
|
|
6325
|
+
connectionReferences: newConnRefs,
|
|
6326
|
+
...newDescription !== void 0 ? { description: newDescription } : {}
|
|
6125
6327
|
}
|
|
6126
6328
|
};
|
|
6127
6329
|
try {
|