xapi-to 0.1.11 → 0.1.12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xapi-to",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "description": "Agent-friendly CLI for xapi - discover and call capabilities and APIs",
5
5
  "type": "module",
6
6
  "bin": {
package/src/client.ts CHANGED
@@ -124,13 +124,14 @@ export async function actionCall(
124
124
  actionId: string,
125
125
  input: Record<string, unknown>,
126
126
  opts: ClientOptions,
127
+ httpMethod?: string,
127
128
  ) {
128
129
  return request<unknown>(
129
130
  `${baseUrl(opts)}/v1/actions/execute`,
130
131
  {
131
132
  method: 'POST',
132
133
  headers: headers(opts.apiKey),
133
- body: JSON.stringify({ action_id: actionId, input }),
134
+ body: JSON.stringify({ action_id: actionId, ...(httpMethod ? { method: httpMethod } : {}), input }),
134
135
  },
135
136
  EXECUTE_TIMEOUT_MS,
136
137
  );
package/src/codegen.ts CHANGED
@@ -13,6 +13,7 @@ export interface CodegenParams {
13
13
  actionId: string;
14
14
  input: Record<string, unknown>;
15
15
  actionHost: string;
16
+ method?: string;
16
17
  }
17
18
 
18
19
  interface ResolvedTarget {
@@ -109,8 +110,8 @@ function baseUrl(actionHost: string): string {
109
110
  return `${scheme(actionHost)}://${actionHost}/v1/actions/execute`;
110
111
  }
111
112
 
112
- function jsonBody(actionId: string, input: Record<string, unknown>): string {
113
- return JSON.stringify({ action_id: actionId, input }, null, 2);
113
+ function jsonBody(actionId: string, input: Record<string, unknown>, method?: string): string {
114
+ return JSON.stringify({ action_id: actionId, ...(method ? { method } : {}), input }, null, 2);
114
115
  }
115
116
 
116
117
  /** Re-indent a multi-line string so continuation lines are aligned */
@@ -127,7 +128,7 @@ function shellEscape(s: string): string {
127
128
 
128
129
  function genCurl(params: CodegenParams): string {
129
130
  const url = baseUrl(params.actionHost);
130
- const body = jsonBody(params.actionId, params.input);
131
+ const body = jsonBody(params.actionId, params.input, params.method);
131
132
  return [
132
133
  '# Set XAPI_KEY env var or replace with your key',
133
134
  `curl -X POST '${shellEscape(url)}' \\`,
@@ -139,7 +140,7 @@ function genCurl(params: CodegenParams): string {
139
140
 
140
141
  function genPython(lib: 'requests' | 'httpx', params: CodegenParams): string {
141
142
  const url = baseUrl(params.actionHost);
142
- const payload = { action_id: params.actionId, input: params.input };
143
+ const payload = { action_id: params.actionId, ...(params.method ? { method: params.method } : {}), input: params.input };
143
144
  return [
144
145
  `# pip install ${lib}`,
145
146
  '# Set XAPI_KEY env var or replace with your key',
@@ -160,7 +161,7 @@ function genPython(lib: 'requests' | 'httpx', params: CodegenParams): string {
160
161
 
161
162
  function genJavaScriptFetch(params: CodegenParams): string {
162
163
  const url = baseUrl(params.actionHost);
163
- const body = jsonBody(params.actionId, params.input);
164
+ const body = jsonBody(params.actionId, params.input, params.method);
164
165
  return [
165
166
  '// Set XAPI_KEY env var or replace with your key',
166
167
  `const resp = await fetch("${url}", {`,
@@ -177,7 +178,7 @@ function genJavaScriptFetch(params: CodegenParams): string {
177
178
 
178
179
  function genJavaScriptAxios(params: CodegenParams): string {
179
180
  const url = baseUrl(params.actionHost);
180
- const body = jsonBody(params.actionId, params.input);
181
+ const body = jsonBody(params.actionId, params.input, params.method);
181
182
  return [
182
183
  '// npm install axios',
183
184
  '// Set XAPI_KEY env var or replace with your key',
@@ -199,7 +200,7 @@ function genJavaScriptAxios(params: CodegenParams): string {
199
200
 
200
201
  function genTypescriptFetch(params: CodegenParams): string {
201
202
  const url = baseUrl(params.actionHost);
202
- const body = jsonBody(params.actionId, params.input);
203
+ const body = jsonBody(params.actionId, params.input, params.method);
203
204
  return [
204
205
  '// Set XAPI_KEY env var or replace with your key',
205
206
  `const resp: Response = await fetch("${url}", {`,
@@ -217,7 +218,7 @@ function genTypescriptFetch(params: CodegenParams): string {
217
218
 
218
219
  function genGo(params: CodegenParams): string {
219
220
  const url = baseUrl(params.actionHost);
220
- const body = jsonBody(params.actionId, params.input);
221
+ const body = jsonBody(params.actionId, params.input, params.method);
221
222
  const escaped = body.replace(/`/g, '` + "`" + `');
222
223
  return [
223
224
  '// Set XAPI_KEY env var or replace with your key',
@@ -278,8 +278,8 @@ export async function actionGet(args: string[], flags: Record<string, string>) {
278
278
  );
279
279
  }
280
280
  const action = filtered[0] as any;
281
- const input = buildDefaultInput(action.input ?? {});
282
- const result = generateCode(flags.code, { actionId: id, input, actionHost: cfg.actionHost });
281
+ const { method: _schemaMethod, ...cleanCodeInput } = buildDefaultInput(action.input ?? {});
282
+ const result = generateCode(flags.code, { actionId: id, input: cleanCodeInput, actionHost: cfg.actionHost, method: action.method });
283
283
  outputCode(result, flags);
284
284
  return;
285
285
  }
@@ -303,20 +303,24 @@ export async function actionCall(args: string[], flags: Record<string, string>)
303
303
  } catch {
304
304
  err('--input must be valid JSON');
305
305
  }
306
+ if (typeof input !== 'object' || input === null || Array.isArray(input)) {
307
+ err('--input must be a JSON object');
308
+ }
306
309
  }
307
- if (flags.method) {
308
- input = { ...input, method: flags.method.toUpperCase() };
309
- }
310
+ // method 作为独立参数传递,兼容 input 内的 method
311
+ const { method: inputMethod, ...cleanInput } = input;
312
+ const method = flags.method?.toUpperCase()
313
+ || (typeof inputMethod === 'string' ? inputMethod.toUpperCase() : undefined);
310
314
 
311
315
  if (flags.code) {
312
- const result = generateCode(flags.code, { actionId: id, input, actionHost: cfg.actionHost });
316
+ const result = generateCode(flags.code, { actionId: id, input: cleanInput, actionHost: cfg.actionHost, method });
313
317
  outputCode(result, flags);
314
318
  return;
315
319
  }
316
320
 
317
321
  requireApiKey(cfg);
318
322
  try {
319
- const res = await client.actionCall(id, input, cfg);
323
+ const res = await client.actionCall(id, cleanInput, cfg, method);
320
324
  output(res, flags.format as any);
321
325
  } catch (e: any) {
322
326
  err('call failed', e.message);
package/src/index.ts CHANGED
@@ -88,6 +88,7 @@ COMMANDS
88
88
  get <id> [--method GET|POST|...] Get action schema (filter by HTTP method)
89
89
  --code <target> Generate code snippet (curl, py, js, ts, go)
90
90
  call <id> --input '{"key":"val"}' Execute an action
91
+ --method GET|POST|... Override HTTP method
91
92
  --code <target> Generate code snippet instead of executing
92
93
  Variants: python.requests, python.httpx, javascript.fetch, javascript.axios
93
94