bdy 1.25.1-stage → 1.25.2-beta
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/distTs/package.json +2 -6
- package/distTs/src/command/api/info.js +224 -255
- package/distTs/src/command/api/list.js +14 -17
- package/distTs/src/command/yaml/actions/detect.js +11 -2
- package/distTs/src/command/yaml/actions/info.js +22 -12
- package/distTs/src/command/yaml/actions/list.js +11 -20
- package/distTs/src/command/yaml/actions/schema.js +43 -87
- package/distTs/src/command/yaml/pipeline.js +9 -25
- package/distTs/src/command/yaml/render.js +83 -71
- package/distTs/src/command/yaml/schemaUtils.js +12 -50
- package/distTs/src/command/yaml/validate.js +32 -27
- package/distTs/src/diskCache.js +0 -1
- package/distTs/src/openapi.js +16 -68
- package/distTs/src/texts.js +7 -9
- package/package.json +2 -6
- package/distTs/README.md +0 -181
- package/distTs/src/autocomplete.js +0 -90
- package/distTs/src/command/autocomplete/install.js +0 -16
- package/distTs/src/command/autocomplete/uninstall.js +0 -16
- package/distTs/src/command/autocomplete.js +0 -14
- package/distTs/src/command/environment/resolve.js +0 -47
- package/distTs/src/command/package/create.js +0 -64
- package/distTs/src/command/package/delete.js +0 -38
- package/distTs/src/command/package/docker/login.js +0 -26
- package/distTs/src/command/package/docker.js +0 -11
- package/distTs/src/command/package/download.js +0 -138
- package/distTs/src/command/package/get.js +0 -36
- package/distTs/src/command/package/list.js +0 -31
- package/distTs/src/command/package/publish.js +0 -241
- package/distTs/src/command/package/version/delete.js +0 -39
- package/distTs/src/command/package/version/get.js +0 -45
- package/distTs/src/command/package/version/list.js +0 -47
- package/distTs/src/command/package/version.js +0 -16
- package/distTs/src/command/package.js +0 -26
- package/distTs/src/command/project/get.js +0 -18
- package/distTs/src/command/project/set.js +0 -31
- package/distTs/src/command/sandbox/get/yaml.js +0 -30
- package/distTs/src/command/scrape/validation.js +0 -154
- package/distTs/src/command/scrape.js +0 -144
- package/distTs/src/command/ut/upload.js +0 -86
- package/distTs/src/command/ut.js +0 -12
- package/distTs/src/command/vt/close.js +0 -27
- package/distTs/src/command/vt/compare/validation.js +0 -46
- package/distTs/src/command/vt/compare.js +0 -100
- package/distTs/src/command/vt/exec.js +0 -82
- package/distTs/src/command/vt/installBrowser.js +0 -20
- package/distTs/src/command/vt/scrape.js +0 -193
- package/distTs/src/command/vt/shared/validation.js +0 -145
- package/distTs/src/command/vt/storybook.js +0 -138
- package/distTs/src/command/vt.js +0 -20
- package/distTs/src/main.js +0 -190
- package/distTs/src/types/options.js +0 -2
- package/distTs/src/types/scrape.js +0 -2
package/distTs/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bdy",
|
|
3
3
|
"preferGlobal": false,
|
|
4
|
-
"version": "1.25.
|
|
4
|
+
"version": "1.25.2-beta",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://buddy.works/docs/cli",
|
|
@@ -50,14 +50,12 @@
|
|
|
50
50
|
],
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@buddy-works/ci-info": "1.1.7",
|
|
53
|
+
"@buddy-works/docs-schema": "0.1.3",
|
|
53
54
|
"@fastify/accept-negotiator": "2.0.1",
|
|
54
55
|
"@fastify/cors": "11.2.0",
|
|
55
56
|
"@inquirer/prompts": "8.5.2",
|
|
56
57
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
57
58
|
"@puppeteer/browsers": "3.2.0",
|
|
58
|
-
"@scalar/json-magic": "0.12.16",
|
|
59
|
-
"@scalar/openapi-parser": "0.28.7",
|
|
60
|
-
"@scalar/openapi-types": "0.9.1",
|
|
61
59
|
"@xhmikosr/decompress": "11.1.3",
|
|
62
60
|
"ajv": "8.20.0",
|
|
63
61
|
"ajv-formats": "3.0.1",
|
|
@@ -77,7 +75,6 @@
|
|
|
77
75
|
"jsonwebtoken": "9.0.3",
|
|
78
76
|
"mime-db": "1.54.0",
|
|
79
77
|
"mime-types": "3.0.2",
|
|
80
|
-
"minisearch": "7.2.0",
|
|
81
78
|
"netmask": "2.1.1",
|
|
82
79
|
"node-forge": "1.4.0",
|
|
83
80
|
"open": "11.0.0",
|
|
@@ -105,7 +102,6 @@
|
|
|
105
102
|
"@rollup/plugin-json": "6.1.0",
|
|
106
103
|
"@rollup/plugin-node-resolve": "16.0.3",
|
|
107
104
|
"@rollup/plugin-replace": "6.0.3",
|
|
108
|
-
"@scalar/types": "0.13.2",
|
|
109
105
|
"@stylistic/eslint-plugin": "5.10.0",
|
|
110
106
|
"@types/basic-auth": "1.1.8",
|
|
111
107
|
"@types/content-disposition": "0.5.9",
|
|
@@ -7,259 +7,255 @@ const utils_1 = require("../../utils");
|
|
|
7
7
|
const texts_1 = require("../../texts");
|
|
8
8
|
const input_1 = __importDefault(require("../../input"));
|
|
9
9
|
const output_1 = __importDefault(require("../../output"));
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
10
|
+
/** `members` keeps declaration order, which numbers the listing; `values` does not. */
|
|
11
|
+
const orderedMembers = (body) => {
|
|
12
|
+
if (body.kind !== 'union')
|
|
13
|
+
return [];
|
|
14
|
+
const members = body.discriminator?.members;
|
|
15
|
+
return members ? Object.keys(members) : body.variants.map((one) => one.name);
|
|
16
|
+
};
|
|
17
|
+
const memberDef = (body, name) => body.discriminator?.members?.[name] ?? body.variants.find((one) => one.name === name)?.ref?.name;
|
|
18
|
+
const unionsOf = (doc) => {
|
|
19
|
+
const bodies = [];
|
|
20
|
+
for (const content of doc.request?.contents ?? [])
|
|
21
|
+
bodies.push(content.body);
|
|
22
|
+
for (const response of doc.responses)
|
|
23
|
+
for (const content of response.contents)
|
|
24
|
+
bodies.push(content.body);
|
|
25
|
+
return bodies.filter((body) => body.kind === 'union');
|
|
21
26
|
};
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
const memberMeta = async (api, doc) => {
|
|
28
|
+
const defs = new Set();
|
|
29
|
+
for (const body of unionsOf(doc)) {
|
|
30
|
+
if (body.kind !== 'union')
|
|
31
|
+
continue;
|
|
32
|
+
for (const name of orderedMembers(body)) {
|
|
33
|
+
const def = memberDef(body, name);
|
|
34
|
+
if (def)
|
|
35
|
+
defs.add(def);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const meta = new Map();
|
|
39
|
+
for (const def of defs) {
|
|
40
|
+
const type = await api.type(def);
|
|
41
|
+
const shown = type?.extensions?.['x-name'];
|
|
42
|
+
meta.set(def, {
|
|
43
|
+
...(typeof shown === 'string' ? { shown } : {}),
|
|
44
|
+
deprecated: type?.deprecated === true,
|
|
45
|
+
});
|
|
25
46
|
}
|
|
26
|
-
return
|
|
47
|
+
return meta;
|
|
27
48
|
};
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
example = workspace;
|
|
35
|
-
else if (p.name === 'project_name' && project)
|
|
36
|
-
example = project;
|
|
37
|
-
else if (p.schema && p.schema.example)
|
|
38
|
-
example = p.schema.example;
|
|
39
|
-
table.push([
|
|
40
|
-
p.name || '-',
|
|
41
|
-
getParameterType(p),
|
|
42
|
-
example.toString(),
|
|
43
|
-
p.description || '-',
|
|
44
|
-
]);
|
|
49
|
+
const scopesOf = (security) => {
|
|
50
|
+
const found = new Set();
|
|
51
|
+
for (const alternative of security) {
|
|
52
|
+
for (const requirement of alternative) {
|
|
53
|
+
for (const scope of requirement.scopes)
|
|
54
|
+
found.add(scope);
|
|
45
55
|
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
56
|
+
}
|
|
57
|
+
return [...found];
|
|
58
|
+
};
|
|
59
|
+
const exampleOf = (field, workspace, project) => {
|
|
60
|
+
if (field.name === 'workspace_domain')
|
|
61
|
+
return workspace;
|
|
62
|
+
if (field.name === 'project_name' && project)
|
|
63
|
+
return project;
|
|
64
|
+
return field.example === undefined ? '-' : String(field.example);
|
|
65
|
+
};
|
|
66
|
+
const outputParameters = (label, fields, workspace, project) => {
|
|
67
|
+
if (fields.length === 0)
|
|
68
|
+
return;
|
|
69
|
+
const table = [[label, 'Type', 'Example', 'Description']];
|
|
70
|
+
for (const field of fields) {
|
|
71
|
+
table.push([
|
|
72
|
+
field.name || '-',
|
|
73
|
+
field.type || 'string',
|
|
74
|
+
exampleOf(field, workspace, project),
|
|
75
|
+
field.description || '-',
|
|
53
76
|
]);
|
|
54
|
-
output_1.default.table(table);
|
|
55
|
-
output_1.default.normal('');
|
|
56
77
|
}
|
|
78
|
+
output_1.default.table(table);
|
|
79
|
+
output_1.default.normal('');
|
|
57
80
|
};
|
|
58
81
|
const outputTextWithPadding = (text, padding = 1, newLine = true) => {
|
|
59
|
-
|
|
60
|
-
for (let i = 0; i < padding; i += 1)
|
|
61
|
-
t += ' ';
|
|
62
|
-
t += text;
|
|
63
|
-
output_1.default.normal(t, newLine);
|
|
82
|
+
output_1.default.normal(' '.repeat(padding) + text, newLine);
|
|
64
83
|
};
|
|
65
|
-
const outputSimpleProp = (name, type, description,
|
|
84
|
+
const outputSimpleProp = (name, type, description, enumValues, required, padding) => {
|
|
66
85
|
outputTextWithPadding(name, padding, false);
|
|
67
86
|
output_1.default.gray(`: ${type}`, false);
|
|
68
87
|
if (required)
|
|
69
88
|
output_1.default.gray(' (required)', false);
|
|
70
89
|
if (description)
|
|
71
90
|
output_1.default.gray(` - ${description}`, false);
|
|
72
|
-
if (
|
|
73
|
-
output_1.default.gray(` - ${
|
|
91
|
+
if (enumValues && enumValues.length)
|
|
92
|
+
output_1.default.gray(` - ${enumValues.join(', ')}`, false);
|
|
74
93
|
output_1.default.normal('');
|
|
75
94
|
};
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
output_1.default.gray(' (required)', false);
|
|
82
|
-
if (data.description)
|
|
83
|
-
output_1.default.gray(` - ${data.description}`, false);
|
|
84
|
-
output_1.default.normal('');
|
|
95
|
+
const fieldsOf = (field, types) => field.ref?.elsewhere ? (types?.[field.ref.name]?.fields ?? []) : (field.fields ?? []);
|
|
96
|
+
const outputField = (field, padding, ctx, onPath) => {
|
|
97
|
+
if (field.constraints?.format === 'binary') {
|
|
98
|
+
outputSimpleProp(field.name, field.ref?.array ? 'binary array' : 'binary', field.description, undefined, field.required, padding);
|
|
99
|
+
return;
|
|
85
100
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
101
|
+
const named = field.ref?.name;
|
|
102
|
+
const children = named !== undefined && onPath.has(named) ? [] : fieldsOf(field, ctx.types);
|
|
103
|
+
const deeper = named === undefined ? onPath : new Set(onPath).add(named);
|
|
104
|
+
if (children.length === 0) {
|
|
105
|
+
outputSimpleProp(field.name, field.type, field.description, field.enum, field.required, padding);
|
|
106
|
+
return;
|
|
89
107
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
outputSimpleProp('item', data.items.type, data.items.description, data.items.enum, false, padding + 2);
|
|
108
|
+
if (field.ref?.array) {
|
|
109
|
+
outputSimpleProp(field.name, 'array', field.description, undefined, field.required, padding);
|
|
110
|
+
outputTextWithPadding('[', padding);
|
|
111
|
+
outputFields(children, padding + 2, ctx, deeper);
|
|
112
|
+
outputTextWithPadding(']', padding);
|
|
113
|
+
return;
|
|
97
114
|
}
|
|
98
|
-
outputTextWithPadding(
|
|
115
|
+
outputTextWithPadding(field.name, padding, false);
|
|
116
|
+
output_1.default.gray(' : object', false);
|
|
117
|
+
if (field.required)
|
|
118
|
+
output_1.default.gray(' (required)', false);
|
|
119
|
+
if (field.description)
|
|
120
|
+
output_1.default.gray(` - ${field.description}`, false);
|
|
121
|
+
output_1.default.normal('');
|
|
122
|
+
outputFields(children, padding, ctx, deeper);
|
|
99
123
|
};
|
|
100
|
-
const
|
|
101
|
-
const propsRequired = data.required || [];
|
|
102
|
-
const props = data.properties || {};
|
|
103
|
-
if (name) {
|
|
104
|
-
outputTextWithPadding(name, padding, false);
|
|
105
|
-
output_1.default.gray(` : ${SCHEMA_TYPE.OBJECT}`, false);
|
|
106
|
-
if (required)
|
|
107
|
-
output_1.default.gray(' (required)', false);
|
|
108
|
-
if (data.description)
|
|
109
|
-
output_1.default.gray(` - ${data.description}`, false);
|
|
110
|
-
output_1.default.normal('');
|
|
111
|
-
}
|
|
124
|
+
const outputFields = (fields, padding, ctx, onPath = new Set()) => {
|
|
112
125
|
outputTextWithPadding('{', padding);
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
keys.forEach((name) => {
|
|
116
|
-
const prop = props[name];
|
|
117
|
-
if (prop.type === SCHEMA_TYPE.ARRAY)
|
|
118
|
-
outputJsonArrayProp(prop, padding + 2, name, propsRequired.includes(name));
|
|
119
|
-
else if (prop.type === SCHEMA_TYPE.OBJECT)
|
|
120
|
-
outputJsonObject(prop, padding + 2, name, propsRequired.includes(name));
|
|
121
|
-
else
|
|
122
|
-
outputSimpleProp(name, prop.type, prop.description, prop.enum, propsRequired.includes(name), padding + 2);
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
else if (data.additionalProperties) {
|
|
126
|
-
outputTextWithPadding('key: value', padding + 2, false);
|
|
127
|
-
if (data.additionalProperties.description)
|
|
128
|
-
output_1.default.gray(` - ${data.additionalProperties.description}`, false);
|
|
129
|
-
output_1.default.normal('');
|
|
130
|
-
}
|
|
126
|
+
for (const field of fields)
|
|
127
|
+
outputField(field, padding + 2, ctx, onPath);
|
|
131
128
|
outputTextWithPadding('}', padding);
|
|
132
129
|
};
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
output_1.default.normal('');
|
|
141
|
-
};
|
|
142
|
-
const outputMultipartFormData = (data, padding = 1) => {
|
|
143
|
-
const propsRequired = data.required || [];
|
|
144
|
-
const props = data.properties || {};
|
|
145
|
-
const keys = Object.keys(props);
|
|
146
|
-
if (keys.length > 0) {
|
|
147
|
-
keys.forEach((name) => {
|
|
148
|
-
const prop = props[name];
|
|
149
|
-
if (prop.format === 'binary')
|
|
150
|
-
outputMultipartBinary(name, prop.type === 'array', prop.description, propsRequired.includes(name), padding);
|
|
151
|
-
else if (prop.type === SCHEMA_TYPE.ARRAY)
|
|
152
|
-
output_1.default.exitError(texts_1.ERR_API_MEDIA_TYPE_NOT_IMPLEMENTED);
|
|
153
|
-
else if (prop.type === SCHEMA_TYPE.OBJECT)
|
|
154
|
-
output_1.default.exitError(texts_1.ERR_API_MEDIA_TYPE_NOT_IMPLEMENTED);
|
|
155
|
-
else
|
|
156
|
-
outputSimpleProp(name, prop.type, prop.description, prop.enum, propsRequired.includes(name), padding);
|
|
157
|
-
});
|
|
130
|
+
const outputUnion = (body, ctx, padding) => {
|
|
131
|
+
const names = orderedMembers(body);
|
|
132
|
+
// One variant means one was asked for; more than one is the listing.
|
|
133
|
+
const shown = body.variants.length === 1 ? body.variants[0] : undefined;
|
|
134
|
+
if (shown) {
|
|
135
|
+
outputFields([...body.shared, ...shown.fields], padding, ctx);
|
|
136
|
+
return;
|
|
158
137
|
}
|
|
138
|
+
output_1.default.gray(` media type contains ${names.length} schemas:`);
|
|
139
|
+
names.forEach((name, index) => {
|
|
140
|
+
const def = memberDef(body, name);
|
|
141
|
+
const meta = def ? ctx.members.get(def) : undefined;
|
|
142
|
+
outputTextWithPadding(`${index + 1}: ${name}`, padding, false);
|
|
143
|
+
if (meta?.deprecated)
|
|
144
|
+
output_1.default.gray(' (deprecated)', false);
|
|
145
|
+
if (meta?.shown)
|
|
146
|
+
output_1.default.gray(` - ${meta.shown}`, false);
|
|
147
|
+
output_1.default.normal('');
|
|
148
|
+
});
|
|
149
|
+
outputTextWithPadding(`pass ${ctx.flag} with number or type to view it`);
|
|
159
150
|
};
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
151
|
+
const outputBody = (body, ctx, padding = 1) => {
|
|
152
|
+
switch (body.kind) {
|
|
153
|
+
case 'none':
|
|
154
|
+
return;
|
|
155
|
+
case 'fields':
|
|
156
|
+
outputFields(body.fields, padding, ctx);
|
|
157
|
+
return;
|
|
158
|
+
case 'array':
|
|
159
|
+
outputTextWithPadding('[', padding);
|
|
160
|
+
outputBody(body.items, ctx, padding + 2);
|
|
161
|
+
outputTextWithPadding(']', padding);
|
|
162
|
+
return;
|
|
163
|
+
case 'value': {
|
|
164
|
+
outputTextWithPadding(body.type, padding, false);
|
|
165
|
+
if (body.description)
|
|
166
|
+
output_1.default.gray(` - ${body.description}`, false);
|
|
167
|
+
if (body.enum?.length)
|
|
168
|
+
output_1.default.gray(` - ${body.enum.join(', ')}`, false);
|
|
169
|
+
output_1.default.normal('');
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
case 'union':
|
|
173
|
+
outputUnion(body, ctx, padding);
|
|
174
|
+
return;
|
|
166
175
|
}
|
|
167
|
-
|
|
168
|
-
|
|
176
|
+
};
|
|
177
|
+
const outputContent = (content, ctx, first) => {
|
|
178
|
+
if (!first)
|
|
179
|
+
output_1.default.gray(' ------- or content type -------');
|
|
180
|
+
output_1.default.gray(' content-type: ', false);
|
|
181
|
+
output_1.default.normal(content.contentType ?? '-');
|
|
182
|
+
if (content.contentType === 'multipart/form-data' && content.body.kind === 'fields') {
|
|
183
|
+
for (const field of content.body.fields)
|
|
184
|
+
outputField(field, 1, ctx, new Set());
|
|
185
|
+
return;
|
|
169
186
|
}
|
|
187
|
+
outputBody(content.body, ctx);
|
|
170
188
|
};
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
189
|
+
const outputRequestBody = (doc, members) => {
|
|
190
|
+
// Declared with no content is not absent, and the header is all there is to say.
|
|
191
|
+
if (!doc.request)
|
|
192
|
+
return;
|
|
193
|
+
const contents = doc.request.contents;
|
|
194
|
+
const ctx = { types: doc.types, members, flag: '--request-schema' };
|
|
195
|
+
output_1.default.blue(` Request body`);
|
|
196
|
+
contents.forEach((content, index) => outputContent(content, ctx, index === 0));
|
|
197
|
+
output_1.default.normal('');
|
|
198
|
+
};
|
|
199
|
+
const outputResponsesBody = (doc, members) => {
|
|
200
|
+
if (doc.responses.length === 0)
|
|
201
|
+
return;
|
|
202
|
+
const ctx = { types: doc.types, members, flag: '--response-schema' };
|
|
203
|
+
output_1.default.blue(` Response body`);
|
|
204
|
+
doc.responses.forEach((response, index) => {
|
|
205
|
+
if (index > 0)
|
|
206
|
+
output_1.default.gray(' ------------');
|
|
207
|
+
output_1.default.gray(' http status: ', false);
|
|
208
|
+
output_1.default.normal(response.status);
|
|
209
|
+
response.contents.forEach((content, i) => outputContent(content, ctx, i === 0));
|
|
178
210
|
});
|
|
179
211
|
};
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
output_1.default.gray(' ------------');
|
|
188
|
-
}
|
|
189
|
-
output_1.default.gray(' http status: ', false);
|
|
190
|
-
output_1.default.normal(code);
|
|
191
|
-
outputResponse(r[code], schema);
|
|
192
|
-
});
|
|
193
|
-
}
|
|
212
|
+
const chosen = (asked, names) => {
|
|
213
|
+
if (!asked)
|
|
214
|
+
return undefined;
|
|
215
|
+
if (names.includes(asked))
|
|
216
|
+
return asked;
|
|
217
|
+
const position = Number(asked);
|
|
218
|
+
return Number.isInteger(position) && position >= 1 ? names[position - 1] : undefined;
|
|
194
219
|
};
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
for (let i = 0; i < mappings.length; i += 1) {
|
|
216
|
-
if (mappings[i] === userSchema) {
|
|
217
|
-
const schema = schemas[i];
|
|
218
|
-
if (schema) {
|
|
219
|
-
outputBodyObject(mediaType, schema);
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
output_1.default.gray(` media type contains ${schemas.length} schemas:`);
|
|
225
|
-
for (let i = 1; i <= schemas.length; i += 1) {
|
|
226
|
-
const mapping = mappings[i - 1];
|
|
227
|
-
const name = mapping ? `${i}: ${mapping}` : `${i}`;
|
|
228
|
-
outputTextWithPadding(name, 1, false);
|
|
229
|
-
const schema = schemas[i - 1];
|
|
230
|
-
logger_1.default.info(schema);
|
|
231
|
-
if (schema) {
|
|
232
|
-
if (schema.deprecated)
|
|
233
|
-
output_1.default.gray(` (deprecated)`, false);
|
|
234
|
-
const desc = schema['x-name'] || schema.title || schema.description;
|
|
235
|
-
if (desc)
|
|
236
|
-
output_1.default.gray(` - ${desc}`, false);
|
|
237
|
-
}
|
|
238
|
-
output_1.default.normal('');
|
|
239
|
-
}
|
|
240
|
-
outputTextWithPadding(`pass --${schemaParamName} with number or type to view it`);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
else {
|
|
244
|
-
outputBodyObject(mediaType, mediaTypeObject.schema);
|
|
245
|
-
}
|
|
220
|
+
const commandApiInfo = (0, utils_1.newCommand)('info', texts_1.DESC_COMMAND_API_INFO);
|
|
221
|
+
commandApiInfo.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
|
|
222
|
+
commandApiInfo.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
|
|
223
|
+
commandApiInfo.option('--request-schema <schema>', texts_1.OPT_COMMAND_API_INFO_SCHEMA);
|
|
224
|
+
commandApiInfo.option('--response-schema <schema>', texts_1.OPT_COMMAND_API_INFO_SCHEMA);
|
|
225
|
+
commandApiInfo.argument('<method>', texts_1.OPT_COMMAND_API_INFO_METHOD);
|
|
226
|
+
commandApiInfo.argument('<url>', texts_1.OPT_COMMAND_API_INFO_URL);
|
|
227
|
+
commandApiInfo.action(async (fm, filterUrl, options) => {
|
|
228
|
+
const { apiEndpoints } = require('../../openapi');
|
|
229
|
+
const workspace = input_1.default.restApiWorkspace(options.workspace);
|
|
230
|
+
const project = input_1.default.restApiProject(options.project, true);
|
|
231
|
+
const method = (input_1.default.restApiMethod(fm, false) ?? '').toLowerCase();
|
|
232
|
+
const client = input_1.default.restApiTokenClient(true);
|
|
233
|
+
const api = await apiEndpoints(client.baseUrl);
|
|
234
|
+
const wanted = (await api.operations()).find((operation) => operation.method.toLowerCase() === method &&
|
|
235
|
+
(operation.path === filterUrl ||
|
|
236
|
+
(0, utils_1.openApiPrepareUrl)(operation.path, workspace, project) === filterUrl));
|
|
237
|
+
if (!wanted) {
|
|
238
|
+
output_1.default.exitError(texts_1.ERR_API_ENDPOINT_NOT_FOUND);
|
|
239
|
+
return;
|
|
246
240
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
const content = data.content || {};
|
|
252
|
-
Object.keys(content).forEach((mediaType, index) => {
|
|
253
|
-
if (index > 0) {
|
|
254
|
-
output_1.default.gray(' ------- or content type -------');
|
|
255
|
-
}
|
|
256
|
-
outputMediaType(mediaType, content[mediaType], 'request-schema', schema);
|
|
257
|
-
});
|
|
258
|
-
output_1.default.normal('');
|
|
241
|
+
const listed = await api.endpoint(wanted.method, wanted.path);
|
|
242
|
+
if (!listed) {
|
|
243
|
+
output_1.default.exitError(texts_1.ERR_API_ENDPOINT_NOT_FOUND);
|
|
244
|
+
return;
|
|
259
245
|
}
|
|
260
|
-
|
|
261
|
-
const
|
|
262
|
-
const
|
|
246
|
+
const namesOf = (bodies) => bodies.flatMap((body) => [...orderedMembers(body)]);
|
|
247
|
+
const request = chosen(options.requestSchema, namesOf((listed.request?.contents ?? []).map((content) => content.body)));
|
|
248
|
+
const response = chosen(options.responseSchema, namesOf(listed.responses.flatMap((one) => one.contents.map((content) => content.body))));
|
|
249
|
+
const member = request || response
|
|
250
|
+
? { ...(request ? { request } : {}), ...(response ? { response } : {}) }
|
|
251
|
+
: undefined;
|
|
252
|
+
const doc = member ? await api.endpoint(wanted.method, wanted.path, member) : listed;
|
|
253
|
+
if (!doc) {
|
|
254
|
+
output_1.default.exitError(texts_1.ERR_API_ENDPOINT_NOT_FOUND);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
const members = await memberMeta(api, doc);
|
|
258
|
+
const m = doc.method.toUpperCase();
|
|
263
259
|
if (m === 'GET')
|
|
264
260
|
output_1.default.cyan(m, false);
|
|
265
261
|
else if (m === 'POST')
|
|
@@ -270,48 +266,21 @@ const outputUrl = (url, method, data, workspace, project, requestSchema, respons
|
|
|
270
266
|
output_1.default.yellow(m, false);
|
|
271
267
|
else if (m === 'DELETE')
|
|
272
268
|
output_1.default.error(m, false);
|
|
273
|
-
output_1.default.normal(` ${
|
|
274
|
-
if (
|
|
275
|
-
output_1.default.gray(
|
|
276
|
-
const scopes =
|
|
269
|
+
output_1.default.normal(` ${(0, utils_1.openApiPrepareUrl)(doc.path, workspace, project)}`);
|
|
270
|
+
if (doc.summary)
|
|
271
|
+
output_1.default.gray(doc.summary, false);
|
|
272
|
+
const scopes = scopesOf(doc.security);
|
|
277
273
|
if (scopes.length > 0) {
|
|
278
|
-
if (
|
|
274
|
+
if (doc.summary)
|
|
279
275
|
output_1.default.gray('. ', false);
|
|
280
276
|
output_1.default.gray(`${texts_1.TXT_API_ENDPOINT_REQUIRED_SCOPES}: `, false);
|
|
281
277
|
output_1.default.gray(scopes.join(', '), false);
|
|
282
278
|
}
|
|
283
279
|
output_1.default.normal('\n');
|
|
284
|
-
outputParameters('
|
|
285
|
-
outputParameters('
|
|
286
|
-
outputRequestBody(
|
|
287
|
-
outputResponsesBody(
|
|
280
|
+
outputParameters('URL param', doc.parameters.path ?? [], workspace, project);
|
|
281
|
+
outputParameters('Query param', doc.parameters.query ?? [], workspace, project);
|
|
282
|
+
outputRequestBody(doc, members);
|
|
283
|
+
outputResponsesBody(doc, members);
|
|
288
284
|
output_1.default.exitNormal();
|
|
289
|
-
};
|
|
290
|
-
const commandApiInfo = (0, utils_1.newCommand)('info', texts_1.DESC_COMMAND_API_INFO);
|
|
291
|
-
commandApiInfo.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
|
|
292
|
-
commandApiInfo.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
|
|
293
|
-
commandApiInfo.option('--request-schema <schema>', texts_1.OPT_COMMAND_API_INFO_SCHEMA);
|
|
294
|
-
commandApiInfo.option('--response-schema <schema>', texts_1.OPT_COMMAND_API_INFO_SCHEMA);
|
|
295
|
-
commandApiInfo.argument('<method>', texts_1.OPT_COMMAND_API_INFO_METHOD);
|
|
296
|
-
commandApiInfo.argument('<url>', texts_1.OPT_COMMAND_API_INFO_URL);
|
|
297
|
-
commandApiInfo.action(async (fm, filterUrl, options) => {
|
|
298
|
-
const { fetchOpenApiSchema } = require('../../openapi');
|
|
299
|
-
const workspace = input_1.default.restApiWorkspace(options.workspace);
|
|
300
|
-
const project = input_1.default.restApiProject(options.project, true);
|
|
301
|
-
const filterMethod = input_1.default.restApiMethod(fm, false);
|
|
302
|
-
const client = input_1.default.restApiTokenClient(true);
|
|
303
|
-
const schema = await fetchOpenApiSchema(client.baseUrl);
|
|
304
|
-
const paths = schema.paths || {};
|
|
305
|
-
Object.keys(paths).forEach((url) => {
|
|
306
|
-
const preparedUrl = (0, utils_1.openApiPrepareUrl)(url, workspace, project);
|
|
307
|
-
if (filterUrl === url || filterUrl === preparedUrl) {
|
|
308
|
-
const methods = paths[url] || {};
|
|
309
|
-
Object.entries(methods).forEach(([method, data]) => {
|
|
310
|
-
if (filterMethod === method)
|
|
311
|
-
outputUrl(preparedUrl, method, data, workspace, project, options.requestSchema, options.responseSchema);
|
|
312
|
-
});
|
|
313
|
-
}
|
|
314
|
-
});
|
|
315
|
-
output_1.default.exitError(texts_1.ERR_API_ENDPOINT_NOT_FOUND);
|
|
316
285
|
});
|
|
317
286
|
exports.default = commandApiInfo;
|
|
@@ -7,8 +7,8 @@ const utils_1 = require("../../utils");
|
|
|
7
7
|
const texts_1 = require("../../texts");
|
|
8
8
|
const input_1 = __importDefault(require("../../input"));
|
|
9
9
|
const output_1 = __importDefault(require("../../output"));
|
|
10
|
-
const outputUrl = (
|
|
11
|
-
const m =
|
|
10
|
+
const outputUrl = (operation, workspace, project) => {
|
|
11
|
+
const m = operation.method.toUpperCase();
|
|
12
12
|
if (m === 'GET')
|
|
13
13
|
output_1.default.cyan(m, false);
|
|
14
14
|
else if (m === 'POST')
|
|
@@ -21,9 +21,9 @@ const outputUrl = (url, method, data, workspace, project) => {
|
|
|
21
21
|
output_1.default.error(m, false);
|
|
22
22
|
else
|
|
23
23
|
output_1.default.blue(m, false);
|
|
24
|
-
output_1.default.normal(` ${(0, utils_1.openApiPrepareUrl)(
|
|
25
|
-
if (
|
|
26
|
-
output_1.default.gray(
|
|
24
|
+
output_1.default.normal(` ${(0, utils_1.openApiPrepareUrl)(operation.path, workspace, project)}`);
|
|
25
|
+
if (operation.summary)
|
|
26
|
+
output_1.default.gray(operation.summary);
|
|
27
27
|
};
|
|
28
28
|
const commandApiList = (0, utils_1.newCommand)('list', texts_1.DESC_COMMAND_API_LIST);
|
|
29
29
|
commandApiList.alias('ls');
|
|
@@ -32,23 +32,20 @@ commandApiList.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
|
|
|
32
32
|
commandApiList.option('-m, --method <method>', texts_1.OPT_COMMAND_API_LIST_METHOD);
|
|
33
33
|
commandApiList.option('-s, --search <phrase>', texts_1.OPT_COMMAND_API_LIST_SEARCH);
|
|
34
34
|
commandApiList.action(async (options) => {
|
|
35
|
-
const {
|
|
35
|
+
const { apiEndpoints } = require('../../openapi');
|
|
36
36
|
const workspace = input_1.default.restApiWorkspace(options.workspace);
|
|
37
37
|
const project = input_1.default.restApiProject(options.project, true);
|
|
38
38
|
const filterMethod = input_1.default.restApiMethod(options.method);
|
|
39
39
|
const filter = options.search;
|
|
40
40
|
const client = input_1.default.restApiTokenClient(true);
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
});
|
|
41
|
+
const api = await apiEndpoints(client.baseUrl);
|
|
42
|
+
for (const operation of await api.operations()) {
|
|
43
|
+
if (filter && !operation.path.includes(filter))
|
|
44
|
+
continue;
|
|
45
|
+
if (filterMethod && filterMethod !== operation.method.toLowerCase())
|
|
46
|
+
continue;
|
|
47
|
+
outputUrl(operation, workspace, project);
|
|
48
|
+
}
|
|
52
49
|
output_1.default.exitNormal();
|
|
53
50
|
});
|
|
54
51
|
exports.default = commandApiList;
|