@flanksource/clicky-ui 0.3.12 → 0.3.14
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/data/ai/SessionViewer.input.cjs +2 -1
- package/dist/data/ai/SessionViewer.input.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.input.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.input.js +2 -1
- package/dist/data/ai/SessionViewer.input.js.map +1 -1
- package/dist/data/diagnostics/error-diagnostics.cjs +38 -6
- package/dist/data/diagnostics/error-diagnostics.cjs.map +1 -1
- package/dist/data/diagnostics/error-diagnostics.js +38 -6
- package/dist/data/diagnostics/error-diagnostics.js.map +1 -1
- package/dist/data/diagnostics/jvm-stacktrace.cjs +35 -3
- package/dist/data/diagnostics/jvm-stacktrace.cjs.map +1 -1
- package/dist/data/diagnostics/jvm-stacktrace.d.ts.map +1 -1
- package/dist/data/diagnostics/jvm-stacktrace.js +35 -3
- package/dist/data/diagnostics/jvm-stacktrace.js.map +1 -1
- package/dist/data/diagnostics/stacktrace-parse.cjs +19 -5
- package/dist/data/diagnostics/stacktrace-parse.cjs.map +1 -1
- package/dist/data/diagnostics/stacktrace-parse.d.ts.map +1 -1
- package/dist/data/diagnostics/stacktrace-parse.js +19 -5
- package/dist/data/diagnostics/stacktrace-parse.js.map +1 -1
- package/dist/data/diagnostics/stacktrace.cjs +50 -7
- package/dist/data/diagnostics/stacktrace.cjs.map +1 -1
- package/dist/data/diagnostics/stacktrace.d.ts.map +1 -1
- package/dist/data/diagnostics/stacktrace.js +50 -7
- package/dist/data/diagnostics/stacktrace.js.map +1 -1
- package/dist/data/test-runner/routePath.cjs +3 -1
- package/dist/data/test-runner/routePath.cjs.map +1 -1
- package/dist/data/test-runner/routePath.d.ts.map +1 -1
- package/dist/data/test-runner/routePath.js +3 -1
- package/dist/data/test-runner/routePath.js.map +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/lib/string.cjs +15 -0
- package/dist/lib/string.cjs.map +1 -0
- package/dist/lib/string.d.ts +3 -0
- package/dist/lib/string.d.ts.map +1 -0
- package/dist/lib/string.js +15 -0
- package/dist/lib/string.js.map +1 -0
- package/dist/rpc/OperationActionDialog.cjs +4 -10
- package/dist/rpc/OperationActionDialog.cjs.map +1 -1
- package/dist/rpc/OperationActionDialog.d.ts.map +1 -1
- package/dist/rpc/OperationActionDialog.js +2 -8
- package/dist/rpc/OperationActionDialog.js.map +1 -1
- package/dist/rpc/OperationCommandPage.cjs +3 -2
- package/dist/rpc/OperationCommandPage.cjs.map +1 -1
- package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
- package/dist/rpc/OperationCommandPage.js +3 -2
- package/dist/rpc/OperationCommandPage.js.map +1 -1
- package/dist/rpc/apiClient.cjs +2 -1
- package/dist/rpc/apiClient.cjs.map +1 -1
- package/dist/rpc/apiClient.d.ts.map +1 -1
- package/dist/rpc/apiClient.js +2 -1
- package/dist/rpc/apiClient.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routePath.cjs","sources":["../../../src/data/test-runner/routePath.ts"],"sourcesContent":["// Stable, URL-safe paths for selection/navigation. A host that wants to encode\n// the selected node in its route annotates the forest once with annotateRoutePaths\n// (writing Test.route_path), then resolves a path back to a node with\n// findNodeByRoutePath. Tree's nodeKey already prefers route_path, so an annotated\n// forest also gets stable React keys for free.\n\nimport type { Test } from \"./types\";\n\nexport function slugify(value: string): string {\n
|
|
1
|
+
{"version":3,"file":"routePath.cjs","sources":["../../../src/data/test-runner/routePath.ts"],"sourcesContent":["// Stable, URL-safe paths for selection/navigation. A host that wants to encode\n// the selected node in its route annotates the forest once with annotateRoutePaths\n// (writing Test.route_path), then resolves a path back to a node with\n// findNodeByRoutePath. Tree's nodeKey already prefers route_path, so an annotated\n// forest also gets stable React keys for free.\n\nimport type { Test } from \"./types\";\n\nexport function slugify(value: string): string {\n let slug = (value || \"\").toLowerCase().replace(/[^a-z0-9]+/g, \"-\");\n if (slug.startsWith(\"-\")) slug = slug.slice(1);\n if (slug.endsWith(\"-\")) slug = slug.slice(0, -1);\n return slug || \"node\";\n}\n\n/**\n * Return a deep copy of the forest with a stable, unique `route_path` on every\n * node. Each segment is the slug of the node's name; siblings that slug to the\n * same value are disambiguated with a `~N` ordinal so paths stay unique.\n */\nexport function annotateRoutePaths(nodes: Test[], parentSegments: string[] = []): Test[] {\n const counts = new Map<string, number>();\n for (const node of nodes) {\n const slug = slugify(node.name);\n counts.set(slug, (counts.get(slug) || 0) + 1);\n }\n\n const seen = new Map<string, number>();\n return nodes.map((node) => {\n const slug = slugify(node.name);\n const ordinal = (seen.get(slug) || 0) + 1;\n seen.set(slug, ordinal);\n const finalSlug = (counts.get(slug) || 0) > 1 ? `${slug}~${ordinal}` : slug;\n const segments = [...parentSegments, finalSlug];\n const annotated: Test = { ...node, route_path: segments.join(\"/\") };\n if (node.children) annotated.children = annotateRoutePaths(node.children, segments);\n return annotated;\n });\n}\n\n/** Depth-first lookup of the node whose route_path equals target, or null. */\nexport function findNodeByRoutePath(nodes: Test[], target: string): Test | null {\n if (!target) return null;\n for (const node of nodes) {\n if (node.route_path === target) return node;\n if (node.children) {\n const child = findNodeByRoutePath(node.children, target);\n if (child) return child;\n }\n }\n return null;\n}\n"],"names":[],"mappings":";;AAQO,SAAS,QAAQ,OAAuB;AAC7C,MAAI,QAAQ,SAAS,IAAI,cAAc,QAAQ,eAAe,GAAG;AACjE,MAAI,KAAK,WAAW,GAAG,EAAG,QAAO,KAAK,MAAM,CAAC;AAC7C,MAAI,KAAK,SAAS,GAAG,UAAU,KAAK,MAAM,GAAG,EAAE;AAC/C,SAAO,QAAQ;AACjB;AAOO,SAAS,mBAAmB,OAAe,iBAA2B,IAAY;AACvF,QAAM,6BAAa,IAAA;AACnB,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,QAAQ,KAAK,IAAI;AAC9B,WAAO,IAAI,OAAO,OAAO,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,EAC9C;AAEA,QAAM,2BAAW,IAAA;AACjB,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,UAAM,OAAO,QAAQ,KAAK,IAAI;AAC9B,UAAM,WAAW,KAAK,IAAI,IAAI,KAAK,KAAK;AACxC,SAAK,IAAI,MAAM,OAAO;AACtB,UAAM,aAAa,OAAO,IAAI,IAAI,KAAK,KAAK,IAAI,GAAG,IAAI,IAAI,OAAO,KAAK;AACvE,UAAM,WAAW,CAAC,GAAG,gBAAgB,SAAS;AAC9C,UAAM,YAAkB,EAAE,GAAG,MAAM,YAAY,SAAS,KAAK,GAAG,EAAA;AAChE,QAAI,KAAK,SAAU,WAAU,WAAW,mBAAmB,KAAK,UAAU,QAAQ;AAClF,WAAO;AAAA,EACT,CAAC;AACH;AAGO,SAAS,oBAAoB,OAAe,QAA6B;AAC9E,MAAI,CAAC,OAAQ,QAAO;AACpB,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,eAAe,OAAQ,QAAO;AACvC,QAAI,KAAK,UAAU;AACjB,YAAM,QAAQ,oBAAoB,KAAK,UAAU,MAAM;AACvD,UAAI,MAAO,QAAO;AAAA,IACpB;AAAA,EACF;AACA,SAAO;AACT;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routePath.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/routePath.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAEpC,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"routePath.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/routePath.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAEpC,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK7C;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,cAAc,GAAE,MAAM,EAAO,GAAG,IAAI,EAAE,CAkBvF;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAU9E"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
function slugify(value) {
|
|
2
|
-
|
|
2
|
+
let slug = (value || "").toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
3
|
+
if (slug.startsWith("-")) slug = slug.slice(1);
|
|
4
|
+
if (slug.endsWith("-")) slug = slug.slice(0, -1);
|
|
3
5
|
return slug || "node";
|
|
4
6
|
}
|
|
5
7
|
function annotateRoutePaths(nodes, parentSegments = []) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routePath.js","sources":["../../../src/data/test-runner/routePath.ts"],"sourcesContent":["// Stable, URL-safe paths for selection/navigation. A host that wants to encode\n// the selected node in its route annotates the forest once with annotateRoutePaths\n// (writing Test.route_path), then resolves a path back to a node with\n// findNodeByRoutePath. Tree's nodeKey already prefers route_path, so an annotated\n// forest also gets stable React keys for free.\n\nimport type { Test } from \"./types\";\n\nexport function slugify(value: string): string {\n
|
|
1
|
+
{"version":3,"file":"routePath.js","sources":["../../../src/data/test-runner/routePath.ts"],"sourcesContent":["// Stable, URL-safe paths for selection/navigation. A host that wants to encode\n// the selected node in its route annotates the forest once with annotateRoutePaths\n// (writing Test.route_path), then resolves a path back to a node with\n// findNodeByRoutePath. Tree's nodeKey already prefers route_path, so an annotated\n// forest also gets stable React keys for free.\n\nimport type { Test } from \"./types\";\n\nexport function slugify(value: string): string {\n let slug = (value || \"\").toLowerCase().replace(/[^a-z0-9]+/g, \"-\");\n if (slug.startsWith(\"-\")) slug = slug.slice(1);\n if (slug.endsWith(\"-\")) slug = slug.slice(0, -1);\n return slug || \"node\";\n}\n\n/**\n * Return a deep copy of the forest with a stable, unique `route_path` on every\n * node. Each segment is the slug of the node's name; siblings that slug to the\n * same value are disambiguated with a `~N` ordinal so paths stay unique.\n */\nexport function annotateRoutePaths(nodes: Test[], parentSegments: string[] = []): Test[] {\n const counts = new Map<string, number>();\n for (const node of nodes) {\n const slug = slugify(node.name);\n counts.set(slug, (counts.get(slug) || 0) + 1);\n }\n\n const seen = new Map<string, number>();\n return nodes.map((node) => {\n const slug = slugify(node.name);\n const ordinal = (seen.get(slug) || 0) + 1;\n seen.set(slug, ordinal);\n const finalSlug = (counts.get(slug) || 0) > 1 ? `${slug}~${ordinal}` : slug;\n const segments = [...parentSegments, finalSlug];\n const annotated: Test = { ...node, route_path: segments.join(\"/\") };\n if (node.children) annotated.children = annotateRoutePaths(node.children, segments);\n return annotated;\n });\n}\n\n/** Depth-first lookup of the node whose route_path equals target, or null. */\nexport function findNodeByRoutePath(nodes: Test[], target: string): Test | null {\n if (!target) return null;\n for (const node of nodes) {\n if (node.route_path === target) return node;\n if (node.children) {\n const child = findNodeByRoutePath(node.children, target);\n if (child) return child;\n }\n }\n return null;\n}\n"],"names":[],"mappings":"AAQO,SAAS,QAAQ,OAAuB;AAC7C,MAAI,QAAQ,SAAS,IAAI,cAAc,QAAQ,eAAe,GAAG;AACjE,MAAI,KAAK,WAAW,GAAG,EAAG,QAAO,KAAK,MAAM,CAAC;AAC7C,MAAI,KAAK,SAAS,GAAG,UAAU,KAAK,MAAM,GAAG,EAAE;AAC/C,SAAO,QAAQ;AACjB;AAOO,SAAS,mBAAmB,OAAe,iBAA2B,IAAY;AACvF,QAAM,6BAAa,IAAA;AACnB,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,QAAQ,KAAK,IAAI;AAC9B,WAAO,IAAI,OAAO,OAAO,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,EAC9C;AAEA,QAAM,2BAAW,IAAA;AACjB,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,UAAM,OAAO,QAAQ,KAAK,IAAI;AAC9B,UAAM,WAAW,KAAK,IAAI,IAAI,KAAK,KAAK;AACxC,SAAK,IAAI,MAAM,OAAO;AACtB,UAAM,aAAa,OAAO,IAAI,IAAI,KAAK,KAAK,IAAI,GAAG,IAAI,IAAI,OAAO,KAAK;AACvE,UAAM,WAAW,CAAC,GAAG,gBAAgB,SAAS;AAC9C,UAAM,YAAkB,EAAE,GAAG,MAAM,YAAY,SAAS,KAAK,GAAG,EAAA;AAChE,QAAI,KAAK,SAAU,WAAU,WAAW,mBAAmB,KAAK,UAAU,QAAQ;AAClF,WAAO;AAAA,EACT,CAAC;AACH;AAGO,SAAS,oBAAoB,OAAe,QAA6B;AAC9E,MAAI,CAAC,OAAQ,QAAO;AACpB,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,eAAe,OAAQ,QAAO;AACvC,QAAI,KAAK,UAAU;AACjB,YAAM,QAAQ,oBAAoB,KAAK,UAAU,MAAM;AACvD,UAAI,MAAO,QAAO;AAAA,IACpB;AAAA,EACF;AACA,SAAO;AACT;"}
|
|
@@ -15,9 +15,9 @@ function detectMode() {
|
|
|
15
15
|
}
|
|
16
16
|
function getVersionInfo() {
|
|
17
17
|
return {
|
|
18
|
-
commit: read(() => "
|
|
19
|
-
tag: read(() => "clicky-ui@0.3.
|
|
20
|
-
date: read(() => "2026-07-
|
|
18
|
+
commit: read(() => "2ab76b33", ""),
|
|
19
|
+
tag: read(() => "clicky-ui@0.3.13", ""),
|
|
20
|
+
date: read(() => "2026-07-16T18:37:04.048Z", ""),
|
|
21
21
|
dirty: read(() => true, false),
|
|
22
22
|
mode: detectMode()
|
|
23
23
|
};
|
|
@@ -13,9 +13,9 @@ function detectMode() {
|
|
|
13
13
|
}
|
|
14
14
|
function getVersionInfo() {
|
|
15
15
|
return {
|
|
16
|
-
commit: read(() => "
|
|
17
|
-
tag: read(() => "clicky-ui@0.3.
|
|
18
|
-
date: read(() => "2026-07-
|
|
16
|
+
commit: read(() => "2ab76b33", ""),
|
|
17
|
+
tag: read(() => "clicky-ui@0.3.13", ""),
|
|
18
|
+
date: read(() => "2026-07-16T18:36:45.992Z", ""),
|
|
19
19
|
dirty: read(() => true, false),
|
|
20
20
|
mode: detectMode()
|
|
21
21
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
function stripLeadingSlashes(value) {
|
|
4
|
+
let start = 0;
|
|
5
|
+
while (start < value.length && value[start] === "/") start++;
|
|
6
|
+
return value.slice(start);
|
|
7
|
+
}
|
|
8
|
+
function stripTrailingSlashes(value) {
|
|
9
|
+
let end = value.length;
|
|
10
|
+
while (end > 0 && value[end - 1] === "/") end--;
|
|
11
|
+
return value.slice(0, end);
|
|
12
|
+
}
|
|
13
|
+
exports.stripLeadingSlashes = stripLeadingSlashes;
|
|
14
|
+
exports.stripTrailingSlashes = stripTrailingSlashes;
|
|
15
|
+
//# sourceMappingURL=string.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"string.cjs","sources":["../../src/lib/string.ts"],"sourcesContent":["export function stripLeadingSlashes(value: string): string {\n let start = 0;\n while (start < value.length && value[start] === \"/\") start++;\n return value.slice(start);\n}\n\nexport function stripTrailingSlashes(value: string): string {\n let end = value.length;\n while (end > 0 && value[end - 1] === \"/\") end--;\n return value.slice(0, end);\n}\n"],"names":[],"mappings":";;AAAO,SAAS,oBAAoB,OAAuB;AACzD,MAAI,QAAQ;AACZ,SAAO,QAAQ,MAAM,UAAU,MAAM,KAAK,MAAM,IAAK;AACrD,SAAO,MAAM,MAAM,KAAK;AAC1B;AAEO,SAAS,qBAAqB,OAAuB;AAC1D,MAAI,MAAM,MAAM;AAChB,SAAO,MAAM,KAAK,MAAM,MAAM,CAAC,MAAM,IAAK;AAC1C,SAAO,MAAM,MAAM,GAAG,GAAG;AAC3B;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../../src/lib/string.ts"],"names":[],"mappings":"AAAA,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIzD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI1D"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function stripLeadingSlashes(value) {
|
|
2
|
+
let start = 0;
|
|
3
|
+
while (start < value.length && value[start] === "/") start++;
|
|
4
|
+
return value.slice(start);
|
|
5
|
+
}
|
|
6
|
+
function stripTrailingSlashes(value) {
|
|
7
|
+
let end = value.length;
|
|
8
|
+
while (end > 0 && value[end - 1] === "/") end--;
|
|
9
|
+
return value.slice(0, end);
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
stripLeadingSlashes,
|
|
13
|
+
stripTrailingSlashes
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=string.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"string.js","sources":["../../src/lib/string.ts"],"sourcesContent":["export function stripLeadingSlashes(value: string): string {\n let start = 0;\n while (start < value.length && value[start] === \"/\") start++;\n return value.slice(start);\n}\n\nexport function stripTrailingSlashes(value: string): string {\n let end = value.length;\n while (end > 0 && value[end - 1] === \"/\") end--;\n return value.slice(0, end);\n}\n"],"names":[],"mappings":"AAAO,SAAS,oBAAoB,OAAuB;AACzD,MAAI,QAAQ;AACZ,SAAO,QAAQ,MAAM,UAAU,MAAM,KAAK,MAAM,IAAK;AACrD,SAAO,MAAM,MAAM,KAAK;AAC1B;AAEO,SAAS,qBAAqB,OAAuB;AAC1D,MAAI,MAAM,MAAM;AAChB,SAAO,MAAM,KAAK,MAAM,MAAM,CAAC,MAAM,IAAK;AAC1C,SAAO,MAAM,MAAM,GAAG,GAAG;AAC3B;"}
|
|
@@ -7,7 +7,9 @@ const Icon = require("../data/Icon.cjs");
|
|
|
7
7
|
const Modal = require("../overlay/Modal.cjs");
|
|
8
8
|
const CommandForm = require("./CommandForm.cjs");
|
|
9
9
|
const CommandOutput = require("./CommandOutput.cjs");
|
|
10
|
+
const commandFormUtils = require("./command-form-utils.cjs");
|
|
10
11
|
const InlineError = require("./InlineError.cjs");
|
|
12
|
+
const rowNavigation = require("./rowNavigation.cjs");
|
|
11
13
|
const UiPlay = require("../icons/components/UiPlay.cjs");
|
|
12
14
|
function OperationActionDialog({
|
|
13
15
|
operation,
|
|
@@ -66,8 +68,8 @@ function OperationActionDialog({
|
|
|
66
68
|
function hrefForOperationAction(path, params) {
|
|
67
69
|
const nextParams = { ...params };
|
|
68
70
|
const args = parseArgsParam(params.args);
|
|
69
|
-
let route = apiPathToRoutePath(path);
|
|
70
|
-
for (const [index, name] of pathParamNames(path).entries()) {
|
|
71
|
+
let route = rowNavigation.apiPathToRoutePath(path);
|
|
72
|
+
for (const [index, name] of commandFormUtils.pathParamNames(path).entries()) {
|
|
71
73
|
const value = nextParams[name] || args[index];
|
|
72
74
|
if (!value) return void 0;
|
|
73
75
|
route = route.replace(`:${name}`, encodeURIComponent(value));
|
|
@@ -83,14 +85,6 @@ function hrefForOperationAction(path, params) {
|
|
|
83
85
|
const query = search.toString();
|
|
84
86
|
return query ? `${route}?${query}` : route;
|
|
85
87
|
}
|
|
86
|
-
function apiPathToRoutePath(path) {
|
|
87
|
-
const cliPath = path.trim().replace(/^\/api\/v1\/?/, "").replace(/^\/+/, "").replace(/\/+$/, "");
|
|
88
|
-
if (!cliPath) return "/";
|
|
89
|
-
return `/${cliPath.replace(/\{([^}]+)\}/g, ":$1")}`;
|
|
90
|
-
}
|
|
91
|
-
function pathParamNames(path) {
|
|
92
|
-
return [...path.matchAll(/\{([^}]+)\}/g)].map((match) => match[1]).filter((name) => Boolean(name));
|
|
93
|
-
}
|
|
94
88
|
function parseArgsParam(value) {
|
|
95
89
|
if (!value) return [];
|
|
96
90
|
const trimmed = value.trim();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OperationActionDialog.cjs","sources":["../../src/rpc/OperationActionDialog.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { Button } from \"../components/button\";\nimport { Icon } from \"../data/Icon\";\nimport { UiPlay } from \"../icons\";\nimport { Modal } from \"../overlay/Modal\";\nimport { CommandForm } from \"./CommandForm\";\nimport { CommandOutput } from \"./CommandOutput\";\nimport { InlineError } from \"./InlineError\";\nimport type { ExecutionResponse, ResolvedOperation } from \"./types\";\nimport type { OperationsApiClient } from \"./useOperations\";\n\nexport type OperationActionDialogProps = {\n operation: ResolvedOperation;\n client: OperationsApiClient;\n initialValues: Record<string, string>;\n label: string;\n defaultAccept?: string;\n onNavigateAction?: (href: string) => void;\n};\n\nexport function OperationActionDialog({\n operation,\n client,\n initialValues,\n label,\n defaultAccept = \"application/clicky+json\",\n onNavigateAction,\n}: OperationActionDialogProps) {\n const [open, setOpen] = useState(false);\n const [isExecuting, setIsExecuting] = useState(false);\n const [response, setResponse] = useState<ExecutionResponse | null>(null);\n const [error, setError] = useState<unknown>(null);\n\n async function handleExecute(params: Record<string, string>, headers: Record<string, string>) {\n if (onNavigateAction) {\n const href = hrefForOperationAction(operation.path, params);\n if (!href) return;\n const separator = href.includes(\"?\") ? \"&\" : \"?\";\n onNavigateAction(`${href}${separator}autoRun=1`);\n return;\n }\n\n setIsExecuting(true);\n setError(null);\n setResponse(null);\n try {\n const result = await client.executeCommand(operation.path, operation.method, params, headers);\n setResponse(result);\n } catch (err) {\n setError(err);\n } finally {\n setIsExecuting(false);\n }\n }\n\n return (\n <>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setOpen(true)}>\n <Icon icon={UiPlay} />\n {label}\n </Button>\n <Modal open={open} onClose={() => setOpen(false)} title={label} size=\"lg\">\n <div className=\"space-y-4\">\n <CommandForm\n parameters={operation.operation.parameters ?? []}\n onExecute={handleExecute}\n isPending={isExecuting}\n method={operation.method}\n path={operation.path}\n accept={defaultAccept}\n initialValues={initialValues}\n />\n\n {error ? (\n <InlineError title={`Failed to execute ${operation.path}`} error={error} />\n ) : response ? (\n <CommandOutput response={response} />\n ) : null}\n </div>\n </Modal>\n </>\n );\n}\n\nfunction hrefForOperationAction(path: string, params: Record<string, string>): string | undefined {\n const nextParams = { ...params };\n const args = parseArgsParam(params.args);\n let route = apiPathToRoutePath(path);\n\n for (const [index, name] of pathParamNames(path).entries()) {\n const value = nextParams[name] || args[index];\n if (!value) return undefined;\n route = route.replace(`:${name}`, encodeURIComponent(value));\n delete nextParams[name];\n if (!nextParams[name] && value === args[index]) {\n delete nextParams.args;\n }\n }\n\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(nextParams)) {\n if (value && key !== \"autoRun\" && key !== \"__autoRun\") search.set(key, value);\n }\n const query = search.toString();\n return query ? `${route}?${query}` : route;\n}\n\nfunction
|
|
1
|
+
{"version":3,"file":"OperationActionDialog.cjs","sources":["../../src/rpc/OperationActionDialog.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { Button } from \"../components/button\";\nimport { Icon } from \"../data/Icon\";\nimport { UiPlay } from \"../icons\";\nimport { Modal } from \"../overlay/Modal\";\nimport { CommandForm } from \"./CommandForm\";\nimport { CommandOutput } from \"./CommandOutput\";\nimport { pathParamNames } from \"./command-form-utils\";\nimport { InlineError } from \"./InlineError\";\nimport { apiPathToRoutePath } from \"./rowNavigation\";\nimport type { ExecutionResponse, ResolvedOperation } from \"./types\";\nimport type { OperationsApiClient } from \"./useOperations\";\n\nexport type OperationActionDialogProps = {\n operation: ResolvedOperation;\n client: OperationsApiClient;\n initialValues: Record<string, string>;\n label: string;\n defaultAccept?: string;\n onNavigateAction?: (href: string) => void;\n};\n\nexport function OperationActionDialog({\n operation,\n client,\n initialValues,\n label,\n defaultAccept = \"application/clicky+json\",\n onNavigateAction,\n}: OperationActionDialogProps) {\n const [open, setOpen] = useState(false);\n const [isExecuting, setIsExecuting] = useState(false);\n const [response, setResponse] = useState<ExecutionResponse | null>(null);\n const [error, setError] = useState<unknown>(null);\n\n async function handleExecute(params: Record<string, string>, headers: Record<string, string>) {\n if (onNavigateAction) {\n const href = hrefForOperationAction(operation.path, params);\n if (!href) return;\n const separator = href.includes(\"?\") ? \"&\" : \"?\";\n onNavigateAction(`${href}${separator}autoRun=1`);\n return;\n }\n\n setIsExecuting(true);\n setError(null);\n setResponse(null);\n try {\n const result = await client.executeCommand(operation.path, operation.method, params, headers);\n setResponse(result);\n } catch (err) {\n setError(err);\n } finally {\n setIsExecuting(false);\n }\n }\n\n return (\n <>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setOpen(true)}>\n <Icon icon={UiPlay} />\n {label}\n </Button>\n <Modal open={open} onClose={() => setOpen(false)} title={label} size=\"lg\">\n <div className=\"space-y-4\">\n <CommandForm\n parameters={operation.operation.parameters ?? []}\n onExecute={handleExecute}\n isPending={isExecuting}\n method={operation.method}\n path={operation.path}\n accept={defaultAccept}\n initialValues={initialValues}\n />\n\n {error ? (\n <InlineError title={`Failed to execute ${operation.path}`} error={error} />\n ) : response ? (\n <CommandOutput response={response} />\n ) : null}\n </div>\n </Modal>\n </>\n );\n}\n\nfunction hrefForOperationAction(path: string, params: Record<string, string>): string | undefined {\n const nextParams = { ...params };\n const args = parseArgsParam(params.args);\n let route = apiPathToRoutePath(path);\n\n for (const [index, name] of pathParamNames(path).entries()) {\n const value = nextParams[name] || args[index];\n if (!value) return undefined;\n route = route.replace(`:${name}`, encodeURIComponent(value));\n delete nextParams[name];\n if (!nextParams[name] && value === args[index]) {\n delete nextParams.args;\n }\n }\n\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(nextParams)) {\n if (value && key !== \"autoRun\" && key !== \"__autoRun\") search.set(key, value);\n }\n const query = search.toString();\n return query ? `${route}?${query}` : route;\n}\n\nfunction parseArgsParam(value: string | undefined): string[] {\n if (!value) return [];\n const trimmed = value.trim();\n if (!trimmed || trimmed === \"[]\" || trimmed.toLowerCase() === \"null\") return [];\n try {\n const parsed = JSON.parse(trimmed);\n if (Array.isArray(parsed)) return parsed.map(String).filter(Boolean);\n } catch {\n // Fall back to comma-delimited args below.\n }\n return trimmed\n .split(\",\")\n .map((part) => part.trim())\n .filter(Boolean);\n}\n"],"names":["useState","jsxs","Fragment","Button","jsx","Icon","UiPlay","Modal","CommandForm","InlineError","CommandOutput","apiPathToRoutePath","pathParamNames"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OperationActionDialog.d.ts","sourceRoot":"","sources":["../../src/rpc/OperationActionDialog.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"OperationActionDialog.d.ts","sourceRoot":"","sources":["../../src/rpc/OperationActionDialog.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAqB,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3D,MAAM,MAAM,0BAA0B,GAAG;IACvC,SAAS,EAAE,iBAAiB,CAAC;IAC7B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,MAAM,EACN,aAAa,EACb,KAAK,EACL,aAAyC,EACzC,gBAAgB,GACjB,EAAE,0BAA0B,2CAuD5B"}
|
|
@@ -5,7 +5,9 @@ import { Icon } from "../data/Icon.js";
|
|
|
5
5
|
import { Modal } from "../overlay/Modal.js";
|
|
6
6
|
import { CommandForm } from "./CommandForm.js";
|
|
7
7
|
import { CommandOutput } from "./CommandOutput.js";
|
|
8
|
+
import { pathParamNames } from "./command-form-utils.js";
|
|
8
9
|
import { InlineError } from "./InlineError.js";
|
|
10
|
+
import { apiPathToRoutePath } from "./rowNavigation.js";
|
|
9
11
|
import { UiPlay } from "../icons/components/UiPlay.js";
|
|
10
12
|
function OperationActionDialog({
|
|
11
13
|
operation,
|
|
@@ -81,14 +83,6 @@ function hrefForOperationAction(path, params) {
|
|
|
81
83
|
const query = search.toString();
|
|
82
84
|
return query ? `${route}?${query}` : route;
|
|
83
85
|
}
|
|
84
|
-
function apiPathToRoutePath(path) {
|
|
85
|
-
const cliPath = path.trim().replace(/^\/api\/v1\/?/, "").replace(/^\/+/, "").replace(/\/+$/, "");
|
|
86
|
-
if (!cliPath) return "/";
|
|
87
|
-
return `/${cliPath.replace(/\{([^}]+)\}/g, ":$1")}`;
|
|
88
|
-
}
|
|
89
|
-
function pathParamNames(path) {
|
|
90
|
-
return [...path.matchAll(/\{([^}]+)\}/g)].map((match) => match[1]).filter((name) => Boolean(name));
|
|
91
|
-
}
|
|
92
86
|
function parseArgsParam(value) {
|
|
93
87
|
if (!value) return [];
|
|
94
88
|
const trimmed = value.trim();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OperationActionDialog.js","sources":["../../src/rpc/OperationActionDialog.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { Button } from \"../components/button\";\nimport { Icon } from \"../data/Icon\";\nimport { UiPlay } from \"../icons\";\nimport { Modal } from \"../overlay/Modal\";\nimport { CommandForm } from \"./CommandForm\";\nimport { CommandOutput } from \"./CommandOutput\";\nimport { InlineError } from \"./InlineError\";\nimport type { ExecutionResponse, ResolvedOperation } from \"./types\";\nimport type { OperationsApiClient } from \"./useOperations\";\n\nexport type OperationActionDialogProps = {\n operation: ResolvedOperation;\n client: OperationsApiClient;\n initialValues: Record<string, string>;\n label: string;\n defaultAccept?: string;\n onNavigateAction?: (href: string) => void;\n};\n\nexport function OperationActionDialog({\n operation,\n client,\n initialValues,\n label,\n defaultAccept = \"application/clicky+json\",\n onNavigateAction,\n}: OperationActionDialogProps) {\n const [open, setOpen] = useState(false);\n const [isExecuting, setIsExecuting] = useState(false);\n const [response, setResponse] = useState<ExecutionResponse | null>(null);\n const [error, setError] = useState<unknown>(null);\n\n async function handleExecute(params: Record<string, string>, headers: Record<string, string>) {\n if (onNavigateAction) {\n const href = hrefForOperationAction(operation.path, params);\n if (!href) return;\n const separator = href.includes(\"?\") ? \"&\" : \"?\";\n onNavigateAction(`${href}${separator}autoRun=1`);\n return;\n }\n\n setIsExecuting(true);\n setError(null);\n setResponse(null);\n try {\n const result = await client.executeCommand(operation.path, operation.method, params, headers);\n setResponse(result);\n } catch (err) {\n setError(err);\n } finally {\n setIsExecuting(false);\n }\n }\n\n return (\n <>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setOpen(true)}>\n <Icon icon={UiPlay} />\n {label}\n </Button>\n <Modal open={open} onClose={() => setOpen(false)} title={label} size=\"lg\">\n <div className=\"space-y-4\">\n <CommandForm\n parameters={operation.operation.parameters ?? []}\n onExecute={handleExecute}\n isPending={isExecuting}\n method={operation.method}\n path={operation.path}\n accept={defaultAccept}\n initialValues={initialValues}\n />\n\n {error ? (\n <InlineError title={`Failed to execute ${operation.path}`} error={error} />\n ) : response ? (\n <CommandOutput response={response} />\n ) : null}\n </div>\n </Modal>\n </>\n );\n}\n\nfunction hrefForOperationAction(path: string, params: Record<string, string>): string | undefined {\n const nextParams = { ...params };\n const args = parseArgsParam(params.args);\n let route = apiPathToRoutePath(path);\n\n for (const [index, name] of pathParamNames(path).entries()) {\n const value = nextParams[name] || args[index];\n if (!value) return undefined;\n route = route.replace(`:${name}`, encodeURIComponent(value));\n delete nextParams[name];\n if (!nextParams[name] && value === args[index]) {\n delete nextParams.args;\n }\n }\n\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(nextParams)) {\n if (value && key !== \"autoRun\" && key !== \"__autoRun\") search.set(key, value);\n }\n const query = search.toString();\n return query ? `${route}?${query}` : route;\n}\n\nfunction
|
|
1
|
+
{"version":3,"file":"OperationActionDialog.js","sources":["../../src/rpc/OperationActionDialog.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { Button } from \"../components/button\";\nimport { Icon } from \"../data/Icon\";\nimport { UiPlay } from \"../icons\";\nimport { Modal } from \"../overlay/Modal\";\nimport { CommandForm } from \"./CommandForm\";\nimport { CommandOutput } from \"./CommandOutput\";\nimport { pathParamNames } from \"./command-form-utils\";\nimport { InlineError } from \"./InlineError\";\nimport { apiPathToRoutePath } from \"./rowNavigation\";\nimport type { ExecutionResponse, ResolvedOperation } from \"./types\";\nimport type { OperationsApiClient } from \"./useOperations\";\n\nexport type OperationActionDialogProps = {\n operation: ResolvedOperation;\n client: OperationsApiClient;\n initialValues: Record<string, string>;\n label: string;\n defaultAccept?: string;\n onNavigateAction?: (href: string) => void;\n};\n\nexport function OperationActionDialog({\n operation,\n client,\n initialValues,\n label,\n defaultAccept = \"application/clicky+json\",\n onNavigateAction,\n}: OperationActionDialogProps) {\n const [open, setOpen] = useState(false);\n const [isExecuting, setIsExecuting] = useState(false);\n const [response, setResponse] = useState<ExecutionResponse | null>(null);\n const [error, setError] = useState<unknown>(null);\n\n async function handleExecute(params: Record<string, string>, headers: Record<string, string>) {\n if (onNavigateAction) {\n const href = hrefForOperationAction(operation.path, params);\n if (!href) return;\n const separator = href.includes(\"?\") ? \"&\" : \"?\";\n onNavigateAction(`${href}${separator}autoRun=1`);\n return;\n }\n\n setIsExecuting(true);\n setError(null);\n setResponse(null);\n try {\n const result = await client.executeCommand(operation.path, operation.method, params, headers);\n setResponse(result);\n } catch (err) {\n setError(err);\n } finally {\n setIsExecuting(false);\n }\n }\n\n return (\n <>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setOpen(true)}>\n <Icon icon={UiPlay} />\n {label}\n </Button>\n <Modal open={open} onClose={() => setOpen(false)} title={label} size=\"lg\">\n <div className=\"space-y-4\">\n <CommandForm\n parameters={operation.operation.parameters ?? []}\n onExecute={handleExecute}\n isPending={isExecuting}\n method={operation.method}\n path={operation.path}\n accept={defaultAccept}\n initialValues={initialValues}\n />\n\n {error ? (\n <InlineError title={`Failed to execute ${operation.path}`} error={error} />\n ) : response ? (\n <CommandOutput response={response} />\n ) : null}\n </div>\n </Modal>\n </>\n );\n}\n\nfunction hrefForOperationAction(path: string, params: Record<string, string>): string | undefined {\n const nextParams = { ...params };\n const args = parseArgsParam(params.args);\n let route = apiPathToRoutePath(path);\n\n for (const [index, name] of pathParamNames(path).entries()) {\n const value = nextParams[name] || args[index];\n if (!value) return undefined;\n route = route.replace(`:${name}`, encodeURIComponent(value));\n delete nextParams[name];\n if (!nextParams[name] && value === args[index]) {\n delete nextParams.args;\n }\n }\n\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(nextParams)) {\n if (value && key !== \"autoRun\" && key !== \"__autoRun\") search.set(key, value);\n }\n const query = search.toString();\n return query ? `${route}?${query}` : route;\n}\n\nfunction parseArgsParam(value: string | undefined): string[] {\n if (!value) return [];\n const trimmed = value.trim();\n if (!trimmed || trimmed === \"[]\" || trimmed.toLowerCase() === \"null\") return [];\n try {\n const parsed = JSON.parse(trimmed);\n if (Array.isArray(parsed)) return parsed.map(String).filter(Boolean);\n } catch {\n // Fall back to comma-delimited args below.\n }\n return trimmed\n .split(\",\")\n .map((part) => part.trim())\n .filter(Boolean);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ const jsxRuntime = require("react/jsx-runtime");
|
|
|
4
4
|
const react = require("react");
|
|
5
5
|
const reactQuery = require("@tanstack/react-query");
|
|
6
6
|
const MethodBadge = require("../data/MethodBadge.cjs");
|
|
7
|
+
const string = require("../lib/string.cjs");
|
|
7
8
|
const CommandForm = require("./CommandForm.cjs");
|
|
8
9
|
const commandFormUtils = require("./command-form-utils.cjs");
|
|
9
10
|
const formMetadata = require("./formMetadata.cjs");
|
|
@@ -301,7 +302,7 @@ function OperationCommandPage({
|
|
|
301
302
|
function findRelatedOperations(current, operations, pathValues) {
|
|
302
303
|
if (current.method.toUpperCase() !== "GET") return [];
|
|
303
304
|
if (!pathTemplateSatisfied(current.path, pathValues)) return [];
|
|
304
|
-
const basePath = current.path
|
|
305
|
+
const basePath = string.stripTrailingSlashes(current.path);
|
|
305
306
|
return operations.filter((candidate) => {
|
|
306
307
|
if (candidate === current) return false;
|
|
307
308
|
if (!candidate.path.startsWith(`${basePath}/`)) return false;
|
|
@@ -322,7 +323,7 @@ function findRelatedOperations(current, operations, pathValues) {
|
|
|
322
323
|
}
|
|
323
324
|
function findDetailOperation(current, operations) {
|
|
324
325
|
const method = current.method.toUpperCase();
|
|
325
|
-
const detailPath = `${current.path
|
|
326
|
+
const detailPath = `${string.stripTrailingSlashes(current.path)}/{id}`;
|
|
326
327
|
return operations.find(
|
|
327
328
|
(candidate) => {
|
|
328
329
|
var _a;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OperationCommandPage.cjs","sources":["../../src/rpc/OperationCommandPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { ClickyCommandRuntime } from \"../data/Clicky\";\nimport { MethodBadge } from \"../data/MethodBadge\";\nimport { CommandForm } from \"./CommandForm\";\nimport { pathParamNames, submitValue } from \"./command-form-utils\";\nimport type { RenderLink } from \"./EndpointList\";\nimport {\n buildInitialParameterValues,\n dataTablePaginationFromForm,\n packParameterValues,\n parametersToFormConfig,\n pruneParameterValues,\n titleCase,\n useDebouncedRecord,\n type ParameterValues,\n} from \"./formMetadata\";\nimport { InlineError } from \"./InlineError\";\nimport { OperationActionDialog } from \"./OperationActionDialog\";\nimport { OperationResultView } from \"./OperationResultView\";\nimport { hrefForOperation } from \"./rowNavigation\";\nimport type {\n ExecutionResponse,\n OpenAPIParameter,\n ResolvedOperation,\n} from \"./types\";\nimport { useOperationById, type OperationsApiClient } from \"./useOperations\";\n\n// All operation results are fetched as clicky documents; the in-result View\n// menu re-fetches other formats on demand via the response's requestUrl.\nconst RESULT_ACCEPT = \"application/clicky+json\";\n\nexport type OperationCommandPageProps = {\n client: OperationsApiClient;\n operationId?: string;\n operation?: ResolvedOperation;\n operations?: ResolvedOperation[];\n initialValues?: ParameterValues;\n autoRun?: boolean;\n backHref?: string;\n backLabel?: string;\n renderLink?: RenderLink;\n commandRuntime?: ClickyCommandRuntime;\n onNavigate?: (href: string) => void;\n onResult?: (\n response: ExecutionResponse,\n operation: ResolvedOperation,\n values: ParameterValues,\n ) => void;\n hideLockedPathFilters?: boolean;\n className?: string;\n};\n\nconst EMPTY_PARAMETER_VALUES: ParameterValues = {};\n\nexport function OperationCommandPage({\n client,\n operationId,\n operation: providedOperation,\n operations = providedOperation ? [providedOperation] : [],\n initialValues = EMPTY_PARAMETER_VALUES,\n autoRun,\n backHref,\n backLabel = \"Back\",\n renderLink,\n onNavigate,\n onResult,\n commandRuntime,\n hideLockedPathFilters = Boolean(providedOperation),\n className,\n}: OperationCommandPageProps) {\n const lookup = useOperationById(\n client,\n providedOperation ? undefined : operationId,\n );\n const operation = providedOperation ?? lookup.operation;\n const isLoading = providedOperation ? false : lookup.isLoading;\n const [isExecuting, setIsExecuting] = useState(false);\n const [result, setResult] = useState<ExecutionResponse | null>(null);\n const [error, setError] = useState<unknown>(null);\n const [hasAutoRun, setHasAutoRun] = useState(false);\n const parameters = operation?.operation.parameters ?? [];\n const isGet = (operation?.method ?? \"\").toUpperCase() === \"GET\";\n const effectiveAutoRun = operation ? (autoRun ?? isGet) : false;\n const parameterSignature = JSON.stringify(\n parameters.map((param) => ({\n name: param.name,\n in: param.in,\n required: param.required ?? false,\n default: param.schema?.default ?? null,\n })),\n );\n const operationKey = `${operation?.method ?? \"\"}:${operation?.path ?? \"\"}:${operation?.operation.operationId ?? \"\"}`;\n const effectiveInitialValues = useMemo(\n () =>\n operation\n ? buildInitialParameterValues(\n parameters,\n operation.method,\n {},\n {\n ...readQueryParameterValuesFromUrl(parameters),\n ...stripRunnerParams(initialValues),\n },\n )\n : stripRunnerParams(initialValues),\n [initialValues, operation?.method, parameterSignature],\n );\n const pathParameters = parameters.filter((param) => param.in === \"path\");\n const lockedPathValues = useMemo<ParameterValues>(() => {\n const values: ParameterValues = {};\n for (const param of pathParameters) {\n const value = effectiveInitialValues[param.name];\n if (typeof value === \"string\" && value.trim() !== \"\") {\n values[param.name] = value;\n }\n }\n return values;\n }, [effectiveInitialValues, pathParameters]);\n const detailOperation = useMemo(\n () => (operation ? findDetailOperation(operation, operations) : undefined),\n [operation, operations],\n );\n const relatedOperations = useMemo(\n () =>\n operation\n ? findRelatedOperations(operation, operations, lockedPathValues)\n : [],\n [lockedPathValues, operation, operations],\n );\n\n // GET-mode parameter state: filter values + pagination cursor are driven\n // by the page so they can flow natively into the result table's in-table\n // FilterBar and pagination footer (via OperationResultView's filterConfig).\n const [values, setValues] = useState<ParameterValues>(effectiveInitialValues);\n useEffect(() => {\n setValues(effectiveInitialValues);\n }, [effectiveInitialValues]);\n const debouncedValues = useDebouncedRecord(values, 250);\n\n useEffect(() => {\n if (!isGet || !operation) return;\n writeQueryParameterValuesToUrl(debouncedValues, parameters);\n }, [isGet, operationKey, debouncedValues, parameterSignature]);\n\n const lookupQuery = useQuery({\n queryKey: [\n \"operation-query-lookup\",\n operation?.method,\n operation?.path,\n debouncedValues,\n ],\n queryFn: async () => {\n if (!operation) return { filters: {} };\n return (\n (await client.lookupFilters?.(\n operation.path,\n operation.method,\n packParameterValues(debouncedValues, parameters),\n { Accept: \"application/json+clicky\" },\n )) ?? { filters: {} }\n );\n },\n enabled:\n isGet &&\n !!operation &&\n !!client.lookupFilters &&\n parameters.some((param) => param.in === \"query\"),\n staleTime: 30_000,\n retry: 0,\n });\n\n const formConfig = useMemo(() => {\n if (!isGet) return { filters: [] };\n return parametersToFormConfig(parameters, values, setValues, {\n lookup: lookupQuery.data,\n lockedValues: lockedPathValues,\n hideLocked: hideLockedPathFilters,\n });\n }, [\n isGet,\n parameters,\n values,\n lookupQuery.data,\n lockedPathValues,\n hideLockedPathFilters,\n ]);\n\n const dataTablePagination = useMemo(\n () => dataTablePaginationFromForm(formConfig.pagination, result),\n [formConfig.pagination, result],\n );\n\n // Ref tracking the last submitted parameter signature so the\n // auto-submit-on-debounced-change effect coordinates against the same\n // \"have I already fired this set of values\" check.\n const lastSubmittedSignature = useRef(\"\");\n\n async function executeOperation(values: ParameterValues) {\n if (!operation) return;\n\n setIsExecuting(true);\n setError(null);\n\n try {\n const response = await client.executeCommand(\n operation.path,\n operation.method,\n packParameterValues(values, operation.operation.parameters ?? []),\n { Accept: RESULT_ACCEPT },\n );\n setResult(response);\n onResult?.(response, operation, values);\n } catch (err) {\n setResult(null);\n setError(err);\n } finally {\n setIsExecuting(false);\n }\n }\n\n useEffect(() => {\n setHasAutoRun(false);\n setResult(null);\n setError(null);\n lastSubmittedSignature.current = \"\";\n }, [effectiveAutoRun, operationKey]);\n\n useEffect(() => {\n if (!effectiveAutoRun || !operation || hasAutoRun) return;\n // Auto-run a GET as long as every required parameter has a value. Optional\n // params (limit/offset, filter chips, etc.) get their defaults; the\n // sidebar's \"click → instant table\" flow depends on this not bailing just\n // because the operation declares any parameters at all.\n const missingRequired = parameters.filter((param) => {\n if (!param.required) return false;\n return (effectiveInitialValues[param.name] ?? \"\").trim() === \"\";\n });\n if (missingRequired.length > 0) return;\n\n setHasAutoRun(true);\n lastSubmittedSignature.current = JSON.stringify(\n pruneParameterValues(effectiveInitialValues),\n );\n void executeOperation(effectiveInitialValues);\n }, [\n effectiveAutoRun,\n effectiveInitialValues,\n hasAutoRun,\n operationKey,\n parameterSignature,\n ]);\n\n // GET re-runs on debounced filter/pagination changes once the initial\n // auto-run has fired; non-GETs keep their explicit-submit behavior.\n useEffect(() => {\n if (!isGet || !operation || !hasAutoRun) return;\n const merged = { ...debouncedValues, ...lockedPathValues };\n const missingRequired = parameters.filter((param) => {\n if (!param.required) return false;\n return (merged[param.name] ?? \"\").trim() === \"\";\n });\n if (missingRequired.length > 0) return;\n const signature = JSON.stringify(pruneParameterValues(merged));\n if (lastSubmittedSignature.current === signature) return;\n lastSubmittedSignature.current = signature;\n void executeOperation(merged);\n }, [\n isGet,\n hasAutoRun,\n debouncedValues,\n lockedPathValues,\n parameterSignature,\n ]);\n\n const backLink =\n backHref == null ? null : renderLink ? (\n renderLink({\n to: backHref,\n className: \"text-sm text-primary underline-offset-4 hover:underline\",\n children: backLabel,\n })\n ) : (\n <a\n href={backHref}\n className=\"text-sm text-primary underline-offset-4 hover:underline\"\n >\n {backLabel}\n </a>\n );\n\n if (isLoading) {\n return (\n <div className=\"text-sm text-muted-foreground\">Loading operation...</div>\n );\n }\n\n if (!operation) {\n return (\n <div className=\"space-y-4\">\n <div className=\"text-sm text-muted-foreground\">\n Unknown operation: <code>{operationId}</code>\n </div>\n {backLink}\n </div>\n );\n }\n\n const { path, method, operation: op } = operation;\n\n return (\n <div className={className ?? \"min-w-0 flex-1 space-y-6 p-6\"}>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0 flex-1\">\n {backLink}\n <div className=\"flex items-center gap-3\">\n <MethodBadge method={method} />\n <h1 className=\"truncate text-xl font-bold\">\n {op.summary || op.operationId || path}\n </h1>\n </div>\n <p className=\"mt-1 font-mono text-xs text-muted-foreground\">{path}</p>\n {op.operationId && op.summary && (\n <p className=\"mt-2 font-mono text-xs text-muted-foreground\">\n {op.operationId}\n </p>\n )}\n {op.description && op.description !== op.summary && (\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {op.description}\n </p>\n )}\n </div>\n <div className=\"flex shrink-0 flex-col items-end gap-3\">\n {relatedOperations.length > 0 && (\n <div className=\"flex flex-wrap justify-end gap-2\">\n {relatedOperations.map((related) =>\n related.href ? (\n renderLink ? (\n renderLink({\n key: `${related.operation.method}:${related.operation.path}`,\n to: related.href,\n className:\n \"inline-flex h-8 items-center justify-center gap-2 rounded-md border border-input bg-background px-3 text-xs font-medium hover:bg-accent hover:text-accent-foreground\",\n children: related.label,\n })\n ) : (\n <a\n key={`${related.operation.method}:${related.operation.path}`}\n href={related.href}\n className=\"inline-flex h-8 items-center justify-center gap-2 rounded-md border border-input bg-background px-3 text-xs font-medium hover:bg-accent hover:text-accent-foreground\"\n >\n {related.label}\n </a>\n )\n ) : (\n <OperationActionDialog\n key={`${related.operation.method}:${related.operation.path}`}\n operation={related.operation}\n client={client}\n initialValues={lockedPathValues}\n label={related.label}\n defaultAccept={RESULT_ACCEPT}\n {...(onNavigate ? { onNavigateAction: onNavigate } : {})}\n />\n ),\n )}\n </div>\n )}\n </div>\n </div>\n\n {method.toUpperCase() !== \"GET\" && (\n <section className=\"space-y-3\">\n <div className=\"rounded-lg border p-4\">\n <CommandForm\n parameters={parameters}\n onExecute={(params) => executeOperation(params)}\n isPending={isExecuting}\n method={method}\n path={path}\n accept={RESULT_ACCEPT}\n initialValues={effectiveInitialValues}\n />\n </div>\n </section>\n )}\n\n {error ? (\n <InlineError title={`Failed to load ${path}`} error={error} />\n ) : isExecuting || result ? (\n <OperationResultView\n response={result}\n loading={isExecuting}\n loadingMessage=\"Loading execution results…\"\n ariaLabel=\"Response body\"\n detailOperation={detailOperation}\n {...(commandRuntime ? { commandRuntime } : {})}\n {...(isGet && effectiveAutoRun\n ? {\n filterConfig: {\n filters: formConfig.filters,\n ...(formConfig.timeRange\n ? { timeRange: formConfig.timeRange }\n : {}),\n },\n }\n : {})}\n {...(isGet && effectiveAutoRun && dataTablePagination\n ? { pagination: dataTablePagination }\n : {})}\n />\n ) : null}\n </div>\n );\n}\n\ntype RelatedOperation = {\n operation: ResolvedOperation;\n label: string;\n href?: string;\n};\n\nfunction findRelatedOperations(\n current: ResolvedOperation,\n operations: ResolvedOperation[],\n pathValues: Record<string, string>,\n): RelatedOperation[] {\n if (current.method.toUpperCase() !== \"GET\") return [];\n if (!pathTemplateSatisfied(current.path, pathValues)) return [];\n\n const basePath = current.path.replace(/\\/+$/, \"\");\n return operations\n .filter((candidate) => {\n if (candidate === current) return false;\n if (!candidate.path.startsWith(`${basePath}/`)) return false;\n if (!pathTemplateSatisfied(candidate.path, pathValues)) return false;\n const method = candidate.method.toUpperCase();\n return (\n method === \"GET\" ||\n method === \"POST\" ||\n method === \"PUT\" ||\n method === \"DELETE\"\n );\n })\n .map((related) => {\n const method = related.method.toUpperCase();\n const href =\n method === \"GET\"\n ? hrefForOperation(related, [], pathValues)\n : undefined;\n return {\n operation: related,\n label: operationLabel(related),\n ...(href ? { href } : {}),\n };\n })\n .filter(\n (related) =>\n related.operation.method.toUpperCase() !== \"GET\" || related.href,\n );\n}\n\nfunction findDetailOperation(\n current: ResolvedOperation,\n operations: ResolvedOperation[],\n) {\n const method = current.method.toUpperCase();\n const detailPath = `${current.path.replace(/\\/+$/, \"\")}/{id}`;\n return operations.find(\n (candidate) =>\n candidate.method.toUpperCase() === method &&\n candidate.path === detailPath &&\n candidate.operation.parameters?.some(\n (param) => param.in === \"path\" && param.name === \"id\" && param.required,\n ),\n );\n}\n\nfunction pathTemplateSatisfied(path: string, values: Record<string, string>) {\n return pathParamNames(path).every((name) => Boolean(values[name]));\n}\n\nfunction operationLabel(operation: ResolvedOperation): string {\n const actionName =\n operation.operation[\"x-clicky\"]?.actionName ||\n operation.path.split(\"/\").filter(Boolean).at(-1) ||\n operation.operation.operationId ||\n operation.method;\n return titleCase(actionName.replace(/[_-]+/g, \" \"));\n}\n\nfunction stripRunnerParams(values: ParameterValues): ParameterValues {\n const next: ParameterValues = {};\n for (const [key, value] of Object.entries(values)) {\n if (key === \"autoRun\" || key.startsWith(\"__\")) continue;\n next[key] = value;\n }\n return next;\n}\n\nfunction readQueryParameterValuesFromUrl(\n parameters: OpenAPIParameter[],\n): ParameterValues {\n if (typeof window === \"undefined\") return {};\n const queryParamNames = new Set(\n parameters.filter((param) => param.in === \"query\").map((p) => p.name),\n );\n if (queryParamNames.size === 0) return {};\n\n const values: ParameterValues = {};\n const search = new URLSearchParams(window.location.search);\n for (const name of queryParamNames) {\n const value = search.get(name);\n if (value != null && value !== \"\") {\n values[name] = value;\n }\n }\n return values;\n}\n\nfunction writeQueryParameterValuesToUrl(\n values: ParameterValues,\n parameters: OpenAPIParameter[],\n) {\n if (typeof window === \"undefined\") return;\n const queryParameters = parameters.filter((param) => param.in === \"query\");\n if (queryParameters.length === 0) return;\n\n const search = new URLSearchParams(window.location.search);\n for (const param of queryParameters) {\n const value = submitValue(param, values[param.name]);\n if (value == null) {\n search.delete(param.name);\n } else {\n search.set(param.name, value);\n }\n }\n\n const query = search.toString();\n const next = `${window.location.pathname}${query ? `?${query}` : \"\"}${window.location.hash}`;\n const current = `${window.location.pathname}${window.location.search}${window.location.hash}`;\n if (next !== current) {\n window.history.replaceState(window.history.state, \"\", next);\n }\n}\n"],"names":["useOperationById","useState","useMemo","buildInitialParameterValues","values","useEffect","useDebouncedRecord","useQuery","packParameterValues","parametersToFormConfig","dataTablePaginationFromForm","useRef","pruneParameterValues","jsx","jsxs","MethodBadge","OperationActionDialog","CommandForm","InlineError","OperationResultView","hrefForOperation","pathParamNames","titleCase","submitValue"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OperationCommandPage.cjs","sources":["../../src/rpc/OperationCommandPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { ClickyCommandRuntime } from \"../data/Clicky\";\nimport { MethodBadge } from \"../data/MethodBadge\";\nimport { stripTrailingSlashes } from \"../lib/string\";\nimport { CommandForm } from \"./CommandForm\";\nimport { pathParamNames, submitValue } from \"./command-form-utils\";\nimport type { RenderLink } from \"./EndpointList\";\nimport {\n buildInitialParameterValues,\n dataTablePaginationFromForm,\n packParameterValues,\n parametersToFormConfig,\n pruneParameterValues,\n titleCase,\n useDebouncedRecord,\n type ParameterValues,\n} from \"./formMetadata\";\nimport { InlineError } from \"./InlineError\";\nimport { OperationActionDialog } from \"./OperationActionDialog\";\nimport { OperationResultView } from \"./OperationResultView\";\nimport { hrefForOperation } from \"./rowNavigation\";\nimport type {\n ExecutionResponse,\n OpenAPIParameter,\n ResolvedOperation,\n} from \"./types\";\nimport { useOperationById, type OperationsApiClient } from \"./useOperations\";\n\n// All operation results are fetched as clicky documents; the in-result View\n// menu re-fetches other formats on demand via the response's requestUrl.\nconst RESULT_ACCEPT = \"application/clicky+json\";\n\nexport type OperationCommandPageProps = {\n client: OperationsApiClient;\n operationId?: string;\n operation?: ResolvedOperation;\n operations?: ResolvedOperation[];\n initialValues?: ParameterValues;\n autoRun?: boolean;\n backHref?: string;\n backLabel?: string;\n renderLink?: RenderLink;\n commandRuntime?: ClickyCommandRuntime;\n onNavigate?: (href: string) => void;\n onResult?: (\n response: ExecutionResponse,\n operation: ResolvedOperation,\n values: ParameterValues,\n ) => void;\n hideLockedPathFilters?: boolean;\n className?: string;\n};\n\nconst EMPTY_PARAMETER_VALUES: ParameterValues = {};\n\nexport function OperationCommandPage({\n client,\n operationId,\n operation: providedOperation,\n operations = providedOperation ? [providedOperation] : [],\n initialValues = EMPTY_PARAMETER_VALUES,\n autoRun,\n backHref,\n backLabel = \"Back\",\n renderLink,\n onNavigate,\n onResult,\n commandRuntime,\n hideLockedPathFilters = Boolean(providedOperation),\n className,\n}: OperationCommandPageProps) {\n const lookup = useOperationById(\n client,\n providedOperation ? undefined : operationId,\n );\n const operation = providedOperation ?? lookup.operation;\n const isLoading = providedOperation ? false : lookup.isLoading;\n const [isExecuting, setIsExecuting] = useState(false);\n const [result, setResult] = useState<ExecutionResponse | null>(null);\n const [error, setError] = useState<unknown>(null);\n const [hasAutoRun, setHasAutoRun] = useState(false);\n const parameters = operation?.operation.parameters ?? [];\n const isGet = (operation?.method ?? \"\").toUpperCase() === \"GET\";\n const effectiveAutoRun = operation ? (autoRun ?? isGet) : false;\n const parameterSignature = JSON.stringify(\n parameters.map((param) => ({\n name: param.name,\n in: param.in,\n required: param.required ?? false,\n default: param.schema?.default ?? null,\n })),\n );\n const operationKey = `${operation?.method ?? \"\"}:${operation?.path ?? \"\"}:${operation?.operation.operationId ?? \"\"}`;\n const effectiveInitialValues = useMemo(\n () =>\n operation\n ? buildInitialParameterValues(\n parameters,\n operation.method,\n {},\n {\n ...readQueryParameterValuesFromUrl(parameters),\n ...stripRunnerParams(initialValues),\n },\n )\n : stripRunnerParams(initialValues),\n [initialValues, operation?.method, parameterSignature],\n );\n const pathParameters = parameters.filter((param) => param.in === \"path\");\n const lockedPathValues = useMemo<ParameterValues>(() => {\n const values: ParameterValues = {};\n for (const param of pathParameters) {\n const value = effectiveInitialValues[param.name];\n if (typeof value === \"string\" && value.trim() !== \"\") {\n values[param.name] = value;\n }\n }\n return values;\n }, [effectiveInitialValues, pathParameters]);\n const detailOperation = useMemo(\n () => (operation ? findDetailOperation(operation, operations) : undefined),\n [operation, operations],\n );\n const relatedOperations = useMemo(\n () =>\n operation\n ? findRelatedOperations(operation, operations, lockedPathValues)\n : [],\n [lockedPathValues, operation, operations],\n );\n\n // GET-mode parameter state: filter values + pagination cursor are driven\n // by the page so they can flow natively into the result table's in-table\n // FilterBar and pagination footer (via OperationResultView's filterConfig).\n const [values, setValues] = useState<ParameterValues>(effectiveInitialValues);\n useEffect(() => {\n setValues(effectiveInitialValues);\n }, [effectiveInitialValues]);\n const debouncedValues = useDebouncedRecord(values, 250);\n\n useEffect(() => {\n if (!isGet || !operation) return;\n writeQueryParameterValuesToUrl(debouncedValues, parameters);\n }, [isGet, operationKey, debouncedValues, parameterSignature]);\n\n const lookupQuery = useQuery({\n queryKey: [\n \"operation-query-lookup\",\n operation?.method,\n operation?.path,\n debouncedValues,\n ],\n queryFn: async () => {\n if (!operation) return { filters: {} };\n return (\n (await client.lookupFilters?.(\n operation.path,\n operation.method,\n packParameterValues(debouncedValues, parameters),\n { Accept: \"application/json+clicky\" },\n )) ?? { filters: {} }\n );\n },\n enabled:\n isGet &&\n !!operation &&\n !!client.lookupFilters &&\n parameters.some((param) => param.in === \"query\"),\n staleTime: 30_000,\n retry: 0,\n });\n\n const formConfig = useMemo(() => {\n if (!isGet) return { filters: [] };\n return parametersToFormConfig(parameters, values, setValues, {\n lookup: lookupQuery.data,\n lockedValues: lockedPathValues,\n hideLocked: hideLockedPathFilters,\n });\n }, [\n isGet,\n parameters,\n values,\n lookupQuery.data,\n lockedPathValues,\n hideLockedPathFilters,\n ]);\n\n const dataTablePagination = useMemo(\n () => dataTablePaginationFromForm(formConfig.pagination, result),\n [formConfig.pagination, result],\n );\n\n // Ref tracking the last submitted parameter signature so the\n // auto-submit-on-debounced-change effect coordinates against the same\n // \"have I already fired this set of values\" check.\n const lastSubmittedSignature = useRef(\"\");\n\n async function executeOperation(values: ParameterValues) {\n if (!operation) return;\n\n setIsExecuting(true);\n setError(null);\n\n try {\n const response = await client.executeCommand(\n operation.path,\n operation.method,\n packParameterValues(values, operation.operation.parameters ?? []),\n { Accept: RESULT_ACCEPT },\n );\n setResult(response);\n onResult?.(response, operation, values);\n } catch (err) {\n setResult(null);\n setError(err);\n } finally {\n setIsExecuting(false);\n }\n }\n\n useEffect(() => {\n setHasAutoRun(false);\n setResult(null);\n setError(null);\n lastSubmittedSignature.current = \"\";\n }, [effectiveAutoRun, operationKey]);\n\n useEffect(() => {\n if (!effectiveAutoRun || !operation || hasAutoRun) return;\n // Auto-run a GET as long as every required parameter has a value. Optional\n // params (limit/offset, filter chips, etc.) get their defaults; the\n // sidebar's \"click → instant table\" flow depends on this not bailing just\n // because the operation declares any parameters at all.\n const missingRequired = parameters.filter((param) => {\n if (!param.required) return false;\n return (effectiveInitialValues[param.name] ?? \"\").trim() === \"\";\n });\n if (missingRequired.length > 0) return;\n\n setHasAutoRun(true);\n lastSubmittedSignature.current = JSON.stringify(\n pruneParameterValues(effectiveInitialValues),\n );\n void executeOperation(effectiveInitialValues);\n }, [\n effectiveAutoRun,\n effectiveInitialValues,\n hasAutoRun,\n operationKey,\n parameterSignature,\n ]);\n\n // GET re-runs on debounced filter/pagination changes once the initial\n // auto-run has fired; non-GETs keep their explicit-submit behavior.\n useEffect(() => {\n if (!isGet || !operation || !hasAutoRun) return;\n const merged = { ...debouncedValues, ...lockedPathValues };\n const missingRequired = parameters.filter((param) => {\n if (!param.required) return false;\n return (merged[param.name] ?? \"\").trim() === \"\";\n });\n if (missingRequired.length > 0) return;\n const signature = JSON.stringify(pruneParameterValues(merged));\n if (lastSubmittedSignature.current === signature) return;\n lastSubmittedSignature.current = signature;\n void executeOperation(merged);\n }, [\n isGet,\n hasAutoRun,\n debouncedValues,\n lockedPathValues,\n parameterSignature,\n ]);\n\n const backLink =\n backHref == null ? null : renderLink ? (\n renderLink({\n to: backHref,\n className: \"text-sm text-primary underline-offset-4 hover:underline\",\n children: backLabel,\n })\n ) : (\n <a\n href={backHref}\n className=\"text-sm text-primary underline-offset-4 hover:underline\"\n >\n {backLabel}\n </a>\n );\n\n if (isLoading) {\n return (\n <div className=\"text-sm text-muted-foreground\">Loading operation...</div>\n );\n }\n\n if (!operation) {\n return (\n <div className=\"space-y-4\">\n <div className=\"text-sm text-muted-foreground\">\n Unknown operation: <code>{operationId}</code>\n </div>\n {backLink}\n </div>\n );\n }\n\n const { path, method, operation: op } = operation;\n\n return (\n <div className={className ?? \"min-w-0 flex-1 space-y-6 p-6\"}>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0 flex-1\">\n {backLink}\n <div className=\"flex items-center gap-3\">\n <MethodBadge method={method} />\n <h1 className=\"truncate text-xl font-bold\">\n {op.summary || op.operationId || path}\n </h1>\n </div>\n <p className=\"mt-1 font-mono text-xs text-muted-foreground\">{path}</p>\n {op.operationId && op.summary && (\n <p className=\"mt-2 font-mono text-xs text-muted-foreground\">\n {op.operationId}\n </p>\n )}\n {op.description && op.description !== op.summary && (\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {op.description}\n </p>\n )}\n </div>\n <div className=\"flex shrink-0 flex-col items-end gap-3\">\n {relatedOperations.length > 0 && (\n <div className=\"flex flex-wrap justify-end gap-2\">\n {relatedOperations.map((related) =>\n related.href ? (\n renderLink ? (\n renderLink({\n key: `${related.operation.method}:${related.operation.path}`,\n to: related.href,\n className:\n \"inline-flex h-8 items-center justify-center gap-2 rounded-md border border-input bg-background px-3 text-xs font-medium hover:bg-accent hover:text-accent-foreground\",\n children: related.label,\n })\n ) : (\n <a\n key={`${related.operation.method}:${related.operation.path}`}\n href={related.href}\n className=\"inline-flex h-8 items-center justify-center gap-2 rounded-md border border-input bg-background px-3 text-xs font-medium hover:bg-accent hover:text-accent-foreground\"\n >\n {related.label}\n </a>\n )\n ) : (\n <OperationActionDialog\n key={`${related.operation.method}:${related.operation.path}`}\n operation={related.operation}\n client={client}\n initialValues={lockedPathValues}\n label={related.label}\n defaultAccept={RESULT_ACCEPT}\n {...(onNavigate ? { onNavigateAction: onNavigate } : {})}\n />\n ),\n )}\n </div>\n )}\n </div>\n </div>\n\n {method.toUpperCase() !== \"GET\" && (\n <section className=\"space-y-3\">\n <div className=\"rounded-lg border p-4\">\n <CommandForm\n parameters={parameters}\n onExecute={(params) => executeOperation(params)}\n isPending={isExecuting}\n method={method}\n path={path}\n accept={RESULT_ACCEPT}\n initialValues={effectiveInitialValues}\n />\n </div>\n </section>\n )}\n\n {error ? (\n <InlineError title={`Failed to load ${path}`} error={error} />\n ) : isExecuting || result ? (\n <OperationResultView\n response={result}\n loading={isExecuting}\n loadingMessage=\"Loading execution results…\"\n ariaLabel=\"Response body\"\n detailOperation={detailOperation}\n {...(commandRuntime ? { commandRuntime } : {})}\n {...(isGet && effectiveAutoRun\n ? {\n filterConfig: {\n filters: formConfig.filters,\n ...(formConfig.timeRange\n ? { timeRange: formConfig.timeRange }\n : {}),\n },\n }\n : {})}\n {...(isGet && effectiveAutoRun && dataTablePagination\n ? { pagination: dataTablePagination }\n : {})}\n />\n ) : null}\n </div>\n );\n}\n\ntype RelatedOperation = {\n operation: ResolvedOperation;\n label: string;\n href?: string;\n};\n\nfunction findRelatedOperations(\n current: ResolvedOperation,\n operations: ResolvedOperation[],\n pathValues: Record<string, string>,\n): RelatedOperation[] {\n if (current.method.toUpperCase() !== \"GET\") return [];\n if (!pathTemplateSatisfied(current.path, pathValues)) return [];\n\n const basePath = stripTrailingSlashes(current.path);\n return operations\n .filter((candidate) => {\n if (candidate === current) return false;\n if (!candidate.path.startsWith(`${basePath}/`)) return false;\n if (!pathTemplateSatisfied(candidate.path, pathValues)) return false;\n const method = candidate.method.toUpperCase();\n return (\n method === \"GET\" ||\n method === \"POST\" ||\n method === \"PUT\" ||\n method === \"DELETE\"\n );\n })\n .map((related) => {\n const method = related.method.toUpperCase();\n const href =\n method === \"GET\"\n ? hrefForOperation(related, [], pathValues)\n : undefined;\n return {\n operation: related,\n label: operationLabel(related),\n ...(href ? { href } : {}),\n };\n })\n .filter(\n (related) =>\n related.operation.method.toUpperCase() !== \"GET\" || related.href,\n );\n}\n\nfunction findDetailOperation(\n current: ResolvedOperation,\n operations: ResolvedOperation[],\n) {\n const method = current.method.toUpperCase();\n const detailPath = `${stripTrailingSlashes(current.path)}/{id}`;\n return operations.find(\n (candidate) =>\n candidate.method.toUpperCase() === method &&\n candidate.path === detailPath &&\n candidate.operation.parameters?.some(\n (param) => param.in === \"path\" && param.name === \"id\" && param.required,\n ),\n );\n}\n\nfunction pathTemplateSatisfied(path: string, values: Record<string, string>) {\n return pathParamNames(path).every((name) => Boolean(values[name]));\n}\n\nfunction operationLabel(operation: ResolvedOperation): string {\n const actionName =\n operation.operation[\"x-clicky\"]?.actionName ||\n operation.path.split(\"/\").filter(Boolean).at(-1) ||\n operation.operation.operationId ||\n operation.method;\n return titleCase(actionName.replace(/[_-]+/g, \" \"));\n}\n\nfunction stripRunnerParams(values: ParameterValues): ParameterValues {\n const next: ParameterValues = {};\n for (const [key, value] of Object.entries(values)) {\n if (key === \"autoRun\" || key.startsWith(\"__\")) continue;\n next[key] = value;\n }\n return next;\n}\n\nfunction readQueryParameterValuesFromUrl(\n parameters: OpenAPIParameter[],\n): ParameterValues {\n if (typeof window === \"undefined\") return {};\n const queryParamNames = new Set(\n parameters.filter((param) => param.in === \"query\").map((p) => p.name),\n );\n if (queryParamNames.size === 0) return {};\n\n const values: ParameterValues = {};\n const search = new URLSearchParams(window.location.search);\n for (const name of queryParamNames) {\n const value = search.get(name);\n if (value != null && value !== \"\") {\n values[name] = value;\n }\n }\n return values;\n}\n\nfunction writeQueryParameterValuesToUrl(\n values: ParameterValues,\n parameters: OpenAPIParameter[],\n) {\n if (typeof window === \"undefined\") return;\n const queryParameters = parameters.filter((param) => param.in === \"query\");\n if (queryParameters.length === 0) return;\n\n const search = new URLSearchParams(window.location.search);\n for (const param of queryParameters) {\n const value = submitValue(param, values[param.name]);\n if (value == null) {\n search.delete(param.name);\n } else {\n search.set(param.name, value);\n }\n }\n\n const query = search.toString();\n const next = `${window.location.pathname}${query ? `?${query}` : \"\"}${window.location.hash}`;\n const current = `${window.location.pathname}${window.location.search}${window.location.hash}`;\n if (next !== current) {\n window.history.replaceState(window.history.state, \"\", next);\n }\n}\n"],"names":["useOperationById","useState","useMemo","buildInitialParameterValues","values","useEffect","useDebouncedRecord","useQuery","packParameterValues","parametersToFormConfig","dataTablePaginationFromForm","useRef","pruneParameterValues","jsx","jsxs","MethodBadge","OperationActionDialog","CommandForm","InlineError","OperationResultView","stripTrailingSlashes","hrefForOperation","pathParamNames","titleCase","submitValue"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OperationCommandPage.d.ts","sourceRoot":"","sources":["../../src/rpc/OperationCommandPage.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"OperationCommandPage.d.ts","sourceRoot":"","sources":["../../src/rpc/OperationCommandPage.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAK3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAQL,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAKxB,OAAO,KAAK,EACV,iBAAiB,EAEjB,iBAAiB,EAClB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAoB,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAM7E,MAAM,MAAM,yBAAyB,GAAG;IACtC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACjC,aAAa,CAAC,EAAE,eAAe,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,CACT,QAAQ,EAAE,iBAAiB,EAC3B,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,eAAe,KACpB,IAAI,CAAC;IACV,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAIF,wBAAgB,oBAAoB,CAAC,EACnC,MAAM,EACN,WAAW,EACX,SAAS,EAAE,iBAAiB,EAC5B,UAAyD,EACzD,aAAsC,EACtC,OAAO,EACP,QAAQ,EACR,SAAkB,EAClB,UAAU,EACV,UAAU,EACV,QAAQ,EACR,cAAc,EACd,qBAAkD,EAClD,SAAS,GACV,EAAE,yBAAyB,2CAyV3B"}
|
|
@@ -2,6 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState, useMemo, useEffect, useRef } from "react";
|
|
3
3
|
import { useQuery } from "@tanstack/react-query";
|
|
4
4
|
import { MethodBadge } from "../data/MethodBadge.js";
|
|
5
|
+
import { stripTrailingSlashes } from "../lib/string.js";
|
|
5
6
|
import { CommandForm } from "./CommandForm.js";
|
|
6
7
|
import { submitValue, pathParamNames } from "./command-form-utils.js";
|
|
7
8
|
import { buildInitialParameterValues, useDebouncedRecord, packParameterValues, parametersToFormConfig, dataTablePaginationFromForm, pruneParameterValues, titleCase } from "./formMetadata.js";
|
|
@@ -299,7 +300,7 @@ function OperationCommandPage({
|
|
|
299
300
|
function findRelatedOperations(current, operations, pathValues) {
|
|
300
301
|
if (current.method.toUpperCase() !== "GET") return [];
|
|
301
302
|
if (!pathTemplateSatisfied(current.path, pathValues)) return [];
|
|
302
|
-
const basePath = current.path
|
|
303
|
+
const basePath = stripTrailingSlashes(current.path);
|
|
303
304
|
return operations.filter((candidate) => {
|
|
304
305
|
if (candidate === current) return false;
|
|
305
306
|
if (!candidate.path.startsWith(`${basePath}/`)) return false;
|
|
@@ -320,7 +321,7 @@ function findRelatedOperations(current, operations, pathValues) {
|
|
|
320
321
|
}
|
|
321
322
|
function findDetailOperation(current, operations) {
|
|
322
323
|
const method = current.method.toUpperCase();
|
|
323
|
-
const detailPath = `${current.path
|
|
324
|
+
const detailPath = `${stripTrailingSlashes(current.path)}/{id}`;
|
|
324
325
|
return operations.find(
|
|
325
326
|
(candidate) => {
|
|
326
327
|
var _a;
|