@backstage/cli-module-actions 0.0.2-next.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @backstage/cli-module-actions
2
2
 
3
+ ## 0.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - c705d44: Added improved CLI output formatting and UX for the actions module. The `list` command now groups actions by plugin source with colored headers and action titles. The `execute --help` command renders full action details including markdown descriptions. Complex schema types like objects, arrays, and union types are now accepted as JSON flags. Error messages from the server are now surfaced directly. The `sources add` and `sources remove` commands accept multiple plugin IDs at once.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies
12
+ - @backstage/errors@1.3.0
13
+ - @backstage/cli-node@0.3.1
14
+
15
+ ## 0.0.2-next.1
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies
20
+ - @backstage/errors@1.3.0-next.0
21
+ - @backstage/cli-node@0.3.1-next.1
22
+
3
23
  ## 0.0.2-next.0
4
24
 
5
25
  ### Patch Changes
@@ -6,25 +6,9 @@ var cleye = require('cleye');
6
6
  var ActionsClient = require('../lib/ActionsClient.cjs.js');
7
7
  var schemaToFlags = require('../lib/schemaToFlags.cjs.js');
8
8
  var resolveAuth = require('../lib/resolveAuth.cjs.js');
9
+ var format = require('../lib/format.cjs.js');
9
10
 
10
- var execute = async ({ args, info }) => {
11
- if (args.includes("--help") || args.includes("-h")) {
12
- cleye.cli(
13
- {
14
- help: info,
15
- parameters: ["<action-id>"],
16
- flags: {
17
- instance: {
18
- type: String,
19
- description: "Name of the instance to use"
20
- }
21
- }
22
- },
23
- void 0,
24
- args
25
- );
26
- return;
27
- }
11
+ function parseArgs(args) {
28
12
  const instanceIdx = args.indexOf("--instance");
29
13
  const instanceFlag = instanceIdx !== -1 ? args[instanceIdx + 1] : void 0;
30
14
  const skipIndices = /* @__PURE__ */ new Set();
@@ -41,9 +25,70 @@ var execute = async ({ args, info }) => {
41
25
  break;
42
26
  }
43
27
  }
28
+ const wantsHelp = args.includes("--help") || args.includes("-h");
29
+ return { instanceFlag, actionId, actionIdIdx, wantsHelp };
30
+ }
31
+ function showGenericHelp(info, args) {
32
+ cleye.cli(
33
+ {
34
+ help: info,
35
+ parameters: ["<action-id>"],
36
+ flags: {
37
+ instance: {
38
+ type: String,
39
+ description: "Name of the instance to use"
40
+ }
41
+ }
42
+ },
43
+ void 0,
44
+ args
45
+ );
46
+ }
47
+ async function showActionHelp(info, actionId, instanceFlag) {
48
+ try {
49
+ const { accessToken, baseUrl } = await resolveAuth.resolveAuth(instanceFlag);
50
+ const client = new ActionsClient.ActionsClient(baseUrl, accessToken);
51
+ const actions = await client.listForPlugin(actionId);
52
+ const action = actions.find((a) => a.id === actionId);
53
+ if (!action) {
54
+ return false;
55
+ }
56
+ const { flags: flagDefs } = schemaToFlags.schemaToFlags(action.schema.input);
57
+ const flags = format.flagDefsToFlagInfo(flagDefs);
58
+ flags.push({
59
+ name: "instance",
60
+ type: "string",
61
+ description: "Name of the instance to use"
62
+ });
63
+ process.stdout.write(
64
+ await format.formatActionHelp({
65
+ action,
66
+ usage: `${info.usage ?? "backstage actions execute"} ${actionId}`,
67
+ flags
68
+ })
69
+ );
70
+ return true;
71
+ } catch (err) {
72
+ const msg = err instanceof Error ? err.message : String(err);
73
+ process.stderr.write(
74
+ `Unable to retrieve action schema: ${msg}
75
+ Showing generic help.
76
+ `
77
+ );
78
+ return false;
79
+ }
80
+ }
81
+ var execute = async ({ args, info }) => {
82
+ const { instanceFlag, actionId, actionIdIdx, wantsHelp } = parseArgs(args);
83
+ if (wantsHelp) {
84
+ if (!actionId || !await showActionHelp(info, actionId, instanceFlag)) {
85
+ showGenericHelp(info, args);
86
+ }
87
+ return;
88
+ }
44
89
  if (!actionId) {
45
- process.stderr.write("Usage: actions execute <action-id> [flags]\n");
46
- process.exit(1);
90
+ showGenericHelp(info, ["--help", ...args]);
91
+ throw new Error("Action ID is required");
47
92
  }
48
93
  const { accessToken, baseUrl } = await resolveAuth.resolveAuth(instanceFlag);
49
94
  const client = new ActionsClient.ActionsClient(baseUrl, accessToken);
@@ -54,17 +99,18 @@ var execute = async ({ args, info }) => {
54
99
  `Action "${actionId}" not found. Run "actions list" to see available actions.`
55
100
  );
56
101
  }
57
- const schemaFlags = schemaToFlags.schemaToFlags(action.schema.input);
102
+ const inputSchema = action.schema.input;
103
+ const { flags: schemaFlags, complexKeys } = schemaToFlags.schemaToFlags(inputSchema);
58
104
  const flagArgs = args.filter((_, i) => i !== actionIdIdx);
59
105
  const { flags } = cleye.cli(
60
106
  {
61
107
  help: info,
62
108
  flags: {
109
+ ...schemaFlags,
63
110
  instance: {
64
111
  type: String,
65
112
  description: "Name of the instance to use"
66
- },
67
- ...schemaFlags
113
+ }
68
114
  }
69
115
  },
70
116
  void 0,
@@ -73,7 +119,16 @@ var execute = async ({ args, info }) => {
73
119
  const allFlags = flags;
74
120
  const input = {};
75
121
  for (const [key, value] of Object.entries(allFlags)) {
76
- if (key !== "instance" && value !== void 0) {
122
+ if (key === "instance" || value === void 0) {
123
+ continue;
124
+ }
125
+ if (complexKeys.has(key) && typeof value === "string") {
126
+ try {
127
+ input[key] = JSON.parse(value);
128
+ } catch {
129
+ throw new Error(`Invalid JSON for --${key}. Expected a JSON string.`);
130
+ }
131
+ } else {
77
132
  input[key] = value;
78
133
  }
79
134
  }
@@ -1 +1 @@
1
- {"version":3,"file":"execute.cjs.js","sources":["../../src/commands/execute.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cli } from 'cleye';\nimport type { CliCommandContext } from '@backstage/cli-node';\nimport { ActionsClient } from '../lib/ActionsClient';\nimport { schemaToFlags } from '../lib/schemaToFlags';\nimport { resolveAuth } from '../lib/resolveAuth';\n\nexport default async ({ args, info }: CliCommandContext) => {\n if (args.includes('--help') || args.includes('-h')) {\n cli(\n {\n help: info,\n parameters: ['<action-id>'],\n flags: {\n instance: {\n type: String,\n description: 'Name of the instance to use',\n },\n },\n },\n undefined,\n args,\n );\n return;\n }\n\n const instanceIdx = args.indexOf('--instance');\n const instanceFlag = instanceIdx !== -1 ? args[instanceIdx + 1] : undefined;\n\n // Skip flag names, flag values (the argument after a known flag), and\n // the --instance value position so we only pick up positional arguments.\n const skipIndices = new Set<number>();\n if (instanceIdx !== -1) {\n skipIndices.add(instanceIdx);\n skipIndices.add(instanceIdx + 1);\n }\n\n let actionId: string | undefined;\n let actionIdIdx = -1;\n for (let i = 0; i < args.length; i++) {\n if (!skipIndices.has(i) && !args[i].startsWith('-')) {\n actionId = args[i];\n actionIdIdx = i;\n break;\n }\n }\n\n if (!actionId) {\n process.stderr.write('Usage: actions execute <action-id> [flags]\\n');\n process.exit(1);\n }\n\n const { accessToken, baseUrl } = await resolveAuth(instanceFlag);\n\n const client = new ActionsClient(baseUrl, accessToken);\n const actions = await client.listForPlugin(actionId);\n const action = actions.find(a => a.id === actionId);\n\n if (!action) {\n throw new Error(\n `Action \"${actionId}\" not found. Run \"actions list\" to see available actions.`,\n );\n }\n\n const schemaFlags = schemaToFlags(action.schema.input as any);\n\n const flagArgs = args.filter((_, i) => i !== actionIdIdx);\n\n const { flags } = cli(\n {\n help: info,\n flags: {\n instance: {\n type: String,\n description: 'Name of the instance to use',\n },\n ...schemaFlags,\n },\n },\n undefined,\n flagArgs,\n );\n\n const allFlags = flags as Record<string, unknown>;\n const input: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(allFlags)) {\n if (key !== 'instance' && value !== undefined) {\n input[key] = value;\n }\n }\n\n const output = await client.execute(actionId, input);\n process.stdout.write(`${JSON.stringify(output, null, 2)}\\n`);\n};\n"],"names":["cli","resolveAuth","ActionsClient","schemaToFlags"],"mappings":"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"}
1
+ {"version":3,"file":"execute.cjs.js","sources":["../../src/commands/execute.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cli } from 'cleye';\nimport type { CliCommandContext } from '@backstage/cli-node';\nimport { ActionsClient } from '../lib/ActionsClient';\nimport { schemaToFlags } from '../lib/schemaToFlags';\nimport { resolveAuth } from '../lib/resolveAuth';\nimport { formatActionHelp, flagDefsToFlagInfo } from '../lib/format';\n\nfunction parseArgs(args: string[]) {\n const instanceIdx = args.indexOf('--instance');\n const instanceFlag = instanceIdx !== -1 ? args[instanceIdx + 1] : undefined;\n\n const skipIndices = new Set<number>();\n if (instanceIdx !== -1) {\n skipIndices.add(instanceIdx);\n skipIndices.add(instanceIdx + 1);\n }\n\n let actionId: string | undefined;\n let actionIdIdx = -1;\n for (let i = 0; i < args.length; i++) {\n if (!skipIndices.has(i) && !args[i].startsWith('-')) {\n actionId = args[i];\n actionIdIdx = i;\n break;\n }\n }\n\n const wantsHelp = args.includes('--help') || args.includes('-h');\n\n return { instanceFlag, actionId, actionIdIdx, wantsHelp };\n}\n\nfunction showGenericHelp(\n info: CliCommandContext['info'],\n args: string[],\n): void {\n cli(\n {\n help: info,\n parameters: ['<action-id>'],\n flags: {\n instance: {\n type: String,\n description: 'Name of the instance to use',\n },\n },\n },\n undefined,\n args,\n );\n}\n\nasync function showActionHelp(\n info: CliCommandContext['info'],\n actionId: string,\n instanceFlag: string | undefined,\n): Promise<boolean> {\n try {\n const { accessToken, baseUrl } = await resolveAuth(instanceFlag);\n const client = new ActionsClient(baseUrl, accessToken);\n const actions = await client.listForPlugin(actionId);\n const action = actions.find(a => a.id === actionId);\n\n if (!action) {\n return false;\n }\n\n const { flags: flagDefs } = schemaToFlags(action.schema.input as any);\n const flags = flagDefsToFlagInfo(flagDefs);\n flags.push({\n name: 'instance',\n type: 'string',\n description: 'Name of the instance to use',\n });\n\n process.stdout.write(\n await formatActionHelp({\n action,\n usage: `${info.usage ?? 'backstage actions execute'} ${actionId}`,\n flags,\n }),\n );\n return true;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n process.stderr.write(\n `Unable to retrieve action schema: ${msg}\\nShowing generic help.\\n`,\n );\n return false;\n }\n}\n\nexport default async ({ args, info }: CliCommandContext) => {\n const { instanceFlag, actionId, actionIdIdx, wantsHelp } = parseArgs(args);\n\n if (wantsHelp) {\n if (!actionId || !(await showActionHelp(info, actionId, instanceFlag))) {\n showGenericHelp(info, args);\n }\n return;\n }\n\n if (!actionId) {\n // Inject --help so cleye renders its help output before we throw.\n showGenericHelp(info, ['--help', ...args]);\n throw new Error('Action ID is required');\n }\n\n const { accessToken, baseUrl } = await resolveAuth(instanceFlag);\n const client = new ActionsClient(baseUrl, accessToken);\n const actions = await client.listForPlugin(actionId);\n const action = actions.find(a => a.id === actionId);\n\n if (!action) {\n throw new Error(\n `Action \"${actionId}\" not found. Run \"actions list\" to see available actions.`,\n );\n }\n\n const inputSchema = action.schema.input as any;\n const { flags: schemaFlags, complexKeys } = schemaToFlags(inputSchema);\n\n const flagArgs = args.filter((_, i) => i !== actionIdIdx);\n\n const { flags } = cli(\n {\n help: info,\n flags: {\n ...schemaFlags,\n instance: {\n type: String,\n description: 'Name of the instance to use',\n },\n },\n },\n undefined,\n flagArgs,\n );\n\n const allFlags = flags as Record<string, unknown>;\n const input: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(allFlags)) {\n if (key === 'instance' || value === undefined) {\n continue;\n }\n if (complexKeys.has(key) && typeof value === 'string') {\n try {\n input[key] = JSON.parse(value);\n } catch {\n throw new Error(`Invalid JSON for --${key}. Expected a JSON string.`);\n }\n } else {\n input[key] = value;\n }\n }\n\n const output = await client.execute(actionId, input);\n process.stdout.write(`${JSON.stringify(output, null, 2)}\\n`);\n};\n"],"names":["cli","resolveAuth","ActionsClient","schemaToFlags","flagDefsToFlagInfo","formatActionHelp"],"mappings":"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"}
@@ -5,6 +5,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var cleye = require('cleye');
6
6
  var ActionsClient = require('../lib/ActionsClient.cjs.js');
7
7
  var resolveAuth = require('../lib/resolveAuth.cjs.js');
8
+ var format = require('../lib/format.cjs.js');
8
9
 
9
10
  var list = async ({ args, info }) => {
10
11
  const {
@@ -32,16 +33,14 @@ var list = async ({ args, info }) => {
32
33
  return;
33
34
  }
34
35
  const client = new ActionsClient.ActionsClient(baseUrl, accessToken);
35
- const actions = await client.list(pluginSources);
36
- if (!actions.length) {
36
+ const grouped = await client.list(pluginSources);
37
+ const hasActions = grouped.some((g) => g.actions.length > 0);
38
+ if (!hasActions) {
37
39
  process.stderr.write("No actions found.\n");
38
40
  return;
39
41
  }
40
- for (const action of actions) {
41
- const desc = action.description ? ` - ${action.description}` : "";
42
- process.stdout.write(`${action.id}${desc}
42
+ process.stdout.write(`${format.formatActionList(grouped)}
43
43
  `);
44
- }
45
44
  };
46
45
 
47
46
  exports.default = list;
@@ -1 +1 @@
1
- {"version":3,"file":"list.cjs.js","sources":["../../src/commands/list.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cli } from 'cleye';\nimport type { CliCommandContext } from '@backstage/cli-node';\nimport { ActionsClient } from '../lib/ActionsClient';\nimport { resolveAuth } from '../lib/resolveAuth';\n\nexport default async ({ args, info }: CliCommandContext) => {\n const {\n flags: { instance: instanceFlag },\n } = cli(\n {\n help: info,\n flags: {\n instance: {\n type: String,\n description: 'Name of the instance to use',\n },\n },\n },\n undefined,\n args,\n );\n\n const { accessToken, pluginSources, baseUrl } = await resolveAuth(\n instanceFlag,\n );\n\n if (!pluginSources.length) {\n process.stderr.write(\n 'No plugin sources configured. Run \"actions sources add <plugin-id>\" to add one.\\n',\n );\n return;\n }\n\n const client = new ActionsClient(baseUrl, accessToken);\n const actions = await client.list(pluginSources);\n\n if (!actions.length) {\n process.stderr.write('No actions found.\\n');\n return;\n }\n\n for (const action of actions) {\n const desc = action.description ? ` - ${action.description}` : '';\n process.stdout.write(`${action.id}${desc}\\n`);\n }\n};\n"],"names":["cli","resolveAuth","ActionsClient"],"mappings":";;;;;;;;AAqBA,WAAe,OAAO,EAAE,IAAA,EAAM,IAAA,EAAK,KAAyB;AAC1D,EAAA,MAAM;AAAA,IACJ,KAAA,EAAO,EAAE,QAAA,EAAU,YAAA;AAAa,GAClC,GAAIA,SAAA;AAAA,IACF;AAAA,MACE,IAAA,EAAM,IAAA;AAAA,MACN,KAAA,EAAO;AAAA,QACL,QAAA,EAAU;AAAA,UACR,IAAA,EAAM,MAAA;AAAA,UACN,WAAA,EAAa;AAAA;AACf;AACF,KACF;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,EAAE,WAAA,EAAa,aAAA,EAAe,OAAA,KAAY,MAAMC,uBAAA;AAAA,IACpD;AAAA,GACF;AAEA,EAAA,IAAI,CAAC,cAAc,MAAA,EAAQ;AACzB,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA;AAAA,MACb;AAAA,KACF;AACA,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GAAS,IAAIC,2BAAA,CAAc,OAAA,EAAS,WAAW,CAAA;AACrD,EAAA,MAAM,OAAA,GAAU,MAAM,MAAA,CAAO,IAAA,CAAK,aAAa,CAAA;AAE/C,EAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACnB,IAAA,OAAA,CAAQ,MAAA,CAAO,MAAM,qBAAqB,CAAA;AAC1C,IAAA;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,MAAM,OAAO,MAAA,CAAO,WAAA,GAAc,CAAA,GAAA,EAAM,MAAA,CAAO,WAAW,CAAA,CAAA,GAAK,EAAA;AAC/D,IAAA,OAAA,CAAQ,OAAO,KAAA,CAAM,CAAA,EAAG,MAAA,CAAO,EAAE,GAAG,IAAI;AAAA,CAAI,CAAA;AAAA,EAC9C;AACF,CAAA;;;;"}
1
+ {"version":3,"file":"list.cjs.js","sources":["../../src/commands/list.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cli } from 'cleye';\nimport type { CliCommandContext } from '@backstage/cli-node';\nimport { ActionsClient } from '../lib/ActionsClient';\nimport { resolveAuth } from '../lib/resolveAuth';\nimport { formatActionList } from '../lib/format';\n\nexport default async ({ args, info }: CliCommandContext) => {\n const {\n flags: { instance: instanceFlag },\n } = cli(\n {\n help: info,\n flags: {\n instance: {\n type: String,\n description: 'Name of the instance to use',\n },\n },\n },\n undefined,\n args,\n );\n\n const { accessToken, pluginSources, baseUrl } = await resolveAuth(\n instanceFlag,\n );\n\n if (!pluginSources.length) {\n process.stderr.write(\n 'No plugin sources configured. Run \"actions sources add <plugin-id>\" to add one.\\n',\n );\n return;\n }\n\n const client = new ActionsClient(baseUrl, accessToken);\n const grouped = await client.list(pluginSources);\n\n const hasActions = grouped.some(g => g.actions.length > 0);\n if (!hasActions) {\n process.stderr.write('No actions found.\\n');\n return;\n }\n\n process.stdout.write(`${formatActionList(grouped)}\\n`);\n};\n"],"names":["cli","resolveAuth","ActionsClient","formatActionList"],"mappings":";;;;;;;;;AAsBA,WAAe,OAAO,EAAE,IAAA,EAAM,IAAA,EAAK,KAAyB;AAC1D,EAAA,MAAM;AAAA,IACJ,KAAA,EAAO,EAAE,QAAA,EAAU,YAAA;AAAa,GAClC,GAAIA,SAAA;AAAA,IACF;AAAA,MACE,IAAA,EAAM,IAAA;AAAA,MACN,KAAA,EAAO;AAAA,QACL,QAAA,EAAU;AAAA,UACR,IAAA,EAAM,MAAA;AAAA,UACN,WAAA,EAAa;AAAA;AACf;AACF,KACF;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,EAAE,WAAA,EAAa,aAAA,EAAe,OAAA,KAAY,MAAMC,uBAAA;AAAA,IACpD;AAAA,GACF;AAEA,EAAA,IAAI,CAAC,cAAc,MAAA,EAAQ;AACzB,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA;AAAA,MACb;AAAA,KACF;AACA,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GAAS,IAAIC,2BAAA,CAAc,OAAA,EAAS,WAAW,CAAA;AACrD,EAAA,MAAM,OAAA,GAAU,MAAM,MAAA,CAAO,IAAA,CAAK,aAAa,CAAA;AAE/C,EAAA,MAAM,aAAa,OAAA,CAAQ,IAAA,CAAK,OAAK,CAAA,CAAE,OAAA,CAAQ,SAAS,CAAC,CAAA;AACzD,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,OAAA,CAAQ,MAAA,CAAO,MAAM,qBAAqB,CAAA;AAC1C,IAAA;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,EAAGC,uBAAA,CAAiB,OAAO,CAAC;AAAA,CAAI,CAAA;AACvD,CAAA;;;;"}
@@ -4,33 +4,44 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var cleye = require('cleye');
6
6
  var cliNode = require('@backstage/cli-node');
7
- var v3 = require('zod/v3');
7
+ var pluginSources = require('../lib/pluginSources.cjs.js');
8
8
 
9
- const pluginSourcesSchema = v3.z.array(v3.z.string()).default([]);
10
9
  var sourcesAdd = async ({ args, info }) => {
11
10
  const parsed = cleye.cli(
12
11
  {
13
12
  help: info,
14
- parameters: ["<plugin-id>"]
13
+ parameters: ["<plugin-ids...>"]
15
14
  },
16
15
  void 0,
17
16
  args
18
17
  );
19
- const pluginId = parsed._[0];
18
+ const pluginIds = parsed._.pluginIds;
20
19
  const auth = await cliNode.CliAuth.create();
21
- const existing = pluginSourcesSchema.parse(
20
+ const existing = pluginSources.pluginSourcesSchema.parse(
22
21
  await auth.getMetadata("pluginSources")
23
22
  );
24
- if (existing.includes(pluginId)) {
25
- process.stderr.write(
26
- `Plugin source "${pluginId}" is already configured.
23
+ const added = [];
24
+ const skipped = [];
25
+ for (const pluginId of pluginIds) {
26
+ if (existing.includes(pluginId)) {
27
+ skipped.push(pluginId);
28
+ } else {
29
+ added.push(pluginId);
30
+ }
31
+ }
32
+ if (added.length > 0) {
33
+ await auth.setMetadata("pluginSources", [...existing, ...added]);
34
+ process.stdout.write(
35
+ `Added plugin source${added.length > 1 ? "s" : ""}: ${added.join(
36
+ ", "
37
+ )}
27
38
  `
28
39
  );
29
- return;
30
40
  }
31
- await auth.setMetadata("pluginSources", [...existing, pluginId]);
32
- process.stdout.write(`Added plugin source "${pluginId}".
41
+ for (const id of skipped) {
42
+ process.stderr.write(`Plugin source "${id}" is already configured.
33
43
  `);
44
+ }
34
45
  };
35
46
 
36
47
  exports.default = sourcesAdd;
@@ -1 +1 @@
1
- {"version":3,"file":"sourcesAdd.cjs.js","sources":["../../src/commands/sourcesAdd.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cli } from 'cleye';\nimport { CliAuth, type CliCommandContext } from '@backstage/cli-node';\nimport { z } from 'zod/v3';\n\nconst pluginSourcesSchema = z.array(z.string()).default([]);\n\nexport default async ({ args, info }: CliCommandContext) => {\n const parsed = cli(\n {\n help: info,\n parameters: ['<plugin-id>'],\n },\n undefined,\n args,\n );\n\n const pluginId = parsed._[0];\n\n const auth = await CliAuth.create();\n const existing = pluginSourcesSchema.parse(\n await auth.getMetadata('pluginSources'),\n );\n\n if (existing.includes(pluginId)) {\n process.stderr.write(\n `Plugin source \"${pluginId}\" is already configured.\\n`,\n );\n return;\n }\n\n await auth.setMetadata('pluginSources', [...existing, pluginId]);\n\n process.stdout.write(`Added plugin source \"${pluginId}\".\\n`);\n};\n"],"names":["z","cli","CliAuth"],"mappings":";;;;;;;;AAoBA,MAAM,mBAAA,GAAsBA,KAAE,KAAA,CAAMA,IAAA,CAAE,QAAQ,CAAA,CAAE,OAAA,CAAQ,EAAE,CAAA;AAE1D,iBAAe,OAAO,EAAE,IAAA,EAAM,IAAA,EAAK,KAAyB;AAC1D,EAAA,MAAM,MAAA,GAASC,SAAA;AAAA,IACb;AAAA,MACE,IAAA,EAAM,IAAA;AAAA,MACN,UAAA,EAAY,CAAC,aAAa;AAAA,KAC5B;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,CAAA,CAAE,CAAC,CAAA;AAE3B,EAAA,MAAM,IAAA,GAAO,MAAMC,eAAA,CAAQ,MAAA,EAAO;AAClC,EAAA,MAAM,WAAW,mBAAA,CAAoB,KAAA;AAAA,IACnC,MAAM,IAAA,CAAK,WAAA,CAAY,eAAe;AAAA,GACxC;AAEA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,QAAQ,CAAA,EAAG;AAC/B,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA;AAAA,MACb,kBAAkB,QAAQ,CAAA;AAAA;AAAA,KAC5B;AACA,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,KAAK,WAAA,CAAY,eAAA,EAAiB,CAAC,GAAG,QAAA,EAAU,QAAQ,CAAC,CAAA;AAE/D,EAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,qBAAA,EAAwB,QAAQ,CAAA;AAAA,CAAM,CAAA;AAC7D,CAAA;;;;"}
1
+ {"version":3,"file":"sourcesAdd.cjs.js","sources":["../../src/commands/sourcesAdd.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cli } from 'cleye';\nimport { CliAuth, type CliCommandContext } from '@backstage/cli-node';\nimport { pluginSourcesSchema } from '../lib/pluginSources';\n\nexport default async ({ args, info }: CliCommandContext) => {\n const parsed = cli(\n {\n help: info,\n parameters: ['<plugin-ids...>'],\n },\n undefined,\n args,\n );\n\n const pluginIds: string[] = parsed._.pluginIds;\n\n const auth = await CliAuth.create();\n const existing = pluginSourcesSchema.parse(\n await auth.getMetadata('pluginSources'),\n );\n\n const added: string[] = [];\n const skipped: string[] = [];\n\n for (const pluginId of pluginIds) {\n if (existing.includes(pluginId)) {\n skipped.push(pluginId);\n } else {\n added.push(pluginId);\n }\n }\n\n if (added.length > 0) {\n await auth.setMetadata('pluginSources', [...existing, ...added]);\n process.stdout.write(\n `Added plugin source${added.length > 1 ? 's' : ''}: ${added.join(\n ', ',\n )}\\n`,\n );\n }\n\n for (const id of skipped) {\n process.stderr.write(`Plugin source \"${id}\" is already configured.\\n`);\n }\n};\n"],"names":["cli","CliAuth","pluginSourcesSchema"],"mappings":";;;;;;;;AAoBA,iBAAe,OAAO,EAAE,IAAA,EAAM,IAAA,EAAK,KAAyB;AAC1D,EAAA,MAAM,MAAA,GAASA,SAAA;AAAA,IACb;AAAA,MACE,IAAA,EAAM,IAAA;AAAA,MACN,UAAA,EAAY,CAAC,iBAAiB;AAAA,KAChC;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,SAAA,GAAsB,OAAO,CAAA,CAAE,SAAA;AAErC,EAAA,MAAM,IAAA,GAAO,MAAMC,eAAA,CAAQ,MAAA,EAAO;AAClC,EAAA,MAAM,WAAWC,iCAAA,CAAoB,KAAA;AAAA,IACnC,MAAM,IAAA,CAAK,WAAA,CAAY,eAAe;AAAA,GACxC;AAEA,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,MAAM,UAAoB,EAAC;AAE3B,EAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,IAAA,IAAI,QAAA,CAAS,QAAA,CAAS,QAAQ,CAAA,EAAG;AAC/B,MAAA,OAAA,CAAQ,KAAK,QAAQ,CAAA;AAAA,IACvB,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,KAAK,QAAQ,CAAA;AAAA,IACrB;AAAA,EACF;AAEA,EAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,IAAA,MAAM,IAAA,CAAK,YAAY,eAAA,EAAiB,CAAC,GAAG,QAAA,EAAU,GAAG,KAAK,CAAC,CAAA;AAC/D,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA;AAAA,MACb,sBAAsB,KAAA,CAAM,MAAA,GAAS,IAAI,GAAA,GAAM,EAAE,KAAK,KAAA,CAAM,IAAA;AAAA,QAC1D;AAAA,OACD;AAAA;AAAA,KACH;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,MAAM,OAAA,EAAS;AACxB,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,eAAA,EAAkB,EAAE,CAAA;AAAA,CAA4B,CAAA;AAAA,EACvE;AACF,CAAA;;;;"}
@@ -4,13 +4,12 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var cleye = require('cleye');
6
6
  var cliNode = require('@backstage/cli-node');
7
- var v3 = require('zod/v3');
7
+ var pluginSources = require('../lib/pluginSources.cjs.js');
8
8
 
9
- const pluginSourcesSchema = v3.z.array(v3.z.string()).default([]);
10
9
  var sourcesList = async ({ args, info }) => {
11
10
  cleye.cli({ help: info }, void 0, args);
12
11
  const auth = await cliNode.CliAuth.create();
13
- const sources = pluginSourcesSchema.parse(
12
+ const sources = pluginSources.pluginSourcesSchema.parse(
14
13
  await auth.getMetadata("pluginSources")
15
14
  );
16
15
  if (!sources.length) {
@@ -1 +1 @@
1
- {"version":3,"file":"sourcesList.cjs.js","sources":["../../src/commands/sourcesList.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cli } from 'cleye';\nimport { CliAuth, type CliCommandContext } from '@backstage/cli-node';\nimport { z } from 'zod/v3';\n\nconst pluginSourcesSchema = z.array(z.string()).default([]);\n\nexport default async ({ args, info }: CliCommandContext) => {\n cli({ help: info }, undefined, args);\n\n const auth = await CliAuth.create();\n const sources = pluginSourcesSchema.parse(\n await auth.getMetadata('pluginSources'),\n );\n\n if (!sources.length) {\n process.stderr.write('No plugin sources configured.\\n');\n return;\n }\n\n for (const source of sources) {\n process.stdout.write(`${source}\\n`);\n }\n};\n"],"names":["z","cli","CliAuth"],"mappings":";;;;;;;;AAoBA,MAAM,mBAAA,GAAsBA,KAAE,KAAA,CAAMA,IAAA,CAAE,QAAQ,CAAA,CAAE,OAAA,CAAQ,EAAE,CAAA;AAE1D,kBAAe,OAAO,EAAE,IAAA,EAAM,IAAA,EAAK,KAAyB;AAC1D,EAAAC,SAAA,CAAI,EAAE,IAAA,EAAM,IAAA,EAAK,EAAG,QAAW,IAAI,CAAA;AAEnC,EAAA,MAAM,IAAA,GAAO,MAAMC,eAAA,CAAQ,MAAA,EAAO;AAClC,EAAA,MAAM,UAAU,mBAAA,CAAoB,KAAA;AAAA,IAClC,MAAM,IAAA,CAAK,WAAA,CAAY,eAAe;AAAA,GACxC;AAEA,EAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACnB,IAAA,OAAA,CAAQ,MAAA,CAAO,MAAM,iCAAiC,CAAA;AACtD,IAAA;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,MAAM;AAAA,CAAI,CAAA;AAAA,EACpC;AACF,CAAA;;;;"}
1
+ {"version":3,"file":"sourcesList.cjs.js","sources":["../../src/commands/sourcesList.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cli } from 'cleye';\nimport { CliAuth, type CliCommandContext } from '@backstage/cli-node';\nimport { pluginSourcesSchema } from '../lib/pluginSources';\n\nexport default async ({ args, info }: CliCommandContext) => {\n cli({ help: info }, undefined, args);\n\n const auth = await CliAuth.create();\n const sources = pluginSourcesSchema.parse(\n await auth.getMetadata('pluginSources'),\n );\n\n if (!sources.length) {\n process.stderr.write('No plugin sources configured.\\n');\n return;\n }\n\n for (const source of sources) {\n process.stdout.write(`${source}\\n`);\n }\n};\n"],"names":["cli","CliAuth","pluginSourcesSchema"],"mappings":";;;;;;;;AAoBA,kBAAe,OAAO,EAAE,IAAA,EAAM,IAAA,EAAK,KAAyB;AAC1D,EAAAA,SAAA,CAAI,EAAE,IAAA,EAAM,IAAA,EAAK,EAAG,QAAW,IAAI,CAAA;AAEnC,EAAA,MAAM,IAAA,GAAO,MAAMC,eAAA,CAAQ,MAAA,EAAO;AAClC,EAAA,MAAM,UAAUC,iCAAA,CAAoB,KAAA;AAAA,IAClC,MAAM,IAAA,CAAK,WAAA,CAAY,eAAe;AAAA,GACxC;AAEA,EAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACnB,IAAA,OAAA,CAAQ,MAAA,CAAO,MAAM,iCAAiC,CAAA;AACtD,IAAA;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,MAAM;AAAA,CAAI,CAAA;AAAA,EACpC;AACF,CAAA;;;;"}
@@ -4,34 +4,47 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var cleye = require('cleye');
6
6
  var cliNode = require('@backstage/cli-node');
7
- var v3 = require('zod/v3');
7
+ var pluginSources = require('../lib/pluginSources.cjs.js');
8
8
 
9
- const pluginSourcesSchema = v3.z.array(v3.z.string()).default([]);
10
9
  var sourcesRemove = async ({ args, info }) => {
11
10
  const parsed = cleye.cli(
12
11
  {
13
12
  help: info,
14
- parameters: ["<plugin-id>"]
13
+ parameters: ["<plugin-ids...>"]
15
14
  },
16
15
  void 0,
17
16
  args
18
17
  );
19
- const pluginId = parsed._[0];
18
+ const pluginIds = parsed._.pluginIds;
20
19
  const auth = await cliNode.CliAuth.create();
21
- const existing = pluginSourcesSchema.parse(
20
+ const existing = pluginSources.pluginSourcesSchema.parse(
22
21
  await auth.getMetadata("pluginSources")
23
22
  );
24
- if (!existing.includes(pluginId)) {
25
- process.stderr.write(`Plugin source "${pluginId}" is not configured.
26
- `);
27
- return;
23
+ const removed = [];
24
+ const skipped = [];
25
+ for (const pluginId of pluginIds) {
26
+ if (existing.includes(pluginId)) {
27
+ removed.push(pluginId);
28
+ } else {
29
+ skipped.push(pluginId);
30
+ }
28
31
  }
29
- await auth.setMetadata(
30
- "pluginSources",
31
- existing.filter((s) => s !== pluginId)
32
- );
33
- process.stdout.write(`Removed plugin source "${pluginId}".
32
+ if (removed.length > 0) {
33
+ await auth.setMetadata(
34
+ "pluginSources",
35
+ existing.filter((s) => !removed.includes(s))
36
+ );
37
+ process.stdout.write(
38
+ `Removed plugin source${removed.length > 1 ? "s" : ""}: ${removed.join(
39
+ ", "
40
+ )}
41
+ `
42
+ );
43
+ }
44
+ for (const id of skipped) {
45
+ process.stderr.write(`Plugin source "${id}" is not configured.
34
46
  `);
47
+ }
35
48
  };
36
49
 
37
50
  exports.default = sourcesRemove;
@@ -1 +1 @@
1
- {"version":3,"file":"sourcesRemove.cjs.js","sources":["../../src/commands/sourcesRemove.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cli } from 'cleye';\nimport { CliAuth, type CliCommandContext } from '@backstage/cli-node';\nimport { z } from 'zod/v3';\n\nconst pluginSourcesSchema = z.array(z.string()).default([]);\n\nexport default async ({ args, info }: CliCommandContext) => {\n const parsed = cli(\n {\n help: info,\n parameters: ['<plugin-id>'],\n },\n undefined,\n args,\n );\n\n const pluginId = parsed._[0];\n\n const auth = await CliAuth.create();\n const existing = pluginSourcesSchema.parse(\n await auth.getMetadata('pluginSources'),\n );\n\n if (!existing.includes(pluginId)) {\n process.stderr.write(`Plugin source \"${pluginId}\" is not configured.\\n`);\n return;\n }\n\n await auth.setMetadata(\n 'pluginSources',\n existing.filter(s => s !== pluginId),\n );\n\n process.stdout.write(`Removed plugin source \"${pluginId}\".\\n`);\n};\n"],"names":["z","cli","CliAuth"],"mappings":";;;;;;;;AAoBA,MAAM,mBAAA,GAAsBA,KAAE,KAAA,CAAMA,IAAA,CAAE,QAAQ,CAAA,CAAE,OAAA,CAAQ,EAAE,CAAA;AAE1D,oBAAe,OAAO,EAAE,IAAA,EAAM,IAAA,EAAK,KAAyB;AAC1D,EAAA,MAAM,MAAA,GAASC,SAAA;AAAA,IACb;AAAA,MACE,IAAA,EAAM,IAAA;AAAA,MACN,UAAA,EAAY,CAAC,aAAa;AAAA,KAC5B;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,CAAA,CAAE,CAAC,CAAA;AAE3B,EAAA,MAAM,IAAA,GAAO,MAAMC,eAAA,CAAQ,MAAA,EAAO;AAClC,EAAA,MAAM,WAAW,mBAAA,CAAoB,KAAA;AAAA,IACnC,MAAM,IAAA,CAAK,WAAA,CAAY,eAAe;AAAA,GACxC;AAEA,EAAA,IAAI,CAAC,QAAA,CAAS,QAAA,CAAS,QAAQ,CAAA,EAAG;AAChC,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,eAAA,EAAkB,QAAQ,CAAA;AAAA,CAAwB,CAAA;AACvE,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,IAAA,CAAK,WAAA;AAAA,IACT,eAAA;AAAA,IACA,QAAA,CAAS,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,KAAM,QAAQ;AAAA,GACrC;AAEA,EAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,uBAAA,EAA0B,QAAQ,CAAA;AAAA,CAAM,CAAA;AAC/D,CAAA;;;;"}
1
+ {"version":3,"file":"sourcesRemove.cjs.js","sources":["../../src/commands/sourcesRemove.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cli } from 'cleye';\nimport { CliAuth, type CliCommandContext } from '@backstage/cli-node';\nimport { pluginSourcesSchema } from '../lib/pluginSources';\n\nexport default async ({ args, info }: CliCommandContext) => {\n const parsed = cli(\n {\n help: info,\n parameters: ['<plugin-ids...>'],\n },\n undefined,\n args,\n );\n\n const pluginIds: string[] = parsed._.pluginIds;\n\n const auth = await CliAuth.create();\n const existing = pluginSourcesSchema.parse(\n await auth.getMetadata('pluginSources'),\n );\n\n const removed: string[] = [];\n const skipped: string[] = [];\n\n for (const pluginId of pluginIds) {\n if (existing.includes(pluginId)) {\n removed.push(pluginId);\n } else {\n skipped.push(pluginId);\n }\n }\n\n if (removed.length > 0) {\n await auth.setMetadata(\n 'pluginSources',\n existing.filter(s => !removed.includes(s)),\n );\n process.stdout.write(\n `Removed plugin source${removed.length > 1 ? 's' : ''}: ${removed.join(\n ', ',\n )}\\n`,\n );\n }\n\n for (const id of skipped) {\n process.stderr.write(`Plugin source \"${id}\" is not configured.\\n`);\n }\n};\n"],"names":["cli","CliAuth","pluginSourcesSchema"],"mappings":";;;;;;;;AAoBA,oBAAe,OAAO,EAAE,IAAA,EAAM,IAAA,EAAK,KAAyB;AAC1D,EAAA,MAAM,MAAA,GAASA,SAAA;AAAA,IACb;AAAA,MACE,IAAA,EAAM,IAAA;AAAA,MACN,UAAA,EAAY,CAAC,iBAAiB;AAAA,KAChC;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,SAAA,GAAsB,OAAO,CAAA,CAAE,SAAA;AAErC,EAAA,MAAM,IAAA,GAAO,MAAMC,eAAA,CAAQ,MAAA,EAAO;AAClC,EAAA,MAAM,WAAWC,iCAAA,CAAoB,KAAA;AAAA,IACnC,MAAM,IAAA,CAAK,WAAA,CAAY,eAAe;AAAA,GACxC;AAEA,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,MAAM,UAAoB,EAAC;AAE3B,EAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,IAAA,IAAI,QAAA,CAAS,QAAA,CAAS,QAAQ,CAAA,EAAG;AAC/B,MAAA,OAAA,CAAQ,KAAK,QAAQ,CAAA;AAAA,IACvB,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,KAAK,QAAQ,CAAA;AAAA,IACvB;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,IAAA,MAAM,IAAA,CAAK,WAAA;AAAA,MACT,eAAA;AAAA,MACA,SAAS,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,OAAA,CAAQ,QAAA,CAAS,CAAC,CAAC;AAAA,KAC3C;AACA,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA;AAAA,MACb,wBAAwB,OAAA,CAAQ,MAAA,GAAS,IAAI,GAAA,GAAM,EAAE,KAAK,OAAA,CAAQ,IAAA;AAAA,QAChE;AAAA,OACD;AAAA;AAAA,KACH;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,MAAM,OAAA,EAAS;AACxB,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,eAAA,EAAkB,EAAE,CAAA;AAAA,CAAwB,CAAA;AAAA,EACnE;AACF,CAAA;;;;"}
@@ -23,20 +23,21 @@ class ActionsClient {
23
23
  this.accessToken = accessToken;
24
24
  }
25
25
  async list(pluginSources) {
26
- const results = [];
27
- for (const pluginId of pluginSources) {
28
- const url = pluginActionsUrl(this.baseUrl, pluginId);
29
- const response = await httpJson.httpJson(url, {
30
- headers: { Authorization: `Bearer ${this.accessToken}` },
31
- signal: AbortSignal.timeout(3e4)
32
- });
33
- results.push(...response.actions);
34
- }
35
- return results;
26
+ return Promise.all(
27
+ pluginSources.map(async (pluginId) => {
28
+ const url = pluginActionsUrl(this.baseUrl, pluginId);
29
+ const response = await httpJson.httpJson(url, {
30
+ headers: { Authorization: `Bearer ${this.accessToken}` },
31
+ signal: AbortSignal.timeout(3e4)
32
+ });
33
+ return { pluginId, actions: response.actions };
34
+ })
35
+ );
36
36
  }
37
37
  async listForPlugin(actionId) {
38
38
  const pluginId = extractPluginId(actionId);
39
- return this.list([pluginId]);
39
+ const grouped = await this.list([pluginId]);
40
+ return grouped.flatMap((g) => g.actions);
40
41
  }
41
42
  async execute(actionId, input) {
42
43
  const pluginId = extractPluginId(actionId);
@@ -1 +1 @@
1
- {"version":3,"file":"ActionsClient.cjs.js","sources":["../../src/lib/ActionsClient.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { httpJson } from './httpJson';\n\nexport type ActionDef = {\n id: string;\n name: string;\n description?: string;\n schema: {\n input: object;\n output: object;\n };\n};\n\ntype ListActionsResponse = {\n actions: ActionDef[];\n};\n\ntype InvokeResponse = {\n output: unknown;\n};\n\nfunction extractPluginId(actionId: string): string {\n const colonIndex = actionId.indexOf(':');\n if (colonIndex === -1) {\n throw new Error(\n `Invalid action ID \"${actionId}\". Expected format \"pluginId:actionName\".`,\n );\n }\n return actionId.substring(0, colonIndex);\n}\n\nfunction pluginActionsUrl(baseUrl: string, pluginId: string): string {\n return new URL(\n `/api/${encodeURIComponent(pluginId)}/.backstage/actions/v1/actions`,\n baseUrl,\n ).toString();\n}\n\nexport class ActionsClient {\n constructor(\n private readonly baseUrl: string,\n private readonly accessToken: string,\n ) {}\n\n async list(pluginSources: string[]): Promise<ActionDef[]> {\n const results: ActionDef[] = [];\n\n for (const pluginId of pluginSources) {\n const url = pluginActionsUrl(this.baseUrl, pluginId);\n\n const response = await httpJson<ListActionsResponse>(url, {\n headers: { Authorization: `Bearer ${this.accessToken}` },\n signal: AbortSignal.timeout(30_000),\n });\n\n results.push(...response.actions);\n }\n\n return results;\n }\n\n async listForPlugin(actionId: string): Promise<ActionDef[]> {\n const pluginId = extractPluginId(actionId);\n return this.list([pluginId]);\n }\n\n async execute(actionId: string, input?: unknown): Promise<unknown> {\n const pluginId = extractPluginId(actionId);\n const url = `${pluginActionsUrl(\n this.baseUrl,\n pluginId,\n )}/${encodeURIComponent(actionId)}/invoke`;\n\n const response = await httpJson<InvokeResponse>(url, {\n method: 'POST',\n headers: { Authorization: `Bearer ${this.accessToken}` },\n body: input ?? {},\n signal: AbortSignal.timeout(30_000),\n });\n\n return response.output;\n }\n}\n"],"names":["httpJson"],"mappings":";;;;AAoCA,SAAS,gBAAgB,QAAA,EAA0B;AACjD,EAAA,MAAM,UAAA,GAAa,QAAA,CAAS,OAAA,CAAQ,GAAG,CAAA;AACvC,EAAA,IAAI,eAAe,EAAA,EAAI;AACrB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,sBAAsB,QAAQ,CAAA,yCAAA;AAAA,KAChC;AAAA,EACF;AACA,EAAA,OAAO,QAAA,CAAS,SAAA,CAAU,CAAA,EAAG,UAAU,CAAA;AACzC;AAEA,SAAS,gBAAA,CAAiB,SAAiB,QAAA,EAA0B;AACnE,EAAA,OAAO,IAAI,GAAA;AAAA,IACT,CAAA,KAAA,EAAQ,kBAAA,CAAmB,QAAQ,CAAC,CAAA,8BAAA,CAAA;AAAA,IACpC;AAAA,IACA,QAAA,EAAS;AACb;AAEO,MAAM,aAAA,CAAc;AAAA,EACzB,WAAA,CACmB,SACA,WAAA,EACjB;AAFiB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AACA,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AAAA,EAChB;AAAA,EAEH,MAAM,KAAK,aAAA,EAA+C;AACxD,IAAA,MAAM,UAAuB,EAAC;AAE9B,IAAA,KAAA,MAAW,YAAY,aAAA,EAAe;AACpC,MAAA,MAAM,GAAA,GAAM,gBAAA,CAAiB,IAAA,CAAK,OAAA,EAAS,QAAQ,CAAA;AAEnD,MAAA,MAAM,QAAA,GAAW,MAAMA,iBAAA,CAA8B,GAAA,EAAK;AAAA,QACxD,SAAS,EAAE,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,WAAW,CAAA,CAAA,EAAG;AAAA,QACvD,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,GAAM;AAAA,OACnC,CAAA;AAED,MAAA,OAAA,CAAQ,IAAA,CAAK,GAAG,QAAA,CAAS,OAAO,CAAA;AAAA,IAClC;AAEA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,QAAA,EAAwC;AAC1D,IAAA,MAAM,QAAA,GAAW,gBAAgB,QAAQ,CAAA;AACzC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,CAAC,QAAQ,CAAC,CAAA;AAAA,EAC7B;AAAA,EAEA,MAAM,OAAA,CAAQ,QAAA,EAAkB,KAAA,EAAmC;AACjE,IAAA,MAAM,QAAA,GAAW,gBAAgB,QAAQ,CAAA;AACzC,IAAA,MAAM,MAAM,CAAA,EAAG,gBAAA;AAAA,MACb,IAAA,CAAK,OAAA;AAAA,MACL;AAAA,KACD,CAAA,CAAA,EAAI,kBAAA,CAAmB,QAAQ,CAAC,CAAA,OAAA,CAAA;AAEjC,IAAA,MAAM,QAAA,GAAW,MAAMA,iBAAA,CAAyB,GAAA,EAAK;AAAA,MACnD,MAAA,EAAQ,MAAA;AAAA,MACR,SAAS,EAAE,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,WAAW,CAAA,CAAA,EAAG;AAAA,MACvD,IAAA,EAAM,SAAS,EAAC;AAAA,MAChB,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,GAAM;AAAA,KACnC,CAAA;AAED,IAAA,OAAO,QAAA,CAAS,MAAA;AAAA,EAClB;AACF;;;;"}
1
+ {"version":3,"file":"ActionsClient.cjs.js","sources":["../../src/lib/ActionsClient.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { httpJson } from './httpJson';\n\nexport type ActionDef = {\n id: string;\n name: string;\n title?: string;\n description?: string;\n schema: {\n input: object;\n output: object;\n };\n};\n\ntype ListActionsResponse = {\n actions: ActionDef[];\n};\n\ntype InvokeResponse = {\n output: unknown;\n};\n\nfunction extractPluginId(actionId: string): string {\n const colonIndex = actionId.indexOf(':');\n if (colonIndex === -1) {\n throw new Error(\n `Invalid action ID \"${actionId}\". Expected format \"pluginId:actionName\".`,\n );\n }\n return actionId.substring(0, colonIndex);\n}\n\nfunction pluginActionsUrl(baseUrl: string, pluginId: string): string {\n return new URL(\n `/api/${encodeURIComponent(pluginId)}/.backstage/actions/v1/actions`,\n baseUrl,\n ).toString();\n}\n\nexport type GroupedActions = { pluginId: string; actions: ActionDef[] }[];\n\nexport class ActionsClient {\n constructor(\n private readonly baseUrl: string,\n private readonly accessToken: string,\n ) {}\n\n async list(pluginSources: string[]): Promise<GroupedActions> {\n return Promise.all(\n pluginSources.map(async pluginId => {\n const url = pluginActionsUrl(this.baseUrl, pluginId);\n const response = await httpJson<ListActionsResponse>(url, {\n headers: { Authorization: `Bearer ${this.accessToken}` },\n signal: AbortSignal.timeout(30_000),\n });\n return { pluginId, actions: response.actions };\n }),\n );\n }\n\n async listForPlugin(actionId: string): Promise<ActionDef[]> {\n const pluginId = extractPluginId(actionId);\n const grouped = await this.list([pluginId]);\n return grouped.flatMap(g => g.actions);\n }\n\n async execute(actionId: string, input?: unknown): Promise<unknown> {\n const pluginId = extractPluginId(actionId);\n const url = `${pluginActionsUrl(\n this.baseUrl,\n pluginId,\n )}/${encodeURIComponent(actionId)}/invoke`;\n\n const response = await httpJson<InvokeResponse>(url, {\n method: 'POST',\n headers: { Authorization: `Bearer ${this.accessToken}` },\n body: input ?? {},\n signal: AbortSignal.timeout(30_000),\n });\n\n return response.output;\n }\n}\n"],"names":["httpJson"],"mappings":";;;;AAqCA,SAAS,gBAAgB,QAAA,EAA0B;AACjD,EAAA,MAAM,UAAA,GAAa,QAAA,CAAS,OAAA,CAAQ,GAAG,CAAA;AACvC,EAAA,IAAI,eAAe,EAAA,EAAI;AACrB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,sBAAsB,QAAQ,CAAA,yCAAA;AAAA,KAChC;AAAA,EACF;AACA,EAAA,OAAO,QAAA,CAAS,SAAA,CAAU,CAAA,EAAG,UAAU,CAAA;AACzC;AAEA,SAAS,gBAAA,CAAiB,SAAiB,QAAA,EAA0B;AACnE,EAAA,OAAO,IAAI,GAAA;AAAA,IACT,CAAA,KAAA,EAAQ,kBAAA,CAAmB,QAAQ,CAAC,CAAA,8BAAA,CAAA;AAAA,IACpC;AAAA,IACA,QAAA,EAAS;AACb;AAIO,MAAM,aAAA,CAAc;AAAA,EACzB,WAAA,CACmB,SACA,WAAA,EACjB;AAFiB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AACA,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AAAA,EAChB;AAAA,EAEH,MAAM,KAAK,aAAA,EAAkD;AAC3D,IAAA,OAAO,OAAA,CAAQ,GAAA;AAAA,MACb,aAAA,CAAc,GAAA,CAAI,OAAM,QAAA,KAAY;AAClC,QAAA,MAAM,GAAA,GAAM,gBAAA,CAAiB,IAAA,CAAK,OAAA,EAAS,QAAQ,CAAA;AACnD,QAAA,MAAM,QAAA,GAAW,MAAMA,iBAAA,CAA8B,GAAA,EAAK;AAAA,UACxD,SAAS,EAAE,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,WAAW,CAAA,CAAA,EAAG;AAAA,UACvD,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,GAAM;AAAA,SACnC,CAAA;AACD,QAAA,OAAO,EAAE,QAAA,EAAU,OAAA,EAAS,QAAA,CAAS,OAAA,EAAQ;AAAA,MAC/C,CAAC;AAAA,KACH;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,QAAA,EAAwC;AAC1D,IAAA,MAAM,QAAA,GAAW,gBAAgB,QAAQ,CAAA;AACzC,IAAA,MAAM,UAAU,MAAM,IAAA,CAAK,IAAA,CAAK,CAAC,QAAQ,CAAC,CAAA;AAC1C,IAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,CAAA;AAAA,EACvC;AAAA,EAEA,MAAM,OAAA,CAAQ,QAAA,EAAkB,KAAA,EAAmC;AACjE,IAAA,MAAM,QAAA,GAAW,gBAAgB,QAAQ,CAAA;AACzC,IAAA,MAAM,MAAM,CAAA,EAAG,gBAAA;AAAA,MACb,IAAA,CAAK,OAAA;AAAA,MACL;AAAA,KACD,CAAA,CAAA,EAAI,kBAAA,CAAmB,QAAQ,CAAC,CAAA,OAAA,CAAA;AAEjC,IAAA,MAAM,QAAA,GAAW,MAAMA,iBAAA,CAAyB,GAAA,EAAK;AAAA,MACnD,MAAA,EAAQ,MAAA;AAAA,MACR,SAAS,EAAE,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,WAAW,CAAA,CAAA,EAAG;AAAA,MACvD,IAAA,EAAM,SAAS,EAAC;AAAA,MAChB,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,GAAM;AAAA,KACnC,CAAA;AAED,IAAA,OAAO,QAAA,CAAS,MAAA;AAAA,EAClB;AACF;;;;"}
@@ -0,0 +1,112 @@
1
+ 'use strict';
2
+
3
+ var chalk = require('chalk');
4
+
5
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
6
+
7
+ var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
8
+
9
+ async function renderMarkdown(text) {
10
+ const { Marked } = await import('marked');
11
+ const { markedTerminal } = await import('marked-terminal');
12
+ const stripAnsi = (await import('strip-ansi')).default;
13
+ const instance = new Marked(markedTerminal());
14
+ const sanitized = stripAnsi(text);
15
+ return instance.parse(sanitized);
16
+ }
17
+ function dedent(text) {
18
+ const trimmed = text.replace(/^\n+/, "").replace(/\n+$/, "");
19
+ const lines = trimmed.split("\n");
20
+ const nonEmptyLines = lines.filter((l) => l.trim().length > 0);
21
+ if (nonEmptyLines.length === 0) return trimmed;
22
+ const minIndent = Math.min(
23
+ ...nonEmptyLines.map((l) => l.match(/^(\s*)/)[0].length)
24
+ );
25
+ if (minIndent === 0) return trimmed;
26
+ return lines.map((l) => l.slice(minIndent)).join("\n");
27
+ }
28
+ function terminalWidth() {
29
+ return process.stdout.columns || 80;
30
+ }
31
+ function formatActionList(grouped) {
32
+ const width = terminalWidth();
33
+ const lines = [];
34
+ for (let i = 0; i < grouped.length; i++) {
35
+ const { pluginId, actions } = grouped[i];
36
+ if (i > 0) {
37
+ lines.push("");
38
+ }
39
+ const header = `\u2500\u2500 ${pluginId} `;
40
+ const remaining = Math.max(0, width - header.length);
41
+ lines.push(chalk__default.default.bold(`${header}${"\u2500".repeat(remaining)}`));
42
+ lines.push("");
43
+ if (actions.length === 0) {
44
+ lines.push(` ${chalk__default.default.dim("(no actions)")}`);
45
+ continue;
46
+ }
47
+ const maxIdLen = Math.max(...actions.map((a) => a.id.length));
48
+ const idColWidth = maxIdLen + 4;
49
+ for (const action of actions) {
50
+ const paddedId = action.id.padEnd(idColWidth);
51
+ if (!action.title) {
52
+ lines.push(` ${chalk__default.default.cyan(paddedId.trimEnd())}`);
53
+ continue;
54
+ }
55
+ lines.push(` ${chalk__default.default.cyan(paddedId)}${chalk__default.default.dim(action.title)}`);
56
+ }
57
+ }
58
+ return lines.join("\n");
59
+ }
60
+ const typeHintNames = {
61
+ String: "string",
62
+ Number: "number",
63
+ Boolean: ""
64
+ };
65
+ function flagDefsToFlagInfo(defs) {
66
+ return Object.entries(defs).map(([name, def]) => ({
67
+ name,
68
+ type: typeHintNames[def.type.name] ?? "string",
69
+ description: def.description
70
+ }));
71
+ }
72
+ async function formatActionHelp(options) {
73
+ const { action, usage, flags } = options;
74
+ const lines = [];
75
+ lines.push(chalk__default.default.bold.cyan(action.id));
76
+ if (action.title) {
77
+ lines.push(` ${action.title}`);
78
+ }
79
+ if (action.description) {
80
+ lines.push("");
81
+ const dedented = dedent(action.description);
82
+ const rendered = await renderMarkdown(dedented);
83
+ lines.push(rendered.trimEnd());
84
+ }
85
+ lines.push("");
86
+ lines.push(chalk__default.default.bold("Usage:"));
87
+ lines.push(` ${usage} ${chalk__default.default.dim("[flags]")}`);
88
+ if (flags.length > 0) {
89
+ lines.push("");
90
+ lines.push(chalk__default.default.bold("Flags:"));
91
+ const maxFlagLen = Math.max(
92
+ ...flags.map((f) => {
93
+ const typeHint = f.type ? ` <${f.type}>` : "";
94
+ return ` --${f.name}${typeHint}`.length;
95
+ })
96
+ );
97
+ const colWidth = maxFlagLen + 4;
98
+ for (const flag of flags) {
99
+ const typeHint = flag.type ? ` <${flag.type}>` : "";
100
+ const left = ` --${flag.name}${typeHint}`.padEnd(colWidth);
101
+ const desc = flag.description ? chalk__default.default.dim(flag.description) : "";
102
+ lines.push(`${left}${desc}`);
103
+ }
104
+ }
105
+ lines.push("");
106
+ return lines.join("\n");
107
+ }
108
+
109
+ exports.flagDefsToFlagInfo = flagDefsToFlagInfo;
110
+ exports.formatActionHelp = formatActionHelp;
111
+ exports.formatActionList = formatActionList;
112
+ //# sourceMappingURL=format.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.cjs.js","sources":["../../src/lib/format.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport chalk from 'chalk';\nimport type { GroupedActions } from './ActionsClient';\nimport type { CleyeFlag } from './schemaToFlags';\n\nasync function renderMarkdown(text: string): Promise<string> {\n const { Marked } = await import('marked');\n const { markedTerminal } = await import('marked-terminal');\n const stripAnsi = (await import('strip-ansi')).default;\n\n const instance = new Marked(markedTerminal());\n const sanitized = stripAnsi(text);\n return instance.parse(sanitized) as string;\n}\n\nfunction dedent(text: string): string {\n const trimmed = text.replace(/^\\n+/, '').replace(/\\n+$/, '');\n const lines = trimmed.split('\\n');\n const nonEmptyLines = lines.filter(l => l.trim().length > 0);\n if (nonEmptyLines.length === 0) return trimmed;\n const minIndent = Math.min(\n ...nonEmptyLines.map(l => l.match(/^(\\s*)/)![0].length),\n );\n if (minIndent === 0) return trimmed;\n return lines.map(l => l.slice(minIndent)).join('\\n');\n}\n\nfunction terminalWidth(): number {\n return process.stdout.columns || 80;\n}\n\nexport function formatActionList(grouped: GroupedActions): string {\n const width = terminalWidth();\n const lines: string[] = [];\n\n for (let i = 0; i < grouped.length; i++) {\n const { pluginId, actions } = grouped[i];\n\n if (i > 0) {\n lines.push('');\n }\n\n const header = `── ${pluginId} `;\n const remaining = Math.max(0, width - header.length);\n lines.push(chalk.bold(`${header}${'─'.repeat(remaining)}`));\n lines.push('');\n\n if (actions.length === 0) {\n lines.push(` ${chalk.dim('(no actions)')}`);\n continue;\n }\n\n const maxIdLen = Math.max(...actions.map(a => a.id.length));\n const idColWidth = maxIdLen + 4;\n\n for (const action of actions) {\n const paddedId = action.id.padEnd(idColWidth);\n\n if (!action.title) {\n lines.push(` ${chalk.cyan(paddedId.trimEnd())}`);\n continue;\n }\n\n lines.push(` ${chalk.cyan(paddedId)}${chalk.dim(action.title)}`);\n }\n }\n\n return lines.join('\\n');\n}\n\nexport type FlagInfo = {\n name: string;\n type: string;\n description?: string;\n};\n\nconst typeHintNames: Record<string, string> = {\n String: 'string',\n Number: 'number',\n Boolean: '',\n};\n\nexport function flagDefsToFlagInfo(\n defs: Record<string, CleyeFlag>,\n): FlagInfo[] {\n return Object.entries(defs).map(([name, def]) => ({\n name,\n type: typeHintNames[def.type.name] ?? 'string',\n description: def.description,\n }));\n}\n\nexport async function formatActionHelp(options: {\n action: {\n id: string;\n title?: string;\n description?: string;\n };\n usage: string;\n flags: FlagInfo[];\n}): Promise<string> {\n const { action, usage, flags } = options;\n const lines: string[] = [];\n\n lines.push(chalk.bold.cyan(action.id));\n\n if (action.title) {\n lines.push(` ${action.title}`);\n }\n\n if (action.description) {\n lines.push('');\n const dedented = dedent(action.description);\n const rendered = await renderMarkdown(dedented);\n lines.push(rendered.trimEnd());\n }\n\n lines.push('');\n lines.push(chalk.bold('Usage:'));\n lines.push(` ${usage} ${chalk.dim('[flags]')}`);\n\n if (flags.length > 0) {\n lines.push('');\n lines.push(chalk.bold('Flags:'));\n\n const maxFlagLen = Math.max(\n ...flags.map(f => {\n const typeHint = f.type ? ` <${f.type}>` : '';\n return ` --${f.name}${typeHint}`.length;\n }),\n );\n const colWidth = maxFlagLen + 4;\n\n for (const flag of flags) {\n const typeHint = flag.type ? ` <${flag.type}>` : '';\n const left = ` --${flag.name}${typeHint}`.padEnd(colWidth);\n const desc = flag.description ? chalk.dim(flag.description) : '';\n lines.push(`${left}${desc}`);\n }\n }\n\n lines.push('');\n return lines.join('\\n');\n}\n"],"names":["chalk"],"mappings":"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"}
@@ -12,7 +12,12 @@ async function httpJson(url, init) {
12
12
  }
13
13
  });
14
14
  if (!res.ok) {
15
- throw await errors.ResponseError.fromResponse(res);
15
+ const responseError = await errors.ResponseError.fromResponse(res);
16
+ const causeMessage = responseError.cause?.message;
17
+ throw new Error(
18
+ causeMessage || `Request failed with ${res.status} ${res.statusText}`,
19
+ { cause: responseError }
20
+ );
16
21
  }
17
22
  return await res.json();
18
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"httpJson.cjs.js","sources":["../../src/lib/httpJson.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ResponseError } from '@backstage/errors';\n\ntype HttpInit = {\n headers?: Record<string, string>;\n method?: string;\n body?: any;\n signal?: AbortSignal;\n};\n\nexport async function httpJson<T>(url: string, init?: HttpInit): Promise<T> {\n const res = await fetch(url, {\n ...init,\n body: init?.body ? JSON.stringify(init.body) : undefined,\n headers: {\n ...(init?.body ? { 'Content-Type': 'application/json' } : {}),\n ...init?.headers,\n },\n });\n if (!res.ok) {\n throw await ResponseError.fromResponse(res);\n }\n return (await res.json()) as T;\n}\n"],"names":["ResponseError"],"mappings":";;;;AAyBA,eAAsB,QAAA,CAAY,KAAa,IAAA,EAA6B;AAC1E,EAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,IAC3B,GAAG,IAAA;AAAA,IACH,MAAM,IAAA,EAAM,IAAA,GAAO,KAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA,GAAI,MAAA;AAAA,IAC/C,OAAA,EAAS;AAAA,MACP,GAAI,IAAA,EAAM,IAAA,GAAO,EAAE,cAAA,EAAgB,kBAAA,KAAuB,EAAC;AAAA,MAC3D,GAAG,IAAA,EAAM;AAAA;AACX,GACD,CAAA;AACD,EAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,IAAA,MAAM,MAAMA,oBAAA,CAAc,YAAA,CAAa,GAAG,CAAA;AAAA,EAC5C;AACA,EAAA,OAAQ,MAAM,IAAI,IAAA,EAAK;AACzB;;;;"}
1
+ {"version":3,"file":"httpJson.cjs.js","sources":["../../src/lib/httpJson.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ResponseError } from '@backstage/errors';\n\ntype HttpInit = {\n headers?: Record<string, string>;\n method?: string;\n body?: any;\n signal?: AbortSignal;\n};\n\nexport async function httpJson<T>(url: string, init?: HttpInit): Promise<T> {\n const res = await fetch(url, {\n ...init,\n body: init?.body ? JSON.stringify(init.body) : undefined,\n headers: {\n ...(init?.body ? { 'Content-Type': 'application/json' } : {}),\n ...init?.headers,\n },\n });\n if (!res.ok) {\n const responseError = await ResponseError.fromResponse(res);\n const causeMessage = responseError.cause?.message;\n throw new Error(\n causeMessage || `Request failed with ${res.status} ${res.statusText}`,\n { cause: responseError },\n );\n }\n return (await res.json()) as T;\n}\n"],"names":["ResponseError"],"mappings":";;;;AAyBA,eAAsB,QAAA,CAAY,KAAa,IAAA,EAA6B;AAC1E,EAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,IAC3B,GAAG,IAAA;AAAA,IACH,MAAM,IAAA,EAAM,IAAA,GAAO,KAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA,GAAI,MAAA;AAAA,IAC/C,OAAA,EAAS;AAAA,MACP,GAAI,IAAA,EAAM,IAAA,GAAO,EAAE,cAAA,EAAgB,kBAAA,KAAuB,EAAC;AAAA,MAC3D,GAAG,IAAA,EAAM;AAAA;AACX,GACD,CAAA;AACD,EAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,IAAA,MAAM,aAAA,GAAgB,MAAMA,oBAAA,CAAc,YAAA,CAAa,GAAG,CAAA;AAC1D,IAAA,MAAM,YAAA,GAAe,cAAc,KAAA,EAAO,OAAA;AAC1C,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,gBAAgB,CAAA,oBAAA,EAAuB,GAAA,CAAI,MAAM,CAAA,CAAA,EAAI,IAAI,UAAU,CAAA,CAAA;AAAA,MACnE,EAAE,OAAO,aAAA;AAAc,KACzB;AAAA,EACF;AACA,EAAA,OAAQ,MAAM,IAAI,IAAA,EAAK;AACzB;;;;"}
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ var v3 = require('zod/v3');
4
+
5
+ const pluginSourcesSchema = v3.z.array(v3.z.string()).default([]);
6
+
7
+ exports.pluginSourcesSchema = pluginSourcesSchema;
8
+ //# sourceMappingURL=pluginSources.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginSources.cjs.js","sources":["../../src/lib/pluginSources.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from 'zod/v3';\n\nexport const pluginSourcesSchema = z.array(z.string()).default([]);\n"],"names":["z"],"mappings":";;;;AAkBO,MAAM,mBAAA,GAAsBA,KAAE,KAAA,CAAMA,IAAA,CAAE,QAAQ,CAAA,CAAE,OAAA,CAAQ,EAAE;;;;"}
@@ -1,20 +1,19 @@
1
1
  'use strict';
2
2
 
3
3
  var cliNode = require('@backstage/cli-node');
4
- var v3 = require('zod/v3');
4
+ var pluginSources = require('./pluginSources.cjs.js');
5
5
 
6
- const pluginSourcesSchema = v3.z.array(v3.z.string()).default([]);
7
6
  async function resolveAuth(instanceFlag) {
8
7
  const auth = await cliNode.CliAuth.create({ instanceName: instanceFlag });
9
8
  const accessToken = await auth.getAccessToken();
10
- const pluginSources = pluginSourcesSchema.parse(
9
+ const pluginSources$1 = pluginSources.pluginSourcesSchema.parse(
11
10
  await auth.getMetadata("pluginSources")
12
11
  );
13
12
  return {
14
13
  baseUrl: auth.getBaseUrl(),
15
14
  instanceName: auth.getInstanceName(),
16
15
  accessToken,
17
- pluginSources
16
+ pluginSources: pluginSources$1
18
17
  };
19
18
  }
20
19
 
@@ -1 +1 @@
1
- {"version":3,"file":"resolveAuth.cjs.js","sources":["../../src/lib/resolveAuth.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CliAuth } from '@backstage/cli-node';\nimport { z } from 'zod/v3';\n\nconst pluginSourcesSchema = z.array(z.string()).default([]);\n\nexport async function resolveAuth(instanceFlag?: string): Promise<{\n baseUrl: string;\n instanceName: string;\n accessToken: string;\n pluginSources: string[];\n}> {\n const auth = await CliAuth.create({ instanceName: instanceFlag });\n const accessToken = await auth.getAccessToken();\n const pluginSources = pluginSourcesSchema.parse(\n await auth.getMetadata('pluginSources'),\n );\n\n return {\n baseUrl: auth.getBaseUrl(),\n instanceName: auth.getInstanceName(),\n accessToken,\n pluginSources,\n };\n}\n"],"names":["z","CliAuth"],"mappings":";;;;;AAmBA,MAAM,mBAAA,GAAsBA,KAAE,KAAA,CAAMA,IAAA,CAAE,QAAQ,CAAA,CAAE,OAAA,CAAQ,EAAE,CAAA;AAE1D,eAAsB,YAAY,YAAA,EAK/B;AACD,EAAA,MAAM,OAAO,MAAMC,eAAA,CAAQ,OAAO,EAAE,YAAA,EAAc,cAAc,CAAA;AAChE,EAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,cAAA,EAAe;AAC9C,EAAA,MAAM,gBAAgB,mBAAA,CAAoB,KAAA;AAAA,IACxC,MAAM,IAAA,CAAK,WAAA,CAAY,eAAe;AAAA,GACxC;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,KAAK,UAAA,EAAW;AAAA,IACzB,YAAA,EAAc,KAAK,eAAA,EAAgB;AAAA,IACnC,WAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
1
+ {"version":3,"file":"resolveAuth.cjs.js","sources":["../../src/lib/resolveAuth.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CliAuth } from '@backstage/cli-node';\nimport { pluginSourcesSchema } from './pluginSources';\n\nexport async function resolveAuth(instanceFlag?: string): Promise<{\n baseUrl: string;\n instanceName: string;\n accessToken: string;\n pluginSources: string[];\n}> {\n const auth = await CliAuth.create({ instanceName: instanceFlag });\n const accessToken = await auth.getAccessToken();\n const pluginSources = pluginSourcesSchema.parse(\n await auth.getMetadata('pluginSources'),\n );\n\n return {\n baseUrl: auth.getBaseUrl(),\n instanceName: auth.getInstanceName(),\n accessToken,\n pluginSources,\n };\n}\n"],"names":["CliAuth","pluginSources","pluginSourcesSchema"],"mappings":";;;;;AAmBA,eAAsB,YAAY,YAAA,EAK/B;AACD,EAAA,MAAM,OAAO,MAAMA,eAAA,CAAQ,OAAO,EAAE,YAAA,EAAc,cAAc,CAAA;AAChE,EAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,cAAA,EAAe;AAC9C,EAAA,MAAMC,kBAAgBC,iCAAA,CAAoB,KAAA;AAAA,IACxC,MAAM,IAAA,CAAK,WAAA,CAAY,eAAe;AAAA,GACxC;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,KAAK,UAAA,EAAW;AAAA,IACzB,YAAA,EAAc,KAAK,eAAA,EAAgB;AAAA,IACnC,WAAA;AAAA,mBACAD;AAAA,GACF;AACF;;;;"}
@@ -1,24 +1,42 @@
1
1
  'use strict';
2
2
 
3
+ function isComplexType(prop) {
4
+ if (prop.anyOf || prop.oneOf || prop.allOf) {
5
+ return true;
6
+ }
7
+ const rawType = Array.isArray(prop.type) ? prop.type[0] : prop.type;
8
+ return rawType === "object" || rawType === "array";
9
+ }
10
+ function resolveFlagType(rawType) {
11
+ if (rawType === "string") return String;
12
+ if (rawType === "number" || rawType === "integer") return Number;
13
+ if (rawType === "boolean") return Boolean;
14
+ return void 0;
15
+ }
3
16
  function schemaToFlags(schema) {
4
17
  const flags = {};
18
+ const complexKeys = /* @__PURE__ */ new Set();
5
19
  const required = new Set(schema.required ?? []);
6
20
  if (!schema.properties) {
7
- return flags;
21
+ return { flags, complexKeys };
8
22
  }
9
23
  for (const [key, prop] of Object.entries(schema.properties)) {
10
24
  const rawType = Array.isArray(prop.type) ? prop.type[0] : prop.type;
11
- let flagType;
12
- if (rawType === "string") {
25
+ const complex = isComplexType(prop);
26
+ let flagType = resolveFlagType(rawType);
27
+ if (!flagType && complex) {
13
28
  flagType = String;
14
- } else if (rawType === "number" || rawType === "integer") {
15
- flagType = Number;
16
- } else if (rawType === "boolean") {
17
- flagType = Boolean;
18
- } else {
29
+ }
30
+ if (!flagType) {
19
31
  continue;
20
32
  }
33
+ if (complex) {
34
+ complexKeys.add(key);
35
+ }
21
36
  let desc = prop.description ?? "";
37
+ if (complex) {
38
+ desc = desc ? `${desc} (JSON)` : "(JSON)";
39
+ }
22
40
  if (prop.enum?.length) {
23
41
  const values = prop.enum.map((v) => String(v)).join(", ");
24
42
  desc = desc ? `${desc} [${values}]` : `[${values}]`;
@@ -32,7 +50,7 @@ function schemaToFlags(schema) {
32
50
  }
33
51
  flags[key] = flag;
34
52
  }
35
- return flags;
53
+ return { flags, complexKeys };
36
54
  }
37
55
 
38
56
  exports.schemaToFlags = schemaToFlags;
@@ -1 +1 @@
1
- {"version":3,"file":"schemaToFlags.cjs.js","sources":["../../src/lib/schemaToFlags.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ntype JsonSchemaProperty = {\n type?: string | string[];\n description?: string;\n enum?: unknown[];\n default?: unknown;\n};\n\ntype JsonSchemaObject = {\n properties?: Record<string, JsonSchemaProperty>;\n required?: string[];\n};\n\ntype CleyeFlag = {\n type: StringConstructor | NumberConstructor | BooleanConstructor;\n description?: string;\n default?: unknown;\n};\n\nexport function schemaToFlags(\n schema: JsonSchemaObject,\n): Record<string, CleyeFlag> {\n const flags: Record<string, CleyeFlag> = {};\n const required = new Set(schema.required ?? []);\n\n if (!schema.properties) {\n return flags;\n }\n\n for (const [key, prop] of Object.entries(schema.properties)) {\n const rawType = Array.isArray(prop.type) ? prop.type[0] : prop.type;\n\n let flagType: StringConstructor | NumberConstructor | BooleanConstructor;\n if (rawType === 'string') {\n flagType = String;\n } else if (rawType === 'number' || rawType === 'integer') {\n flagType = Number;\n } else if (rawType === 'boolean') {\n flagType = Boolean;\n } else {\n continue;\n }\n\n let desc = prop.description ?? '';\n if (prop.enum?.length) {\n const values = prop.enum.map(v => String(v)).join(', ');\n desc = desc ? `${desc} [${values}]` : `[${values}]`;\n }\n if (required.has(key)) {\n desc = desc ? `${desc} (required)` : '(required)';\n }\n\n const flag: CleyeFlag = { type: flagType, description: desc || undefined };\n if (prop.default !== undefined) {\n flag.default = prop.default;\n }\n\n flags[key] = flag;\n }\n\n return flags;\n}\n"],"names":[],"mappings":";;AAkCO,SAAS,cACd,MAAA,EAC2B;AAC3B,EAAA,MAAM,QAAmC,EAAC;AAC1C,EAAA,MAAM,WAAW,IAAI,GAAA,CAAI,MAAA,CAAO,QAAA,IAAY,EAAE,CAAA;AAE9C,EAAA,IAAI,CAAC,OAAO,UAAA,EAAY;AACtB,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,KAAA,MAAW,CAAC,KAAK,IAAI,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,UAAU,CAAA,EAAG;AAC3D,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,IAAI,IAAI,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA,CAAK,IAAA;AAE/D,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI,YAAY,QAAA,EAAU;AACxB,MAAA,QAAA,GAAW,MAAA;AAAA,IACb,CAAA,MAAA,IAAW,OAAA,KAAY,QAAA,IAAY,OAAA,KAAY,SAAA,EAAW;AACxD,MAAA,QAAA,GAAW,MAAA;AAAA,IACb,CAAA,MAAA,IAAW,YAAY,SAAA,EAAW;AAChC,MAAA,QAAA,GAAW,OAAA;AAAA,IACb,CAAA,MAAO;AACL,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,IAAA,GAAO,KAAK,WAAA,IAAe,EAAA;AAC/B,IAAA,IAAI,IAAA,CAAK,MAAM,MAAA,EAAQ;AACrB,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,CAAA,CAAA,KAAK,OAAO,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AACtD,MAAA,IAAA,GAAO,OAAO,CAAA,EAAG,IAAI,KAAK,MAAM,CAAA,CAAA,CAAA,GAAM,IAAI,MAAM,CAAA,CAAA,CAAA;AAAA,IAClD;AACA,IAAA,IAAI,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA,EAAG;AACrB,MAAA,IAAA,GAAO,IAAA,GAAO,CAAA,EAAG,IAAI,CAAA,WAAA,CAAA,GAAgB,YAAA;AAAA,IACvC;AAEA,IAAA,MAAM,OAAkB,EAAE,IAAA,EAAM,QAAA,EAAU,WAAA,EAAa,QAAQ,MAAA,EAAU;AACzE,IAAA,IAAI,IAAA,CAAK,YAAY,MAAA,EAAW;AAC9B,MAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AAAA,IACtB;AAEA,IAAA,KAAA,CAAM,GAAG,CAAA,GAAI,IAAA;AAAA,EACf;AAEA,EAAA,OAAO,KAAA;AACT;;;;"}
1
+ {"version":3,"file":"schemaToFlags.cjs.js","sources":["../../src/lib/schemaToFlags.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ntype JsonSchemaProperty = {\n type?: string | string[];\n description?: string;\n enum?: unknown[];\n default?: unknown;\n anyOf?: unknown[];\n oneOf?: unknown[];\n allOf?: unknown[];\n};\n\ntype JsonSchemaObject = {\n properties?: Record<string, JsonSchemaProperty>;\n required?: string[];\n};\n\nexport type CleyeFlag = {\n type: StringConstructor | NumberConstructor | BooleanConstructor;\n description?: string;\n default?: unknown;\n};\n\nfunction isComplexType(prop: JsonSchemaProperty): boolean {\n if (prop.anyOf || prop.oneOf || prop.allOf) {\n return true;\n }\n const rawType = Array.isArray(prop.type) ? prop.type[0] : prop.type;\n return rawType === 'object' || rawType === 'array';\n}\n\nfunction resolveFlagType(\n rawType: string | undefined,\n): StringConstructor | NumberConstructor | BooleanConstructor | undefined {\n if (rawType === 'string') return String;\n if (rawType === 'number' || rawType === 'integer') return Number;\n if (rawType === 'boolean') return Boolean;\n return undefined;\n}\n\nexport function schemaToFlags(schema: JsonSchemaObject): {\n flags: Record<string, CleyeFlag>;\n complexKeys: Set<string>;\n} {\n const flags: Record<string, CleyeFlag> = {};\n const complexKeys = new Set<string>();\n const required = new Set(schema.required ?? []);\n\n if (!schema.properties) {\n return { flags, complexKeys };\n }\n\n for (const [key, prop] of Object.entries(schema.properties)) {\n const rawType = Array.isArray(prop.type) ? prop.type[0] : prop.type;\n const complex = isComplexType(prop);\n let flagType = resolveFlagType(rawType);\n\n if (!flagType && complex) {\n flagType = String;\n }\n\n if (!flagType) {\n continue;\n }\n\n if (complex) {\n complexKeys.add(key);\n }\n\n let desc = prop.description ?? '';\n\n if (complex) {\n desc = desc ? `${desc} (JSON)` : '(JSON)';\n }\n\n if (prop.enum?.length) {\n const values = prop.enum.map(v => String(v)).join(', ');\n desc = desc ? `${desc} [${values}]` : `[${values}]`;\n }\n if (required.has(key)) {\n desc = desc ? `${desc} (required)` : '(required)';\n }\n\n const flag: CleyeFlag = { type: flagType, description: desc || undefined };\n if (prop.default !== undefined) {\n flag.default = prop.default;\n }\n\n flags[key] = flag;\n }\n\n return { flags, complexKeys };\n}\n"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var name = "@backstage/cli-module-actions";
6
- var version = "0.0.2-next.0";
6
+ var version = "0.1.0";
7
7
  var description = "CLI module for executing distributed actions";
8
8
  var backstage = {
9
9
  role: "cli-module"
@@ -38,7 +38,11 @@ var scripts = {
38
38
  var dependencies = {
39
39
  "@backstage/cli-node": "workspace:^",
40
40
  "@backstage/errors": "workspace:^",
41
+ chalk: "^4.0.0",
41
42
  cleye: "^2.3.0",
43
+ marked: "^15.0.12",
44
+ "marked-terminal": "^7.3.0",
45
+ "strip-ansi": "^7.1.0",
42
46
  zod: "^3.25.76 || ^4.0.0"
43
47
  };
44
48
  var devDependencies = {
@@ -1 +1 @@
1
- {"version":3,"file":"package.json.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"package.json.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/cli-module-actions",
3
- "version": "0.0.2-next.0",
3
+ "version": "0.1.0",
4
4
  "description": "CLI module for executing distributed actions",
5
5
  "backstage": {
6
6
  "role": "cli-module"
@@ -33,14 +33,18 @@
33
33
  "test": "backstage-cli package test"
34
34
  },
35
35
  "dependencies": {
36
- "@backstage/cli-node": "0.3.1-next.0",
37
- "@backstage/errors": "1.2.7",
36
+ "@backstage/cli-node": "^0.3.1",
37
+ "@backstage/errors": "^1.3.0",
38
+ "chalk": "^4.0.0",
38
39
  "cleye": "^2.3.0",
40
+ "marked": "^15.0.12",
41
+ "marked-terminal": "^7.3.0",
42
+ "strip-ansi": "^7.1.0",
39
43
  "zod": "^3.25.76 || ^4.0.0"
40
44
  },
41
45
  "devDependencies": {
42
- "@backstage/backend-test-utils": "1.11.2-next.0",
43
- "@backstage/cli": "0.36.1-next.0"
46
+ "@backstage/backend-test-utils": "^1.11.2",
47
+ "@backstage/cli": "^0.36.1"
44
48
  },
45
49
  "typesVersions": {
46
50
  "*": {