@clipform/mcp-server 4.2.0 → 4.2.2
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/api-client.d.ts +0 -12
- package/dist/api-client.js +1 -1
- package/dist/{chunk-TXUWAYBZ.js → chunk-5AAKB4S5.js} +3 -3
- package/dist/{chunk-5RUWQOYD.js → chunk-APCG2RRD.js} +3 -3
- package/dist/{chunk-PDI6VJYQ.js → chunk-FGTU764J.js} +14 -2
- package/dist/chunk-FGTU764J.js.map +1 -0
- package/dist/{chunk-4IAURGG7.js → chunk-KZNBYHHR.js} +18 -2
- package/dist/chunk-KZNBYHHR.js.map +1 -0
- package/dist/{chunk-YKJV5LZQ.js → chunk-XOV5ILOJ.js} +112 -42
- package/dist/{chunk-YKJV5LZQ.js.map → chunk-XOV5ILOJ.js.map} +1 -1
- package/dist/index.js +5 -5
- package/dist/prompts.js +3 -3
- package/dist/resources.js +3 -3
- package/dist/server.js +5 -5
- package/package.json +1 -1
- package/server.json +2 -2
- package/dist/chunk-4IAURGG7.js.map +0 -1
- package/dist/chunk-PDI6VJYQ.js.map +0 -1
- /package/dist/{chunk-TXUWAYBZ.js.map → chunk-5AAKB4S5.js.map} +0 -0
- /package/dist/{chunk-5RUWQOYD.js.map → chunk-APCG2RRD.js.map} +0 -0
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
union,
|
|
30
30
|
unknown,
|
|
31
31
|
url
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-APCG2RRD.js";
|
|
33
33
|
import {
|
|
34
34
|
GUIDE_TYPES,
|
|
35
35
|
QUIZ_VARIANTS,
|
|
@@ -38,13 +38,18 @@ import {
|
|
|
38
38
|
getGuideUri,
|
|
39
39
|
guideFallbackText,
|
|
40
40
|
registerResources
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-5AAKB4S5.js";
|
|
42
42
|
import {
|
|
43
|
+
ANON_PREVIEW_LINK_LABEL,
|
|
43
44
|
ANON_PREVIEW_NOTICE,
|
|
45
|
+
ANON_PREVIEW_ONLY_NOTICE,
|
|
46
|
+
CLAIM_URL_DESCRIPTION,
|
|
44
47
|
FULL_CAPS,
|
|
48
|
+
PREVIEW_URL_DESCRIPTION,
|
|
45
49
|
anonPreviewNotice,
|
|
46
|
-
capsFromToolsets
|
|
47
|
-
|
|
50
|
+
capsFromToolsets,
|
|
51
|
+
isPreviewViewerUrl
|
|
52
|
+
} from "./chunk-FGTU764J.js";
|
|
48
53
|
import {
|
|
49
54
|
ACTIVE_NODE_TYPES,
|
|
50
55
|
CONTACT_FIELDS,
|
|
@@ -66,7 +71,7 @@ import {
|
|
|
66
71
|
resolveFormType,
|
|
67
72
|
structuredResult,
|
|
68
73
|
textResult
|
|
69
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-KZNBYHHR.js";
|
|
70
75
|
import {
|
|
71
76
|
getMcpAuth,
|
|
72
77
|
runWithMcpAuth,
|
|
@@ -4774,6 +4779,37 @@ var inputRequired = Object.assign(buildInputRequired, {
|
|
|
4774
4779
|
return { method: "roots/list" };
|
|
4775
4780
|
}
|
|
4776
4781
|
});
|
|
4782
|
+
function acceptedContent(responses, key, schema) {
|
|
4783
|
+
const view = inputResponse(responses, key);
|
|
4784
|
+
if (view.kind !== "elicit" || view.action !== "accept" || view.content === void 0) return void 0;
|
|
4785
|
+
if (schema === void 0) return view.content;
|
|
4786
|
+
const outcome = schema["~standard"].validate(view.content);
|
|
4787
|
+
if (outcome instanceof Promise) throw new TypeError("acceptedContent(responses, key, schema) requires a synchronously-validating schema");
|
|
4788
|
+
return outcome.issues === void 0 ? outcome.value : void 0;
|
|
4789
|
+
}
|
|
4790
|
+
function inputResponse(responses, key) {
|
|
4791
|
+
if (responses === void 0 || typeof responses !== "object" || responses === null) return { kind: "missing" };
|
|
4792
|
+
const entry = responses[key];
|
|
4793
|
+
if (entry === null || typeof entry !== "object" || Array.isArray(entry)) return { kind: "missing" };
|
|
4794
|
+
const candidate = entry;
|
|
4795
|
+
if (candidate["action"] === "accept" || candidate["action"] === "decline" || candidate["action"] === "cancel") {
|
|
4796
|
+
const content = candidate["content"];
|
|
4797
|
+
return {
|
|
4798
|
+
kind: "elicit",
|
|
4799
|
+
action: candidate["action"],
|
|
4800
|
+
...content !== null && typeof content === "object" && !Array.isArray(content) && { content }
|
|
4801
|
+
};
|
|
4802
|
+
}
|
|
4803
|
+
if (Array.isArray(candidate["roots"])) return {
|
|
4804
|
+
kind: "roots",
|
|
4805
|
+
roots: candidate["roots"]
|
|
4806
|
+
};
|
|
4807
|
+
if (typeof candidate["role"] === "string" && candidate["content"] !== void 0) return {
|
|
4808
|
+
kind: "sampling",
|
|
4809
|
+
result: candidate
|
|
4810
|
+
};
|
|
4811
|
+
return { kind: "missing" };
|
|
4812
|
+
}
|
|
4777
4813
|
var REQUEST_STATE_ONLY_LEG_PACING_MS = 250;
|
|
4778
4814
|
function inputRequiredRoundsExceededMessage(method, maxRounds) {
|
|
4779
4815
|
return `Multi-round-trip request '${method}' still required input after ${maxRounds} rounds (inputRequired.maxRounds)`;
|
|
@@ -16283,7 +16319,7 @@ function registerCreateFormTool(server) {
|
|
|
16283
16319
|
"clipform_create_form",
|
|
16284
16320
|
{
|
|
16285
16321
|
title: "Create Clipform",
|
|
16286
|
-
description: `Create a new Clipform (interactive video-style form). Returns a viewer URL and form ID. When connected via an authenticated MCP client (e.g. claude.ai), the form lands directly in the user's workspace. Anonymous sessions build into a temporary account of their own: forms stay drafts with a private preview link. Some results also include a one-time claim URL that signs the user into that account; relay it when present.
|
|
16322
|
+
description: `Create a new Clipform (interactive video-style form). Returns a viewer URL and form ID (an anonymous build's link is a private preview where answers are not saved). When connected via an authenticated MCP client (e.g. claude.ai), the form lands directly in the user's workspace. Anonymous sessions build into a temporary account of their own: forms stay drafts with a private preview link. Some results also include a one-time claim URL that signs the user into that account; relay it when present.
|
|
16287
16323
|
|
|
16288
16324
|
${ONBOARDING_OFFER_TOOL_CUE}
|
|
16289
16325
|
|
|
@@ -16313,12 +16349,20 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
16313
16349
|
}),
|
|
16314
16350
|
outputSchema: external_exports.object({
|
|
16315
16351
|
form_id: external_exports.string().describe("Form UUID - pass to follow-up tools"),
|
|
16316
|
-
// #
|
|
16317
|
-
//
|
|
16318
|
-
//
|
|
16319
|
-
//
|
|
16320
|
-
|
|
16321
|
-
|
|
16352
|
+
// #4845 expand/contract. The deployed ChatGPT schema is
|
|
16353
|
+
// additionalProperties:false, so emitting a field it does not declare
|
|
16354
|
+
// is invalid until the Rescan approves a schema that declares it.
|
|
16355
|
+
// Order: (a) deploy the schema declaring preview_url / claim_url /
|
|
16356
|
+
// is_preview as optional, emitting NOTHING new (this step);
|
|
16357
|
+
// (b) Rescan; (c) once approved, emit them; (d) a later Rescan-approved
|
|
16358
|
+
// CONTRACT step drops the anonymous viewer_url / dashboard_url
|
|
16359
|
+
// duplicates. See SUBMISSION.md. Until (c), structuredContent stays
|
|
16360
|
+
// key-for-key what origin/main emitted (approved-schema.test.ts).
|
|
16361
|
+
viewer_url: external_exports.string().describe("Form URL for respondents - the live public URL. For an anonymous build this is a private preview link: answers are not saved, do not share it with respondents."),
|
|
16362
|
+
dashboard_url: external_exports.string().optional().describe("Builder URL (sign in to edit). For an anonymous build this is a one-time claim link, not an editor."),
|
|
16363
|
+
is_preview: external_exports.boolean().optional().describe("True when this is an anonymous preview build (answers are not saved), false otherwise."),
|
|
16364
|
+
preview_url: external_exports.string().optional().describe(`Anonymous builds only. ${PREVIEW_URL_DESCRIPTION}`),
|
|
16365
|
+
claim_url: external_exports.string().optional().describe(`Anonymous builds only. ${CLAIM_URL_DESCRIPTION}`),
|
|
16322
16366
|
nodes: external_exports.array(external_exports.object({ id: external_exports.string(), type: external_exports.string(), prompt: external_exports.string() })).describe("Created nodes in order - IDs for attach_node_media / update_node"),
|
|
16323
16367
|
plan: external_exports.object({ name: external_exports.string(), auth_mode: external_exports.string() }).optional().describe("Plan and auth context for this session"),
|
|
16324
16368
|
workspace_name: external_exports.string().optional().describe("Name of the workspace the form was created in")
|
|
@@ -16411,7 +16455,7 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
16411
16455
|
});
|
|
16412
16456
|
if (!createResult.ok) {
|
|
16413
16457
|
const message = `Form NOT created (nothing was saved): ${createResult.error}`;
|
|
16414
|
-
return isAnonymousAccountRequired(createResult) ? errorResult(message, authChallengeMeta("
|
|
16458
|
+
return isAnonymousAccountRequired(createResult) ? errorResult(message, authChallengeMeta("insufficient_scope", createResult.apiMessage ?? message)) : errorResult(message);
|
|
16415
16459
|
}
|
|
16416
16460
|
const { data } = createResult;
|
|
16417
16461
|
const formId = data.form_id;
|
|
@@ -16433,6 +16477,8 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
16433
16477
|
const truncate2 = (s, n = 60) => s.length > n ? `${s.slice(0, n - 1)}\u2026` : s;
|
|
16434
16478
|
const lines = [
|
|
16435
16479
|
isPreview ? `Form created as a preview draft.` : `Form created and live.`,
|
|
16480
|
+
// #4845: lead with the in-chat path (wording defined once in lib/anon-notice.ts).
|
|
16481
|
+
...isPreview ? [``, ANON_PREVIEW_ONLY_NOTICE] : [],
|
|
16436
16482
|
``,
|
|
16437
16483
|
`Title: ${title}`,
|
|
16438
16484
|
...planContext?.is_authenticated && planContext.workspace_name ? [`Workspace: ${planContext.workspace_name}`] : [],
|
|
@@ -16441,18 +16487,18 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
16441
16487
|
`Node IDs (use directly with attach_node_media / update_node - no get_form round-trip needed):`,
|
|
16442
16488
|
...createdNodes.map((n) => `- [${n.type}] "${truncate2(n.prompt)}": ${n.id}`),
|
|
16443
16489
|
``,
|
|
16444
|
-
isPreview ? `PREVIEW URL (draft - only you can open this, not
|
|
16490
|
+
isPreview ? `PREVIEW URL (draft - answers are not saved, only you can open this, not for respondents): ${data.viewer_url}` : `FORM URL (live - share this with respondents): ${data.viewer_url}`
|
|
16445
16491
|
];
|
|
16446
16492
|
if (formUrl) {
|
|
16447
16493
|
lines.push(
|
|
16448
|
-
isPreview ? `CLAIM URL (one-time
|
|
16494
|
+
isPreview ? `CLAIM URL (fallback - or open this one-time link to sign up in the browser): ${formUrl}` : `DASHBOARD URL (sign in to edit and manage): ${formUrl}`
|
|
16449
16495
|
);
|
|
16450
16496
|
}
|
|
16451
16497
|
const firstUrlLabel = isPreview ? "PREVIEW" : "FORM";
|
|
16452
16498
|
const secondUrlLabel = isPreview ? "CLAIM" : "DASHBOARD";
|
|
16453
16499
|
lines.push(
|
|
16454
16500
|
``,
|
|
16455
|
-
isPreview ? `This form is a preview
|
|
16501
|
+
isPreview ? `This form is a preview, not live. When the user says "publish it", call clipform_update_form (is_live: true); it prompts them to sign in. The PREVIEW URL never becomes public on its own.` : `The form is live and accessible at the FORM URL above. Edits and media attached AFTER this point are NOT visible to respondents until you re-send is_live: true via clipform_update_form - republishing is the expected final step of a build, never skip it after attaching media/narration.`,
|
|
16456
16502
|
formUrl ? `The URLs above are exact values; constructed or guessed URLs return 404. Use the ${firstUrlLabel} URL and ${secondUrlLabel} URL as shown.` : `The ${firstUrlLabel} URL above is an exact value; constructed or guessed URLs return 404.`,
|
|
16457
16503
|
`Pass form_id on follow-up tools (get_form, add_node, attach_node_media, etc.).`
|
|
16458
16504
|
);
|
|
@@ -16923,7 +16969,11 @@ function formatFormState(data) {
|
|
|
16923
16969
|
const urls = projectUrls(data);
|
|
16924
16970
|
if (urls) {
|
|
16925
16971
|
lines.push(``, `Links (exact values - constructed or guessed URLs return 404):`);
|
|
16926
|
-
if (urls.viewer)
|
|
16972
|
+
if (urls.viewer) {
|
|
16973
|
+
lines.push(
|
|
16974
|
+
isPreviewViewerUrl(urls.viewer) ? ` ${ANON_PREVIEW_LINK_LABEL}: ${urls.viewer}` : ` Viewer (respondent view): ${urls.viewer}`
|
|
16975
|
+
);
|
|
16976
|
+
}
|
|
16927
16977
|
if (urls.builder) lines.push(` Builder: ${urls.builder}`);
|
|
16928
16978
|
if (urls.summary) lines.push(` Summary: ${urls.summary}`);
|
|
16929
16979
|
if (urls.responses) lines.push(` Responses: ${urls.responses}`);
|
|
@@ -16932,6 +16982,7 @@ function formatFormState(data) {
|
|
|
16932
16982
|
if (urls.embed) lines.push(` Embed: ${urls.embed}`);
|
|
16933
16983
|
if (urls.dynamic_link) lines.push(` Dynamic link: ${urls.dynamic_link}`);
|
|
16934
16984
|
}
|
|
16985
|
+
if (isPreviewViewerUrl(urls?.viewer)) lines.push(``, ANON_PREVIEW_ONLY_NOTICE);
|
|
16935
16986
|
lines.push(``, `Nodes (in order):`);
|
|
16936
16987
|
for (let i = 0; i < nodes.length; i++) {
|
|
16937
16988
|
const q = nodes[i];
|
|
@@ -16972,7 +17023,7 @@ function registerGetFormTool(server) {
|
|
|
16972
17023
|
is_live: external_exports.boolean().describe("Whether the form is published"),
|
|
16973
17024
|
has_unpublished_changes: external_exports.boolean().describe("Live form has edits not yet republished"),
|
|
16974
17025
|
urls: external_exports.object({
|
|
16975
|
-
viewer: external_exports.string().optional().describe("Live respondent link, or
|
|
17026
|
+
viewer: external_exports.string().optional().describe("Live respondent link, or - for an anonymous caller's draft - a private preview link where answers are not saved (do not share it with respondents). Omitted for a non-anonymous caller's unpublished draft."),
|
|
16976
17027
|
builder: external_exports.string().optional().describe("Build tab - the node/canvas editor. Not present for an anonymous caller."),
|
|
16977
17028
|
summary: external_exports.string().optional().describe("Summary tab - form overview and key stats. Not present for an anonymous caller."),
|
|
16978
17029
|
responses: external_exports.string().optional().describe("Responses tab - individual submissions. Not present for an anonymous caller."),
|
|
@@ -17081,7 +17132,7 @@ function registerUpdateFormTool(server) {
|
|
|
17081
17132
|
if (!result.ok) {
|
|
17082
17133
|
return isAnonymousAccountRequired(result) ? errorResult(
|
|
17083
17134
|
result.error,
|
|
17084
|
-
authChallengeMeta("
|
|
17135
|
+
authChallengeMeta("insufficient_scope", result.apiMessage ?? result.error)
|
|
17085
17136
|
) : errorResult(result.error);
|
|
17086
17137
|
}
|
|
17087
17138
|
}
|
|
@@ -17093,7 +17144,7 @@ function registerUpdateFormTool(server) {
|
|
|
17093
17144
|
if (!tagResult.ok) {
|
|
17094
17145
|
return isAnonymousAccountRequired(tagResult) ? errorResult(
|
|
17095
17146
|
tagResult.error,
|
|
17096
|
-
authChallengeMeta("
|
|
17147
|
+
authChallengeMeta("insufficient_scope", tagResult.apiMessage ?? tagResult.error)
|
|
17097
17148
|
) : errorResult(tagResult.error);
|
|
17098
17149
|
}
|
|
17099
17150
|
}
|
|
@@ -17179,23 +17230,42 @@ ${anonNotice}`;
|
|
|
17179
17230
|
|
|
17180
17231
|
// src/lib/confirm.ts
|
|
17181
17232
|
var CONFIRM_FIELD_DESCRIPTION = "Set to true ONLY after the user has explicitly confirmed this destructive action. Leave unset otherwise - hosts that support confirmation dialogs will prompt the user automatically.";
|
|
17182
|
-
|
|
17233
|
+
var CONFIRM_RESPONSE_SCHEMA = external_exports.object({ confirm: external_exports.boolean() });
|
|
17234
|
+
var CANCELLED = "Cancelled - nothing was changed.";
|
|
17235
|
+
async function confirmDestructive(server, ctx, opts) {
|
|
17183
17236
|
if (opts.alreadyConfirmed === true) return { proceed: true };
|
|
17237
|
+
const mcpReq = ctx?.mcpReq;
|
|
17238
|
+
const responses = mcpReq?.inputResponses;
|
|
17239
|
+
if (responses && responses.confirm !== void 0) {
|
|
17240
|
+
const answer = acceptedContent(responses, "confirm", CONFIRM_RESPONSE_SCHEMA);
|
|
17241
|
+
if (answer?.confirm === true) return { proceed: true };
|
|
17242
|
+
return { proceed: false, message: CANCELLED };
|
|
17243
|
+
}
|
|
17244
|
+
const requestedSchema = {
|
|
17245
|
+
type: "object",
|
|
17246
|
+
properties: {
|
|
17247
|
+
confirm: { type: "boolean", title: "Confirm", description: opts.message }
|
|
17248
|
+
},
|
|
17249
|
+
required: ["confirm"]
|
|
17250
|
+
};
|
|
17251
|
+
const envelope = mcpReq?.envelope;
|
|
17252
|
+
if (envelope) {
|
|
17253
|
+
if (envelope["io.modelcontextprotocol/clientCapabilities"]?.elicitation) {
|
|
17254
|
+
return {
|
|
17255
|
+
proceed: false,
|
|
17256
|
+
result: inputRequired({
|
|
17257
|
+
inputRequests: { confirm: inputRequired.elicit({ message: opts.message, requestedSchema }) }
|
|
17258
|
+
})
|
|
17259
|
+
};
|
|
17260
|
+
}
|
|
17261
|
+
return { proceed: false, message: opts.relay };
|
|
17262
|
+
}
|
|
17184
17263
|
const lowLevel = server.server;
|
|
17185
17264
|
const caps = lowLevel?.getClientCapabilities?.();
|
|
17186
17265
|
if (caps?.elicitation) {
|
|
17187
|
-
const r = await lowLevel.elicitInput({
|
|
17188
|
-
message: opts.message,
|
|
17189
|
-
requestedSchema: {
|
|
17190
|
-
type: "object",
|
|
17191
|
-
properties: {
|
|
17192
|
-
confirm: { type: "boolean", title: "Confirm", description: opts.message }
|
|
17193
|
-
},
|
|
17194
|
-
required: ["confirm"]
|
|
17195
|
-
}
|
|
17196
|
-
});
|
|
17266
|
+
const r = await lowLevel.elicitInput({ message: opts.message, requestedSchema });
|
|
17197
17267
|
if (r.action === "accept" && r.content?.confirm === true) return { proceed: true };
|
|
17198
|
-
return { proceed: false, message:
|
|
17268
|
+
return { proceed: false, message: CANCELLED };
|
|
17199
17269
|
}
|
|
17200
17270
|
return { proceed: false, message: opts.relay };
|
|
17201
17271
|
}
|
|
@@ -17223,14 +17293,14 @@ function registerDeleteFormTool(server) {
|
|
|
17223
17293
|
openWorldHint: true
|
|
17224
17294
|
}
|
|
17225
17295
|
},
|
|
17226
|
-
async ({ form_id, confirm }) => {
|
|
17227
|
-
const decision = await confirmDestructive(server, {
|
|
17296
|
+
async ({ form_id, confirm }, ctx) => {
|
|
17297
|
+
const decision = await confirmDestructive(server, ctx, {
|
|
17228
17298
|
alreadyConfirmed: confirm,
|
|
17229
17299
|
message: `Move form ${form_id} to the trash? It stops accepting responses immediately and can be restored later.`,
|
|
17230
17300
|
relay: `Confirmation required: moving form ${form_id} to the trash stops it accepting responses immediately. It can be restored later. Ask the user to confirm, then call clipform_delete_form again with confirm: true.`
|
|
17231
17301
|
});
|
|
17232
17302
|
if (!decision.proceed) {
|
|
17233
|
-
return textResult(decision.message);
|
|
17303
|
+
return decision.result ?? textResult(decision.message);
|
|
17234
17304
|
}
|
|
17235
17305
|
const result = await callApi(`/forms/${form_id}`, {
|
|
17236
17306
|
method: "DELETE"
|
|
@@ -17797,14 +17867,14 @@ function registerDeleteNodeTool(server) {
|
|
|
17797
17867
|
openWorldHint: false
|
|
17798
17868
|
}
|
|
17799
17869
|
},
|
|
17800
|
-
async ({ form_id, node_id, confirm }) => {
|
|
17801
|
-
const decision = await confirmDestructive(server, {
|
|
17870
|
+
async ({ form_id, node_id, confirm }, ctx) => {
|
|
17871
|
+
const decision = await confirmDestructive(server, ctx, {
|
|
17802
17872
|
alreadyConfirmed: confirm,
|
|
17803
17873
|
message: `Delete node ${node_id} from this form? This cannot be undone.`,
|
|
17804
17874
|
relay: `Confirmation required: deleting node ${node_id} cannot be undone. Ask the user to confirm, then call clipform_delete_node again with confirm: true.`
|
|
17805
17875
|
});
|
|
17806
17876
|
if (!decision.proceed) {
|
|
17807
|
-
return textResult(decision.message);
|
|
17877
|
+
return decision.result ?? textResult(decision.message);
|
|
17808
17878
|
}
|
|
17809
17879
|
const result = await callApi(
|
|
17810
17880
|
`/forms/${form_id}/nodes/${node_id}`,
|
|
@@ -18290,14 +18360,14 @@ function registerDeleteNodeMediaTool(server) {
|
|
|
18290
18360
|
openWorldHint: true
|
|
18291
18361
|
}
|
|
18292
18362
|
},
|
|
18293
|
-
async ({ form_id, node_id, confirm }) => {
|
|
18294
|
-
const decision = await confirmDestructive(server, {
|
|
18363
|
+
async ({ form_id, node_id, confirm }, ctx) => {
|
|
18364
|
+
const decision = await confirmDestructive(server, ctx, {
|
|
18295
18365
|
alreadyConfirmed: confirm,
|
|
18296
18366
|
message: `Remove the media attached to node ${node_id}? This deletes the underlying video/file and cannot be undone.`,
|
|
18297
18367
|
relay: `Confirmation required: removing media from node ${node_id} deletes the underlying video/file and cannot be undone. Ask the user to confirm, then call clipform_delete_node_media again with confirm: true.`
|
|
18298
18368
|
});
|
|
18299
18369
|
if (!decision.proceed) {
|
|
18300
|
-
return textResult(decision.message);
|
|
18370
|
+
return decision.result ?? textResult(decision.message);
|
|
18301
18371
|
}
|
|
18302
18372
|
const result = await callApi(
|
|
18303
18373
|
`/forms/${form_id}/nodes/${node_id}/media`,
|
|
@@ -20097,4 +20167,4 @@ export {
|
|
|
20097
20167
|
* MIT Licensed
|
|
20098
20168
|
*)
|
|
20099
20169
|
*/
|
|
20100
|
-
//# sourceMappingURL=chunk-
|
|
20170
|
+
//# sourceMappingURL=chunk-XOV5ILOJ.js.map
|