@qodalis/cli-curl 0.0.3 → 2.0.0-beta.1
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 +15 -22
- package/public-api.d.mts +86 -0
- package/public-api.d.ts +86 -2
- package/public-api.js +369 -0
- package/public-api.js.map +1 -0
- package/public-api.mjs +357 -0
- package/public-api.mjs.map +1 -0
- package/umd/cli-entrypoint.global.js +3033 -0
- package/README.md +0 -21
- package/esm2022/lib/cli-curl.module.mjs +0 -19
- package/esm2022/lib/processors/cli-curl-command-processor.mjs +0 -218
- package/esm2022/lib/version.mjs +0 -3
- package/esm2022/public-api.mjs +0 -6
- package/esm2022/qodalis-cli-curl.mjs +0 -5
- package/fesm2022/qodalis-cli-curl.mjs +0 -247
- package/fesm2022/qodalis-cli-curl.mjs.map +0 -1
- package/index.d.ts +0 -5
- package/lib/cli-curl.module.d.ts +0 -6
- package/lib/processors/cli-curl-command-processor.d.ts +0 -20
- package/lib/version.d.ts +0 -1
- package/umd/index.js +0 -257
package/package.json
CHANGED
|
@@ -1,44 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qodalis/cli-curl",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.0.0-beta.1",
|
|
4
|
+
"description": "@qodalis/cli extension for making HTTP requests via a curl-like interface.",
|
|
5
5
|
"author": "Nicolae Lupei, Qodalis Solutions",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/qodalis-solutions/
|
|
9
|
+
"url": "https://github.com/qodalis-solutions/web-cli"
|
|
10
10
|
},
|
|
11
11
|
"homepage": "https://qodalis.com",
|
|
12
12
|
"keywords": [
|
|
13
|
-
"angular",
|
|
14
13
|
"cli",
|
|
15
14
|
"qodalis",
|
|
16
15
|
"terminal",
|
|
17
|
-
"curl"
|
|
16
|
+
"curl",
|
|
17
|
+
"http",
|
|
18
|
+
"requests",
|
|
19
|
+
"fetch"
|
|
18
20
|
],
|
|
19
21
|
"umd": "./umd/index.js",
|
|
20
22
|
"unpkg": "./umd/index.js",
|
|
21
|
-
"peerDependencies": {
|
|
22
|
-
"@angular/common": "^16.2.0",
|
|
23
|
-
"@angular/core": "^16.2.0"
|
|
24
|
-
},
|
|
25
23
|
"dependencies": {
|
|
26
|
-
"
|
|
27
|
-
"@qodalis/cli-core": "^0.0.11",
|
|
28
|
-
"@qodalis/angular-cli": "^1.0.26"
|
|
24
|
+
"@qodalis/cli-core": "2.0.0-beta.1"
|
|
29
25
|
},
|
|
30
26
|
"sideEffects": false,
|
|
31
|
-
"
|
|
32
|
-
"
|
|
27
|
+
"main": "./public-api.js",
|
|
28
|
+
"module": "./public-api.mjs",
|
|
29
|
+
"types": "./public-api.d.ts",
|
|
33
30
|
"exports": {
|
|
34
|
-
"./package.json": {
|
|
35
|
-
"default": "./package.json"
|
|
36
|
-
},
|
|
37
31
|
".": {
|
|
38
|
-
"types": "./
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"default": "./fesm2022/qodalis-cli-curl.mjs"
|
|
32
|
+
"types": "./public-api.d.ts",
|
|
33
|
+
"import": "./public-api.mjs",
|
|
34
|
+
"require": "./public-api.js"
|
|
42
35
|
}
|
|
43
36
|
}
|
|
44
|
-
}
|
|
37
|
+
}
|
package/public-api.d.mts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import * as _qodalis_cli_core from '@qodalis/cli-core';
|
|
2
|
+
import { ICliCommandProcessor, CliProcessorMetadata, CliProcessCommand, ICliExecutionContext, ICliModule } from '@qodalis/cli-core';
|
|
3
|
+
|
|
4
|
+
interface CurlRequestOptions {
|
|
5
|
+
method: string;
|
|
6
|
+
headers: Record<string, string>;
|
|
7
|
+
body?: string;
|
|
8
|
+
followRedirects: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface CurlResponse {
|
|
11
|
+
status: number;
|
|
12
|
+
statusText: string;
|
|
13
|
+
headers: Record<string, string>;
|
|
14
|
+
body: string;
|
|
15
|
+
timing: number;
|
|
16
|
+
url: string;
|
|
17
|
+
redirected: boolean;
|
|
18
|
+
}
|
|
19
|
+
declare function inferMethod(explicitMethod?: string, hasBody?: boolean): string;
|
|
20
|
+
declare function parseHeaders(headerArgs: string | string[] | undefined): Record<string, string>;
|
|
21
|
+
declare function resolveBody(data?: string, dataRaw?: string): string | undefined;
|
|
22
|
+
declare function isJsonBody(body?: string): boolean;
|
|
23
|
+
declare function buildFetchOptions(options: CurlRequestOptions): RequestInit;
|
|
24
|
+
declare function formatResponseBody(body: string, pretty: boolean): string;
|
|
25
|
+
declare function rewriteUrlToProxy(originalUrl: string): string;
|
|
26
|
+
declare function buildCurlEquivalent(url: string, method: string, headers: Record<string, string>, body?: string): string;
|
|
27
|
+
declare function extractResponseHeaders(response: Response): Record<string, string>;
|
|
28
|
+
|
|
29
|
+
declare class CliCurlCommandProcessor implements ICliCommandProcessor {
|
|
30
|
+
command: string;
|
|
31
|
+
description: string;
|
|
32
|
+
author: _qodalis_cli_core.ICliCommandAuthor;
|
|
33
|
+
version: string;
|
|
34
|
+
valueRequired: boolean;
|
|
35
|
+
metadata?: CliProcessorMetadata;
|
|
36
|
+
parameters: ({
|
|
37
|
+
name: string;
|
|
38
|
+
aliases: string[];
|
|
39
|
+
type: "string";
|
|
40
|
+
description: string;
|
|
41
|
+
required: boolean;
|
|
42
|
+
defaultValue?: undefined;
|
|
43
|
+
} | {
|
|
44
|
+
name: string;
|
|
45
|
+
aliases: string[];
|
|
46
|
+
type: "array";
|
|
47
|
+
description: string;
|
|
48
|
+
required: boolean;
|
|
49
|
+
defaultValue?: undefined;
|
|
50
|
+
} | {
|
|
51
|
+
name: string;
|
|
52
|
+
type: "string";
|
|
53
|
+
description: string;
|
|
54
|
+
required: boolean;
|
|
55
|
+
aliases?: undefined;
|
|
56
|
+
defaultValue?: undefined;
|
|
57
|
+
} | {
|
|
58
|
+
name: string;
|
|
59
|
+
aliases: string[];
|
|
60
|
+
type: "boolean";
|
|
61
|
+
description: string;
|
|
62
|
+
required: boolean;
|
|
63
|
+
defaultValue?: undefined;
|
|
64
|
+
} | {
|
|
65
|
+
name: string;
|
|
66
|
+
type: "boolean";
|
|
67
|
+
description: string;
|
|
68
|
+
required: boolean;
|
|
69
|
+
aliases?: undefined;
|
|
70
|
+
defaultValue?: undefined;
|
|
71
|
+
} | {
|
|
72
|
+
name: string;
|
|
73
|
+
type: "number";
|
|
74
|
+
description: string;
|
|
75
|
+
required: boolean;
|
|
76
|
+
defaultValue: string;
|
|
77
|
+
aliases?: undefined;
|
|
78
|
+
})[];
|
|
79
|
+
processCommand(command: CliProcessCommand, context: ICliExecutionContext): Promise<void>;
|
|
80
|
+
writeDescription(context: ICliExecutionContext): void;
|
|
81
|
+
initialize(_context: ICliExecutionContext): Promise<void>;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
declare const curlModule: ICliModule;
|
|
85
|
+
|
|
86
|
+
export { CliCurlCommandProcessor, type CurlRequestOptions, type CurlResponse, buildCurlEquivalent, buildFetchOptions, curlModule, extractResponseHeaders, formatResponseBody, inferMethod, isJsonBody, parseHeaders, resolveBody, rewriteUrlToProxy };
|
package/public-api.d.ts
CHANGED
|
@@ -1,2 +1,86 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import * as _qodalis_cli_core from '@qodalis/cli-core';
|
|
2
|
+
import { ICliCommandProcessor, CliProcessorMetadata, CliProcessCommand, ICliExecutionContext, ICliModule } from '@qodalis/cli-core';
|
|
3
|
+
|
|
4
|
+
interface CurlRequestOptions {
|
|
5
|
+
method: string;
|
|
6
|
+
headers: Record<string, string>;
|
|
7
|
+
body?: string;
|
|
8
|
+
followRedirects: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface CurlResponse {
|
|
11
|
+
status: number;
|
|
12
|
+
statusText: string;
|
|
13
|
+
headers: Record<string, string>;
|
|
14
|
+
body: string;
|
|
15
|
+
timing: number;
|
|
16
|
+
url: string;
|
|
17
|
+
redirected: boolean;
|
|
18
|
+
}
|
|
19
|
+
declare function inferMethod(explicitMethod?: string, hasBody?: boolean): string;
|
|
20
|
+
declare function parseHeaders(headerArgs: string | string[] | undefined): Record<string, string>;
|
|
21
|
+
declare function resolveBody(data?: string, dataRaw?: string): string | undefined;
|
|
22
|
+
declare function isJsonBody(body?: string): boolean;
|
|
23
|
+
declare function buildFetchOptions(options: CurlRequestOptions): RequestInit;
|
|
24
|
+
declare function formatResponseBody(body: string, pretty: boolean): string;
|
|
25
|
+
declare function rewriteUrlToProxy(originalUrl: string): string;
|
|
26
|
+
declare function buildCurlEquivalent(url: string, method: string, headers: Record<string, string>, body?: string): string;
|
|
27
|
+
declare function extractResponseHeaders(response: Response): Record<string, string>;
|
|
28
|
+
|
|
29
|
+
declare class CliCurlCommandProcessor implements ICliCommandProcessor {
|
|
30
|
+
command: string;
|
|
31
|
+
description: string;
|
|
32
|
+
author: _qodalis_cli_core.ICliCommandAuthor;
|
|
33
|
+
version: string;
|
|
34
|
+
valueRequired: boolean;
|
|
35
|
+
metadata?: CliProcessorMetadata;
|
|
36
|
+
parameters: ({
|
|
37
|
+
name: string;
|
|
38
|
+
aliases: string[];
|
|
39
|
+
type: "string";
|
|
40
|
+
description: string;
|
|
41
|
+
required: boolean;
|
|
42
|
+
defaultValue?: undefined;
|
|
43
|
+
} | {
|
|
44
|
+
name: string;
|
|
45
|
+
aliases: string[];
|
|
46
|
+
type: "array";
|
|
47
|
+
description: string;
|
|
48
|
+
required: boolean;
|
|
49
|
+
defaultValue?: undefined;
|
|
50
|
+
} | {
|
|
51
|
+
name: string;
|
|
52
|
+
type: "string";
|
|
53
|
+
description: string;
|
|
54
|
+
required: boolean;
|
|
55
|
+
aliases?: undefined;
|
|
56
|
+
defaultValue?: undefined;
|
|
57
|
+
} | {
|
|
58
|
+
name: string;
|
|
59
|
+
aliases: string[];
|
|
60
|
+
type: "boolean";
|
|
61
|
+
description: string;
|
|
62
|
+
required: boolean;
|
|
63
|
+
defaultValue?: undefined;
|
|
64
|
+
} | {
|
|
65
|
+
name: string;
|
|
66
|
+
type: "boolean";
|
|
67
|
+
description: string;
|
|
68
|
+
required: boolean;
|
|
69
|
+
aliases?: undefined;
|
|
70
|
+
defaultValue?: undefined;
|
|
71
|
+
} | {
|
|
72
|
+
name: string;
|
|
73
|
+
type: "number";
|
|
74
|
+
description: string;
|
|
75
|
+
required: boolean;
|
|
76
|
+
defaultValue: string;
|
|
77
|
+
aliases?: undefined;
|
|
78
|
+
})[];
|
|
79
|
+
processCommand(command: CliProcessCommand, context: ICliExecutionContext): Promise<void>;
|
|
80
|
+
writeDescription(context: ICliExecutionContext): void;
|
|
81
|
+
initialize(_context: ICliExecutionContext): Promise<void>;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
declare const curlModule: ICliModule;
|
|
85
|
+
|
|
86
|
+
export { CliCurlCommandProcessor, type CurlRequestOptions, type CurlResponse, buildCurlEquivalent, buildFetchOptions, curlModule, extractResponseHeaders, formatResponseBody, inferMethod, isJsonBody, parseHeaders, resolveBody, rewriteUrlToProxy };
|
package/public-api.js
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var cliCore = require('@qodalis/cli-core');
|
|
4
|
+
|
|
5
|
+
// src/lib/utilities/index.ts
|
|
6
|
+
var VALID_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
|
|
7
|
+
function inferMethod(explicitMethod, hasBody) {
|
|
8
|
+
if (explicitMethod) {
|
|
9
|
+
const upper = explicitMethod.toUpperCase();
|
|
10
|
+
if (!VALID_METHODS.includes(upper)) {
|
|
11
|
+
throw new Error(`Invalid HTTP method: ${explicitMethod}. Valid methods: ${VALID_METHODS.join(", ")}`);
|
|
12
|
+
}
|
|
13
|
+
return upper;
|
|
14
|
+
}
|
|
15
|
+
return hasBody ? "POST" : "GET";
|
|
16
|
+
}
|
|
17
|
+
function parseHeaders(headerArgs) {
|
|
18
|
+
if (!headerArgs) return {};
|
|
19
|
+
const arr = Array.isArray(headerArgs) ? headerArgs : [headerArgs];
|
|
20
|
+
const result = {};
|
|
21
|
+
for (const header of arr) {
|
|
22
|
+
const colonIndex = header.indexOf(":");
|
|
23
|
+
if (colonIndex === -1) continue;
|
|
24
|
+
const key = header.substring(0, colonIndex).trim();
|
|
25
|
+
const value = header.substring(colonIndex + 1).trim();
|
|
26
|
+
if (key) result[key] = value;
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
function resolveBody(data, dataRaw) {
|
|
31
|
+
if (dataRaw != null) return dataRaw;
|
|
32
|
+
if (data == null) return void 0;
|
|
33
|
+
try {
|
|
34
|
+
return JSON.stringify(JSON.parse(data));
|
|
35
|
+
} catch {
|
|
36
|
+
return data;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function isJsonBody(body) {
|
|
40
|
+
if (!body) return false;
|
|
41
|
+
try {
|
|
42
|
+
JSON.parse(body);
|
|
43
|
+
return true;
|
|
44
|
+
} catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function buildFetchOptions(options) {
|
|
49
|
+
const headers = { ...options.headers };
|
|
50
|
+
if (options.body && !headers["Content-Type"] && isJsonBody(options.body)) {
|
|
51
|
+
headers["Content-Type"] = "application/json";
|
|
52
|
+
}
|
|
53
|
+
const init = {
|
|
54
|
+
method: options.method,
|
|
55
|
+
headers
|
|
56
|
+
};
|
|
57
|
+
if (options.body && options.method !== "GET" && options.method !== "HEAD") {
|
|
58
|
+
init.body = options.body;
|
|
59
|
+
}
|
|
60
|
+
if (!options.followRedirects) {
|
|
61
|
+
init.redirect = "manual";
|
|
62
|
+
}
|
|
63
|
+
return init;
|
|
64
|
+
}
|
|
65
|
+
function formatResponseBody(body, pretty) {
|
|
66
|
+
if (!pretty) return body;
|
|
67
|
+
try {
|
|
68
|
+
return JSON.stringify(JSON.parse(body), null, 2);
|
|
69
|
+
} catch {
|
|
70
|
+
return body;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function rewriteUrlToProxy(originalUrl) {
|
|
74
|
+
const match = originalUrl.match(/^(https?):\/\/([^\/]+)(\/.*)?$/i);
|
|
75
|
+
if (!match) {
|
|
76
|
+
throw new Error(`Invalid URL: ${originalUrl}`);
|
|
77
|
+
}
|
|
78
|
+
const scheme = match[1];
|
|
79
|
+
const domain = match[2];
|
|
80
|
+
const path = match[3] || "/";
|
|
81
|
+
return `https://proxy.qodalis.com/proxy/${scheme}/${domain}${path}`;
|
|
82
|
+
}
|
|
83
|
+
function buildCurlEquivalent(url, method, headers, body) {
|
|
84
|
+
const parts = ["curl"];
|
|
85
|
+
if (method !== "GET") {
|
|
86
|
+
parts.push(`-X ${method}`);
|
|
87
|
+
}
|
|
88
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
89
|
+
parts.push(`-H '${key}: ${value}'`);
|
|
90
|
+
}
|
|
91
|
+
if (body) {
|
|
92
|
+
parts.push(`-d '${body}'`);
|
|
93
|
+
}
|
|
94
|
+
parts.push(`'${url}'`);
|
|
95
|
+
return parts.join(" ");
|
|
96
|
+
}
|
|
97
|
+
function extractResponseHeaders(response) {
|
|
98
|
+
const headers = {};
|
|
99
|
+
response.headers.forEach((value, key) => {
|
|
100
|
+
headers[key] = value;
|
|
101
|
+
});
|
|
102
|
+
return headers;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// src/lib/version.ts
|
|
106
|
+
var LIBRARY_VERSION = "2.0.0-beta.1";
|
|
107
|
+
var API_VERSION = 2;
|
|
108
|
+
|
|
109
|
+
// src/lib/processors/cli-curl-command-processor.ts
|
|
110
|
+
var CliCurlCommandProcessor = class {
|
|
111
|
+
constructor() {
|
|
112
|
+
this.command = "curl";
|
|
113
|
+
this.description = "Make HTTP requests from the terminal. Supports all HTTP methods, custom headers, request bodies, timeouts, and more.";
|
|
114
|
+
this.author = cliCore.DefaultLibraryAuthor;
|
|
115
|
+
this.version = LIBRARY_VERSION;
|
|
116
|
+
this.valueRequired = true;
|
|
117
|
+
this.metadata = {
|
|
118
|
+
icon: "\u{1F310}",
|
|
119
|
+
requiredCoreVersion: ">=2.0.0 <3.0.0",
|
|
120
|
+
requiredCliVersion: ">=2.0.0 <3.0.0"
|
|
121
|
+
};
|
|
122
|
+
this.parameters = [
|
|
123
|
+
{
|
|
124
|
+
name: "request",
|
|
125
|
+
aliases: ["X"],
|
|
126
|
+
type: "string",
|
|
127
|
+
description: "HTTP method (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)",
|
|
128
|
+
required: false
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: "header",
|
|
132
|
+
aliases: ["H"],
|
|
133
|
+
type: "array",
|
|
134
|
+
description: "Add header, e.g. -H 'Content-Type: application/json' (repeatable)",
|
|
135
|
+
required: false
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: "data",
|
|
139
|
+
aliases: ["d"],
|
|
140
|
+
type: "string",
|
|
141
|
+
description: "Request body (auto-detects JSON, sets method to POST if -X not given)",
|
|
142
|
+
required: false
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
name: "data-raw",
|
|
146
|
+
type: "string",
|
|
147
|
+
description: "Request body sent as-is without JSON parsing",
|
|
148
|
+
required: false
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
name: "verbose",
|
|
152
|
+
aliases: ["v"],
|
|
153
|
+
type: "boolean",
|
|
154
|
+
description: "Show request/response headers and timing",
|
|
155
|
+
required: false
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: "pretty",
|
|
159
|
+
type: "boolean",
|
|
160
|
+
description: "Pretty-print JSON response body",
|
|
161
|
+
required: false
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: "timeout",
|
|
165
|
+
type: "number",
|
|
166
|
+
description: "Request timeout in milliseconds (default: 30000)",
|
|
167
|
+
required: false,
|
|
168
|
+
defaultValue: "30000"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
name: "location",
|
|
172
|
+
aliases: ["L"],
|
|
173
|
+
type: "boolean",
|
|
174
|
+
description: "Follow redirects (default: true)",
|
|
175
|
+
required: false
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: "proxy",
|
|
179
|
+
type: "boolean",
|
|
180
|
+
description: "Route request through proxy.qodalis.com (bypasses CORS)",
|
|
181
|
+
required: false
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: "silent",
|
|
185
|
+
aliases: ["s"],
|
|
186
|
+
type: "boolean",
|
|
187
|
+
description: "Only output response body (no status line)",
|
|
188
|
+
required: false
|
|
189
|
+
}
|
|
190
|
+
];
|
|
191
|
+
}
|
|
192
|
+
async processCommand(command, context) {
|
|
193
|
+
const url = command.value;
|
|
194
|
+
if (!url) {
|
|
195
|
+
context.writer.writeError("URL is required. Usage: curl <url> [options]");
|
|
196
|
+
context.process.exit(1);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const args = command.args;
|
|
200
|
+
const explicitMethod = args["request"] || args["X"];
|
|
201
|
+
const data = args["data"] || args["d"];
|
|
202
|
+
const dataRaw = args["data-raw"];
|
|
203
|
+
const hasBody = data != null || dataRaw != null;
|
|
204
|
+
const verbose = !!args["verbose"] || !!args["v"];
|
|
205
|
+
const pretty = !!args["pretty"];
|
|
206
|
+
const silent = !!args["silent"] || !!args["s"];
|
|
207
|
+
const useProxy = !!args["proxy"];
|
|
208
|
+
const timeout = parseInt(args["timeout"] || "30000", 10);
|
|
209
|
+
const followRedirects = args["location"] !== false && args["L"] !== false;
|
|
210
|
+
let method;
|
|
211
|
+
try {
|
|
212
|
+
method = inferMethod(explicitMethod, hasBody);
|
|
213
|
+
} catch (e) {
|
|
214
|
+
context.writer.writeError(e.message);
|
|
215
|
+
context.process.exit(1);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const headers = parseHeaders(args["header"] || args["H"]);
|
|
219
|
+
const body = resolveBody(data, dataRaw);
|
|
220
|
+
const requestUrl = useProxy ? rewriteUrlToProxy(url) : url;
|
|
221
|
+
const fetchOptions = buildFetchOptions({
|
|
222
|
+
method,
|
|
223
|
+
headers,
|
|
224
|
+
body,
|
|
225
|
+
followRedirects
|
|
226
|
+
});
|
|
227
|
+
if (verbose) {
|
|
228
|
+
context.writer.writeln(
|
|
229
|
+
`> ${context.writer.wrapInColor(`${method} ${url}`, cliCore.CliForegroundColor.Cyan)}`
|
|
230
|
+
);
|
|
231
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
232
|
+
context.writer.writeln(
|
|
233
|
+
`> ${context.writer.wrapInColor(`${key}: ${value}`, cliCore.CliForegroundColor.Yellow)}`
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
if (body) {
|
|
237
|
+
context.writer.writeln(`> Body: ${body}`);
|
|
238
|
+
}
|
|
239
|
+
context.writer.writeln();
|
|
240
|
+
}
|
|
241
|
+
const controller = new AbortController();
|
|
242
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
243
|
+
fetchOptions.signal = controller.signal;
|
|
244
|
+
const startTime = performance.now();
|
|
245
|
+
try {
|
|
246
|
+
const response = await fetch(requestUrl, fetchOptions);
|
|
247
|
+
const elapsed = Math.round(performance.now() - startTime);
|
|
248
|
+
const responseText = await response.text();
|
|
249
|
+
const responseHeaders = extractResponseHeaders(response);
|
|
250
|
+
const curlResponse = {
|
|
251
|
+
status: response.status,
|
|
252
|
+
statusText: response.statusText,
|
|
253
|
+
headers: responseHeaders,
|
|
254
|
+
body: responseText,
|
|
255
|
+
timing: elapsed,
|
|
256
|
+
url: response.url,
|
|
257
|
+
redirected: response.redirected
|
|
258
|
+
};
|
|
259
|
+
if (!silent) {
|
|
260
|
+
const statusColor = response.ok ? cliCore.CliForegroundColor.Green : cliCore.CliForegroundColor.Red;
|
|
261
|
+
context.writer.writeln(
|
|
262
|
+
context.writer.wrapInColor(
|
|
263
|
+
`HTTP ${response.status} ${response.statusText}`,
|
|
264
|
+
statusColor
|
|
265
|
+
)
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
if (verbose) {
|
|
269
|
+
context.writer.writeln();
|
|
270
|
+
for (const [key, value] of Object.entries(responseHeaders)) {
|
|
271
|
+
context.writer.writeln(
|
|
272
|
+
`< ${context.writer.wrapInColor(`${key}: ${value}`, cliCore.CliForegroundColor.Yellow)}`
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
context.writer.writeln(
|
|
276
|
+
`< ${context.writer.wrapInColor(`Time: ${elapsed}ms`, cliCore.CliForegroundColor.Magenta)}`
|
|
277
|
+
);
|
|
278
|
+
if (response.redirected) {
|
|
279
|
+
context.writer.writeln(
|
|
280
|
+
`< ${context.writer.wrapInColor(`Redirected to: ${response.url}`, cliCore.CliForegroundColor.Cyan)}`
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
context.writer.writeln();
|
|
284
|
+
}
|
|
285
|
+
const formattedBody = formatResponseBody(responseText, pretty);
|
|
286
|
+
if (formattedBody) {
|
|
287
|
+
context.writer.writeln(formattedBody);
|
|
288
|
+
}
|
|
289
|
+
if (verbose) {
|
|
290
|
+
context.writer.writeln();
|
|
291
|
+
context.writer.writeInfo("Equivalent curl command:");
|
|
292
|
+
context.writer.writeln(buildCurlEquivalent(url, method, headers, body));
|
|
293
|
+
}
|
|
294
|
+
context.process.output(curlResponse);
|
|
295
|
+
} catch (error) {
|
|
296
|
+
if (error.name === "AbortError") {
|
|
297
|
+
context.writer.writeError(`Request timed out after ${timeout}ms`);
|
|
298
|
+
} else {
|
|
299
|
+
context.writer.writeError(`Request failed: ${error.message}`);
|
|
300
|
+
}
|
|
301
|
+
context.process.exit(1);
|
|
302
|
+
} finally {
|
|
303
|
+
clearTimeout(timeoutId);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
writeDescription(context) {
|
|
307
|
+
const { writer } = context;
|
|
308
|
+
writer.writeln(this.description);
|
|
309
|
+
writer.writeln();
|
|
310
|
+
writer.writeln(writer.wrapInColor("Usage:", cliCore.CliForegroundColor.Yellow));
|
|
311
|
+
writer.writeln(` curl <url> [options]`);
|
|
312
|
+
writer.writeln();
|
|
313
|
+
writer.writeln(writer.wrapInColor("Options:", cliCore.CliForegroundColor.Yellow));
|
|
314
|
+
writer.writeln(` ${writer.wrapInColor("-X, --request <METHOD>", cliCore.CliForegroundColor.Cyan)} HTTP method (default: GET, or POST if -d given)`);
|
|
315
|
+
writer.writeln(` ${writer.wrapInColor("-H, --header <header>", cliCore.CliForegroundColor.Cyan)} Add header (repeatable)`);
|
|
316
|
+
writer.writeln(` ${writer.wrapInColor("-d, --data <body>", cliCore.CliForegroundColor.Cyan)} Request body (auto-detects JSON)`);
|
|
317
|
+
writer.writeln(` ${writer.wrapInColor("--data-raw <body>", cliCore.CliForegroundColor.Cyan)} Request body as-is`);
|
|
318
|
+
writer.writeln(` ${writer.wrapInColor("-v, --verbose", cliCore.CliForegroundColor.Cyan)} Show headers and timing`);
|
|
319
|
+
writer.writeln(` ${writer.wrapInColor("--pretty", cliCore.CliForegroundColor.Cyan)} Pretty-print JSON response`);
|
|
320
|
+
writer.writeln(` ${writer.wrapInColor("--timeout <ms>", cliCore.CliForegroundColor.Cyan)} Timeout in ms (default: 30000)`);
|
|
321
|
+
writer.writeln(` ${writer.wrapInColor("-L, --location", cliCore.CliForegroundColor.Cyan)} Follow redirects (default: true)`);
|
|
322
|
+
writer.writeln(` ${writer.wrapInColor("--proxy", cliCore.CliForegroundColor.Cyan)} Route through CORS proxy`);
|
|
323
|
+
writer.writeln(` ${writer.wrapInColor("-s, --silent", cliCore.CliForegroundColor.Cyan)} Only output body`);
|
|
324
|
+
writer.writeln();
|
|
325
|
+
writer.writeln(writer.wrapInColor("Examples:", cliCore.CliForegroundColor.Yellow));
|
|
326
|
+
writer.writeln(` curl https://api.example.com/users`);
|
|
327
|
+
writer.writeln(` curl https://api.example.com/users -X POST -d '{"name":"John"}' -H 'Content-Type: application/json'`);
|
|
328
|
+
writer.writeln(` curl https://api.example.com/users -v --pretty`);
|
|
329
|
+
writer.writeln(` curl https://api.example.com/status -X HEAD`);
|
|
330
|
+
writer.writeln(` curl https://api.example.com/data --proxy --timeout 5000`);
|
|
331
|
+
writer.writeln();
|
|
332
|
+
writer.writeWarning("The server must allow CORS for this tool to work. Use --proxy to bypass CORS restrictions.");
|
|
333
|
+
}
|
|
334
|
+
async initialize(_context) {
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
// src/public-api.ts
|
|
339
|
+
var curlModule = {
|
|
340
|
+
apiVersion: API_VERSION,
|
|
341
|
+
name: "@qodalis/cli-curl",
|
|
342
|
+
processors: [new CliCurlCommandProcessor()],
|
|
343
|
+
translations: {
|
|
344
|
+
es: { "cli.curl.description": "Realizar solicitudes HTTP desde la terminal" },
|
|
345
|
+
fr: { "cli.curl.description": "Effectuer des requ\xEAtes HTTP depuis le terminal" },
|
|
346
|
+
de: { "cli.curl.description": "HTTP-Anfragen vom Terminal ausf\xFChren" },
|
|
347
|
+
pt: { "cli.curl.description": "Fazer requisi\xE7\xF5es HTTP pelo terminal" },
|
|
348
|
+
it: { "cli.curl.description": "Eseguire richieste HTTP dal terminale" },
|
|
349
|
+
ja: { "cli.curl.description": "\u30BF\u30FC\u30DF\u30CA\u30EB\u304B\u3089HTTP\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u5B9F\u884C" },
|
|
350
|
+
ko: { "cli.curl.description": "\uD130\uBBF8\uB110\uC5D0\uC11C HTTP \uC694\uCCAD \uC218\uD589" },
|
|
351
|
+
zh: { "cli.curl.description": "\u4ECE\u7EC8\u7AEF\u53D1\u9001 HTTP \u8BF7\u6C42" },
|
|
352
|
+
ru: { "cli.curl.description": "\u0412\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u0435 HTTP-\u0437\u0430\u043F\u0440\u043E\u0441\u043E\u0432 \u0438\u0437 \u0442\u0435\u0440\u043C\u0438\u043D\u0430\u043B\u0430" },
|
|
353
|
+
ro: { "cli.curl.description": "Efectueaz\u0103 cereri HTTP din terminal" }
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
exports.CliCurlCommandProcessor = CliCurlCommandProcessor;
|
|
358
|
+
exports.buildCurlEquivalent = buildCurlEquivalent;
|
|
359
|
+
exports.buildFetchOptions = buildFetchOptions;
|
|
360
|
+
exports.curlModule = curlModule;
|
|
361
|
+
exports.extractResponseHeaders = extractResponseHeaders;
|
|
362
|
+
exports.formatResponseBody = formatResponseBody;
|
|
363
|
+
exports.inferMethod = inferMethod;
|
|
364
|
+
exports.isJsonBody = isJsonBody;
|
|
365
|
+
exports.parseHeaders = parseHeaders;
|
|
366
|
+
exports.resolveBody = resolveBody;
|
|
367
|
+
exports.rewriteUrlToProxy = rewriteUrlToProxy;
|
|
368
|
+
//# sourceMappingURL=public-api.js.map
|
|
369
|
+
//# sourceMappingURL=public-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../packages/plugins/curl/src/lib/utilities/index.ts","../../packages/plugins/curl/src/lib/version.ts","../../packages/plugins/curl/src/lib/processors/cli-curl-command-processor.ts","../../packages/plugins/curl/src/public-api.ts"],"names":["DefaultLibraryAuthor","CliForegroundColor"],"mappings":"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","file":"public-api.js","sourcesContent":["export interface CurlRequestOptions {\n method: string;\n headers: Record<string, string>;\n body?: string;\n followRedirects: boolean;\n}\n\nexport interface CurlResponse {\n status: number;\n statusText: string;\n headers: Record<string, string>;\n body: string;\n timing: number;\n url: string;\n redirected: boolean;\n}\n\nconst VALID_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'];\n\nexport function inferMethod(explicitMethod?: string, hasBody?: boolean): string {\n if (explicitMethod) {\n const upper = explicitMethod.toUpperCase();\n if (!VALID_METHODS.includes(upper)) {\n throw new Error(`Invalid HTTP method: ${explicitMethod}. Valid methods: ${VALID_METHODS.join(', ')}`);\n }\n return upper;\n }\n return hasBody ? 'POST' : 'GET';\n}\n\nexport function parseHeaders(headerArgs: string | string[] | undefined): Record<string, string> {\n if (!headerArgs) return {};\n const arr = Array.isArray(headerArgs) ? headerArgs : [headerArgs];\n const result: Record<string, string> = {};\n for (const header of arr) {\n const colonIndex = header.indexOf(':');\n if (colonIndex === -1) continue;\n const key = header.substring(0, colonIndex).trim();\n const value = header.substring(colonIndex + 1).trim();\n if (key) result[key] = value;\n }\n return result;\n}\n\nexport function resolveBody(data?: string, dataRaw?: string): string | undefined {\n if (dataRaw != null) return dataRaw;\n if (data == null) return undefined;\n try {\n return JSON.stringify(JSON.parse(data));\n } catch {\n return data;\n }\n}\n\nexport function isJsonBody(body?: string): boolean {\n if (!body) return false;\n try {\n JSON.parse(body);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function buildFetchOptions(options: CurlRequestOptions): RequestInit {\n const headers = { ...options.headers };\n\n if (options.body && !headers['Content-Type'] && isJsonBody(options.body)) {\n headers['Content-Type'] = 'application/json';\n }\n\n const init: RequestInit = {\n method: options.method,\n headers,\n };\n\n if (options.body && options.method !== 'GET' && options.method !== 'HEAD') {\n init.body = options.body;\n }\n\n if (!options.followRedirects) {\n init.redirect = 'manual';\n }\n\n return init;\n}\n\nexport function formatResponseBody(body: string, pretty: boolean): string {\n if (!pretty) return body;\n try {\n return JSON.stringify(JSON.parse(body), null, 2);\n } catch {\n return body;\n }\n}\n\nexport function rewriteUrlToProxy(originalUrl: string): string {\n const match = originalUrl.match(/^(https?):\\/\\/([^\\/]+)(\\/.*)?$/i);\n if (!match) {\n throw new Error(`Invalid URL: ${originalUrl}`);\n }\n const scheme = match[1];\n const domain = match[2];\n const path = match[3] || '/';\n return `https://proxy.qodalis.com/proxy/${scheme}/${domain}${path}`;\n}\n\nexport function buildCurlEquivalent(\n url: string,\n method: string,\n headers: Record<string, string>,\n body?: string,\n): string {\n const parts = ['curl'];\n if (method !== 'GET') {\n parts.push(`-X ${method}`);\n }\n for (const [key, value] of Object.entries(headers)) {\n parts.push(`-H '${key}: ${value}'`);\n }\n if (body) {\n parts.push(`-d '${body}'`);\n }\n parts.push(`'${url}'`);\n return parts.join(' ');\n}\n\nexport function extractResponseHeaders(response: Response): Record<string, string> {\n const headers: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n headers[key] = value;\n });\n return headers;\n}\n","\n// Automatically generated during build\nexport const LIBRARY_VERSION = '2.0.0-beta.1';\nexport const API_VERSION = 2;\n ","import {\n CliForegroundColor,\n CliProcessCommand,\n CliProcessorMetadata,\n DefaultLibraryAuthor,\n ICliCommandProcessor,\n ICliExecutionContext,\n} from '@qodalis/cli-core';\nimport { LIBRARY_VERSION } from '../version';\nimport {\n CurlResponse,\n buildCurlEquivalent,\n buildFetchOptions,\n extractResponseHeaders,\n formatResponseBody,\n inferMethod,\n parseHeaders,\n resolveBody,\n rewriteUrlToProxy,\n} from '../utilities';\n\nexport class CliCurlCommandProcessor implements ICliCommandProcessor {\n command = 'curl';\n\n description = 'Make HTTP requests from the terminal. Supports all HTTP methods, custom headers, request bodies, timeouts, and more.';\n\n author = DefaultLibraryAuthor;\n\n version = LIBRARY_VERSION;\n\n valueRequired = true;\n\n metadata?: CliProcessorMetadata = {\n icon: '🌐',\n requiredCoreVersion: '>=2.0.0 <3.0.0',\n requiredCliVersion: '>=2.0.0 <3.0.0',\n };\n\n parameters = [\n {\n name: 'request',\n aliases: ['X'],\n type: 'string' as const,\n description: 'HTTP method (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)',\n required: false,\n },\n {\n name: 'header',\n aliases: ['H'],\n type: 'array' as const,\n description: 'Add header, e.g. -H \\'Content-Type: application/json\\' (repeatable)',\n required: false,\n },\n {\n name: 'data',\n aliases: ['d'],\n type: 'string' as const,\n description: 'Request body (auto-detects JSON, sets method to POST if -X not given)',\n required: false,\n },\n {\n name: 'data-raw',\n type: 'string' as const,\n description: 'Request body sent as-is without JSON parsing',\n required: false,\n },\n {\n name: 'verbose',\n aliases: ['v'],\n type: 'boolean' as const,\n description: 'Show request/response headers and timing',\n required: false,\n },\n {\n name: 'pretty',\n type: 'boolean' as const,\n description: 'Pretty-print JSON response body',\n required: false,\n },\n {\n name: 'timeout',\n type: 'number' as const,\n description: 'Request timeout in milliseconds (default: 30000)',\n required: false,\n defaultValue: '30000',\n },\n {\n name: 'location',\n aliases: ['L'],\n type: 'boolean' as const,\n description: 'Follow redirects (default: true)',\n required: false,\n },\n {\n name: 'proxy',\n type: 'boolean' as const,\n description: 'Route request through proxy.qodalis.com (bypasses CORS)',\n required: false,\n },\n {\n name: 'silent',\n aliases: ['s'],\n type: 'boolean' as const,\n description: 'Only output response body (no status line)',\n required: false,\n },\n ];\n\n async processCommand(\n command: CliProcessCommand,\n context: ICliExecutionContext,\n ): Promise<void> {\n const url = command.value;\n\n if (!url) {\n context.writer.writeError('URL is required. Usage: curl <url> [options]');\n context.process.exit(1);\n return;\n }\n\n const args = command.args;\n const explicitMethod = args['request'] || args['X'];\n const data = args['data'] || args['d'];\n const dataRaw = args['data-raw'];\n const hasBody = data != null || dataRaw != null;\n const verbose = !!args['verbose'] || !!args['v'];\n const pretty = !!args['pretty'];\n const silent = !!args['silent'] || !!args['s'];\n const useProxy = !!args['proxy'];\n const timeout = parseInt(args['timeout'] || '30000', 10);\n const followRedirects = args['location'] !== false && args['L'] !== false;\n\n let method: string;\n try {\n method = inferMethod(explicitMethod, hasBody);\n } catch (e: any) {\n context.writer.writeError(e.message);\n context.process.exit(1);\n return;\n }\n\n const headers = parseHeaders(args['header'] || args['H']);\n const body = resolveBody(data, dataRaw);\n const requestUrl = useProxy ? rewriteUrlToProxy(url) : url;\n\n const fetchOptions = buildFetchOptions({\n method,\n headers,\n body,\n followRedirects,\n });\n\n if (verbose) {\n context.writer.writeln(\n `> ${context.writer.wrapInColor(`${method} ${url}`, CliForegroundColor.Cyan)}`,\n );\n for (const [key, value] of Object.entries(headers)) {\n context.writer.writeln(\n `> ${context.writer.wrapInColor(`${key}: ${value}`, CliForegroundColor.Yellow)}`,\n );\n }\n if (body) {\n context.writer.writeln(`> Body: ${body}`);\n }\n context.writer.writeln();\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n fetchOptions.signal = controller.signal;\n\n const startTime = performance.now();\n\n try {\n const response = await fetch(requestUrl, fetchOptions);\n const elapsed = Math.round(performance.now() - startTime);\n const responseText = await response.text();\n const responseHeaders = extractResponseHeaders(response);\n\n const curlResponse: CurlResponse = {\n status: response.status,\n statusText: response.statusText,\n headers: responseHeaders,\n body: responseText,\n timing: elapsed,\n url: response.url,\n redirected: response.redirected,\n };\n\n if (!silent) {\n const statusColor = response.ok ? CliForegroundColor.Green : CliForegroundColor.Red;\n context.writer.writeln(\n context.writer.wrapInColor(\n `HTTP ${response.status} ${response.statusText}`,\n statusColor,\n ),\n );\n }\n\n if (verbose) {\n context.writer.writeln();\n for (const [key, value] of Object.entries(responseHeaders)) {\n context.writer.writeln(\n `< ${context.writer.wrapInColor(`${key}: ${value}`, CliForegroundColor.Yellow)}`,\n );\n }\n context.writer.writeln(\n `< ${context.writer.wrapInColor(`Time: ${elapsed}ms`, CliForegroundColor.Magenta)}`,\n );\n if (response.redirected) {\n context.writer.writeln(\n `< ${context.writer.wrapInColor(`Redirected to: ${response.url}`, CliForegroundColor.Cyan)}`,\n );\n }\n context.writer.writeln();\n }\n\n const formattedBody = formatResponseBody(responseText, pretty);\n if (formattedBody) {\n context.writer.writeln(formattedBody);\n }\n\n if (verbose) {\n context.writer.writeln();\n context.writer.writeInfo('Equivalent curl command:');\n context.writer.writeln(buildCurlEquivalent(url, method, headers, body));\n }\n\n context.process.output(curlResponse);\n } catch (error: any) {\n if (error.name === 'AbortError') {\n context.writer.writeError(`Request timed out after ${timeout}ms`);\n } else {\n context.writer.writeError(`Request failed: ${error.message}`);\n }\n context.process.exit(1);\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n writeDescription(context: ICliExecutionContext): void {\n const { writer } = context;\n\n writer.writeln(this.description!);\n writer.writeln();\n\n writer.writeln(writer.wrapInColor('Usage:', CliForegroundColor.Yellow));\n writer.writeln(` curl <url> [options]`);\n writer.writeln();\n\n writer.writeln(writer.wrapInColor('Options:', CliForegroundColor.Yellow));\n writer.writeln(` ${writer.wrapInColor('-X, --request <METHOD>', CliForegroundColor.Cyan)} HTTP method (default: GET, or POST if -d given)`);\n writer.writeln(` ${writer.wrapInColor('-H, --header <header>', CliForegroundColor.Cyan)} Add header (repeatable)`);\n writer.writeln(` ${writer.wrapInColor('-d, --data <body>', CliForegroundColor.Cyan)} Request body (auto-detects JSON)`);\n writer.writeln(` ${writer.wrapInColor('--data-raw <body>', CliForegroundColor.Cyan)} Request body as-is`);\n writer.writeln(` ${writer.wrapInColor('-v, --verbose', CliForegroundColor.Cyan)} Show headers and timing`);\n writer.writeln(` ${writer.wrapInColor('--pretty', CliForegroundColor.Cyan)} Pretty-print JSON response`);\n writer.writeln(` ${writer.wrapInColor('--timeout <ms>', CliForegroundColor.Cyan)} Timeout in ms (default: 30000)`);\n writer.writeln(` ${writer.wrapInColor('-L, --location', CliForegroundColor.Cyan)} Follow redirects (default: true)`);\n writer.writeln(` ${writer.wrapInColor('--proxy', CliForegroundColor.Cyan)} Route through CORS proxy`);\n writer.writeln(` ${writer.wrapInColor('-s, --silent', CliForegroundColor.Cyan)} Only output body`);\n writer.writeln();\n\n writer.writeln(writer.wrapInColor('Examples:', CliForegroundColor.Yellow));\n writer.writeln(` curl https://api.example.com/users`);\n writer.writeln(` curl https://api.example.com/users -X POST -d '{\"name\":\"John\"}' -H 'Content-Type: application/json'`);\n writer.writeln(` curl https://api.example.com/users -v --pretty`);\n writer.writeln(` curl https://api.example.com/status -X HEAD`);\n writer.writeln(` curl https://api.example.com/data --proxy --timeout 5000`);\n writer.writeln();\n\n writer.writeWarning('The server must allow CORS for this tool to work. Use --proxy to bypass CORS restrictions.');\n }\n\n async initialize(_context: ICliExecutionContext): Promise<void> {}\n}\n","/*\n * Public API Surface of curl\n */\n\nexport * from './lib/utilities';\nexport * from './lib/processors/cli-curl-command-processor';\n\nimport { ICliModule } from '@qodalis/cli-core';\nimport { CliCurlCommandProcessor } from './lib/processors/cli-curl-command-processor';\nimport { API_VERSION } from './lib/version';\n\nexport const curlModule: ICliModule = {\n apiVersion: API_VERSION,\n name: '@qodalis/cli-curl',\n processors: [new CliCurlCommandProcessor()],\n translations: {\n es: { 'cli.curl.description': 'Realizar solicitudes HTTP desde la terminal' },\n fr: { 'cli.curl.description': 'Effectuer des requêtes HTTP depuis le terminal' },\n de: { 'cli.curl.description': 'HTTP-Anfragen vom Terminal ausführen' },\n pt: { 'cli.curl.description': 'Fazer requisições HTTP pelo terminal' },\n it: { 'cli.curl.description': 'Eseguire richieste HTTP dal terminale' },\n ja: { 'cli.curl.description': 'ターミナルからHTTPリクエストを実行' },\n ko: { 'cli.curl.description': '터미널에서 HTTP 요청 수행' },\n zh: { 'cli.curl.description': '从终端发送 HTTP 请求' },\n ru: { 'cli.curl.description': 'Выполнение HTTP-запросов из терминала' },\n ro: { 'cli.curl.description': 'Efectuează cereri HTTP din terminal' },\n },\n};\n"]}
|