@tronsfey/openapi2cli 1.0.10
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/LICENSE +21 -0
- package/README.md +173 -0
- package/README.zh.md +173 -0
- package/bin/openapi2cli +2 -0
- package/dist/analyzer/schema-analyzer.d.ts +4 -0
- package/dist/analyzer/schema-analyzer.d.ts.map +1 -0
- package/dist/analyzer/schema-analyzer.js +329 -0
- package/dist/analyzer/schema-analyzer.js.map +1 -0
- package/dist/auth/auth-provider.d.ts +22 -0
- package/dist/auth/auth-provider.d.ts.map +1 -0
- package/dist/auth/auth-provider.js +100 -0
- package/dist/auth/auth-provider.js.map +1 -0
- package/dist/generator/command-generator.d.ts +3 -0
- package/dist/generator/command-generator.d.ts.map +1 -0
- package/dist/generator/command-generator.js +96 -0
- package/dist/generator/command-generator.js.map +1 -0
- package/dist/generator/template-engine.d.ts +2 -0
- package/dist/generator/template-engine.d.ts.map +1 -0
- package/dist/generator/template-engine.js +154 -0
- package/dist/generator/template-engine.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +135 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/oas-parser.d.ts +3 -0
- package/dist/parser/oas-parser.d.ts.map +1 -0
- package/dist/parser/oas-parser.js +64 -0
- package/dist/parser/oas-parser.js.map +1 -0
- package/dist/templates/README.md.hbs +197 -0
- package/dist/templates/README.zh.md.hbs +197 -0
- package/dist/templates/SKILL.md.hbs +134 -0
- package/dist/templates/api-client.ts.hbs +217 -0
- package/dist/templates/command.ts.hbs +130 -0
- package/dist/templates/flat-commands.ts.hbs +126 -0
- package/dist/templates/index.ts.hbs +38 -0
- package/dist/templates/package.json.hbs +31 -0
- package/dist/templates/tsconfig.json.hbs +16 -0
- package/dist/types/index.d.ts +104 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.renderTemplate = renderTemplate;
|
|
40
|
+
const handlebars_1 = __importDefault(require("handlebars"));
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
// Register all helpers once at module load
|
|
44
|
+
registerHelpers();
|
|
45
|
+
// After build: __dirname = dist/generator/, templates are at dist/templates/
|
|
46
|
+
// During dev with ts-node: __dirname = src/generator/, templates are at src/templates/
|
|
47
|
+
// In both cases, templates are one level up from __dirname
|
|
48
|
+
const TEMPLATES_DIR = path.join(__dirname, '..', 'templates');
|
|
49
|
+
async function renderTemplate(templateName, context) {
|
|
50
|
+
const templatePath = path.join(TEMPLATES_DIR, templateName);
|
|
51
|
+
const source = fs.readFileSync(templatePath, 'utf-8');
|
|
52
|
+
const template = handlebars_1.default.compile(source, { noEscape: true });
|
|
53
|
+
return template(context);
|
|
54
|
+
}
|
|
55
|
+
function registerHelpers() {
|
|
56
|
+
handlebars_1.default.registerHelper('uppercase', (s) => s.toUpperCase());
|
|
57
|
+
handlebars_1.default.registerHelper('camelCase', (s) => s.replace(/-([a-z])/g, (_, c) => c.toUpperCase()).replace(/^([A-Z])/, (c) => c.toLowerCase()));
|
|
58
|
+
handlebars_1.default.registerHelper('pascalCase', (s) => s.split('-').map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(''));
|
|
59
|
+
// Block helper: {{#eq a "value"}}...{{else}}...{{/eq}}
|
|
60
|
+
// Must use function keyword (not arrow) so Handlebars can bind 'this' correctly
|
|
61
|
+
handlebars_1.default.registerHelper('eq', function (a, b, options) {
|
|
62
|
+
return a === b ? options.fn(this) : options.inverse(this);
|
|
63
|
+
});
|
|
64
|
+
// optionFlag(name, required, type) -> "--name <name>" | "--name [name]" | "--name"
|
|
65
|
+
handlebars_1.default.registerHelper('optionFlag', (name, required, type) => {
|
|
66
|
+
if (type === 'boolean')
|
|
67
|
+
return `--${name}`;
|
|
68
|
+
const brackets = required ? `<${name}>` : `[${name}]`;
|
|
69
|
+
return `--${name} ${brackets}`;
|
|
70
|
+
});
|
|
71
|
+
handlebars_1.default.registerHelper('join', (arr, sep) => Array.isArray(arr) ? arr.join(sep) : '');
|
|
72
|
+
// Check if an array has items
|
|
73
|
+
handlebars_1.default.registerHelper('hasItems', (arr) => Array.isArray(arr) && arr.length > 0);
|
|
74
|
+
// jsString(s) -> JSON.stringify(s) e.g. jsString("it's") -> '"it\'s"'
|
|
75
|
+
// Use this whenever a value is embedded inside a TypeScript string literal in generated code,
|
|
76
|
+
// to safely handle single quotes, double quotes, backslashes, and Unicode characters.
|
|
77
|
+
handlebars_1.default.registerHelper('jsString', (s) => JSON.stringify(String(s ?? '')));
|
|
78
|
+
// subcommandHelpText(subcommand) -> JSON string with tree-formatted body/response fields,
|
|
79
|
+
// or empty string if there is nothing to display.
|
|
80
|
+
handlebars_1.default.registerHelper('subcommandHelpText', (subcommand) => {
|
|
81
|
+
const lines = [];
|
|
82
|
+
const pad = (s, n) => s.padEnd(n);
|
|
83
|
+
// --- request body ---
|
|
84
|
+
const rb = subcommand['requestBody'];
|
|
85
|
+
if (rb?.fields?.length) {
|
|
86
|
+
lines.push('');
|
|
87
|
+
lines.push(`Body (--data JSON, ${rb.required ? 'required' : 'optional'}):`);
|
|
88
|
+
rb.fields.forEach((f, i) => {
|
|
89
|
+
const prefix = i === rb.fields.length - 1 ? ' └─' : ' ├─';
|
|
90
|
+
const req = f.required ? 'required' : 'optional';
|
|
91
|
+
const enumHint = f.enum?.length ? ` choices: ${f.enum.join(' | ')}` : '';
|
|
92
|
+
lines.push(`${prefix} ${pad(f.name, 18)}${pad(f.type, 12)}${pad(req, 10)}${f.description}${enumHint}`);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
// --- 2xx responses ---
|
|
96
|
+
const responses = (subcommand['responses'] ?? {});
|
|
97
|
+
for (const [code, resp] of Object.entries(responses)) {
|
|
98
|
+
if (!code.startsWith('2') || !resp.fields?.length)
|
|
99
|
+
continue;
|
|
100
|
+
lines.push('');
|
|
101
|
+
lines.push(`Response ${code} (${resp.description ?? ''}):`);
|
|
102
|
+
resp.fields.forEach((f, i) => {
|
|
103
|
+
const prefix = i === resp.fields.length - 1 ? ' └─' : ' ├─';
|
|
104
|
+
lines.push(`${prefix} ${pad(f.name, 18)}${pad(f.type, 12)}${f.description}`);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return lines.length ? JSON.stringify(lines.join('\n')) : '';
|
|
108
|
+
});
|
|
109
|
+
// pad(str, n) -> str padded to n chars with spaces (for aligned help output)
|
|
110
|
+
handlebars_1.default.registerHelper('pad', (s, n) => String(s ?? '').padEnd(n));
|
|
111
|
+
// sampleResponseJson(subcommand) -> pretty-printed sample JSON from the first 2xx response
|
|
112
|
+
// schema, or empty string when no schema fields are available.
|
|
113
|
+
handlebars_1.default.registerHelper('sampleResponseJson', (subcommand) => {
|
|
114
|
+
function sampleValue(name, type) {
|
|
115
|
+
if (type === 'integer' || type === 'number')
|
|
116
|
+
return 1;
|
|
117
|
+
if (type === 'boolean')
|
|
118
|
+
return true;
|
|
119
|
+
if (type === 'array')
|
|
120
|
+
return [];
|
|
121
|
+
if (type === 'object')
|
|
122
|
+
return {};
|
|
123
|
+
const lower = name.toLowerCase();
|
|
124
|
+
if (lower === 'id' || lower.endsWith('_id') || lower.endsWith('id'))
|
|
125
|
+
return 1;
|
|
126
|
+
if (lower.includes('email'))
|
|
127
|
+
return 'user@example.com';
|
|
128
|
+
if (lower.includes('name') || lower === 'title')
|
|
129
|
+
return 'example';
|
|
130
|
+
if (lower.includes('url') || lower.includes('href') || lower.includes('link'))
|
|
131
|
+
return 'https://example.com';
|
|
132
|
+
if (lower.includes('date') || lower.includes('time') || lower.endsWith('_at'))
|
|
133
|
+
return '2024-01-01T00:00:00Z';
|
|
134
|
+
if (lower.includes('status') || lower.includes('state'))
|
|
135
|
+
return 'active';
|
|
136
|
+
if (lower.includes('count') || lower.includes('total') || lower.includes('num'))
|
|
137
|
+
return 1;
|
|
138
|
+
if (lower.includes('description') || lower.includes('desc') || lower.includes('summary'))
|
|
139
|
+
return 'A brief description.';
|
|
140
|
+
return 'example';
|
|
141
|
+
}
|
|
142
|
+
const responses = (subcommand['responses'] ?? {});
|
|
143
|
+
for (const [code, resp] of Object.entries(responses)) {
|
|
144
|
+
if (!code.startsWith('2') || !resp.fields?.length)
|
|
145
|
+
continue;
|
|
146
|
+
const obj = {};
|
|
147
|
+
for (const f of resp.fields)
|
|
148
|
+
obj[f.name] = sampleValue(f.name, f.type);
|
|
149
|
+
return resp.isArray ? JSON.stringify([obj], null, 2) : JSON.stringify(obj, null, 2);
|
|
150
|
+
}
|
|
151
|
+
return '';
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=template-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-engine.js","sourceRoot":"","sources":["../../src/generator/template-engine.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
const commander_1 = require("commander");
|
|
41
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
42
|
+
const ora_1 = __importDefault(require("ora"));
|
|
43
|
+
const fse = __importStar(require("fs-extra"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
const oas_parser_1 = require("./parser/oas-parser");
|
|
46
|
+
const schema_analyzer_1 = require("./analyzer/schema-analyzer");
|
|
47
|
+
const command_generator_1 = require("./generator/command-generator");
|
|
48
|
+
const program = new commander_1.Command();
|
|
49
|
+
program
|
|
50
|
+
.name('openapi2cli')
|
|
51
|
+
.description('Generate a typed CLI from an OpenAPI 3.x specification')
|
|
52
|
+
.version('1.0.0')
|
|
53
|
+
.requiredOption('--oas <path-or-url>', 'Path or URL to the OpenAPI spec file')
|
|
54
|
+
.requiredOption('--name <cli-name>', 'Name for the generated CLI tool')
|
|
55
|
+
.requiredOption('--output <dir>', 'Output directory for the generated project')
|
|
56
|
+
.option('--overwrite', 'Overwrite output directory if it exists', false)
|
|
57
|
+
.action(async (opts) => {
|
|
58
|
+
await run(opts);
|
|
59
|
+
});
|
|
60
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
61
|
+
console.error(chalk_1.default.red('Fatal:'), err.message);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
});
|
|
64
|
+
async function run(opts) {
|
|
65
|
+
const outputDir = path.resolve(process.cwd(), opts.output);
|
|
66
|
+
// Pre-flight: check output directory
|
|
67
|
+
if (await fse.pathExists(outputDir)) {
|
|
68
|
+
if (!opts.overwrite) {
|
|
69
|
+
console.error(chalk_1.default.red('Error:'), `Output directory already exists: ${outputDir}`);
|
|
70
|
+
console.error('Use --overwrite to replace it.');
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
await fse.remove(outputDir);
|
|
74
|
+
}
|
|
75
|
+
// Step 1: Parse OAS
|
|
76
|
+
const parseSpinner = (0, ora_1.default)('Parsing OpenAPI spec...').start();
|
|
77
|
+
let api;
|
|
78
|
+
try {
|
|
79
|
+
api = await (0, oas_parser_1.parseOAS)(opts.oas);
|
|
80
|
+
parseSpinner.succeed(chalk_1.default.green(`Parsed: ${api.info.title} v${api.info.version}`));
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
parseSpinner.fail('Failed to parse OpenAPI spec');
|
|
84
|
+
throw err;
|
|
85
|
+
}
|
|
86
|
+
// Step 2: Analyze schema
|
|
87
|
+
const analyzeSpinner = (0, ora_1.default)('Analyzing schema...').start();
|
|
88
|
+
const structure = (0, schema_analyzer_1.analyzeSchema)(api, opts.name);
|
|
89
|
+
const groupCount = structure.groups.length;
|
|
90
|
+
const flatCount = structure.flatCommands.length;
|
|
91
|
+
const summary = [
|
|
92
|
+
groupCount > 0 ? `${groupCount} command group(s)` : '',
|
|
93
|
+
flatCount > 0 ? `${flatCount} flat command(s)` : '',
|
|
94
|
+
].filter(Boolean).join(', ');
|
|
95
|
+
analyzeSpinner.succeed(chalk_1.default.green(`Found ${summary}`));
|
|
96
|
+
// Print any naming warnings collected during analysis
|
|
97
|
+
if (structure.warnings.length > 0) {
|
|
98
|
+
console.log('');
|
|
99
|
+
console.log(chalk_1.default.yellow(' ⚠ 规范性警告 (建议修复 OpenAPI 定义):'));
|
|
100
|
+
for (const w of structure.warnings) {
|
|
101
|
+
console.log(chalk_1.default.yellow(` ${w}`));
|
|
102
|
+
}
|
|
103
|
+
console.log('');
|
|
104
|
+
}
|
|
105
|
+
// Step 3: Generate project files
|
|
106
|
+
const genSpinner = (0, ora_1.default)('Generating project files...').start();
|
|
107
|
+
let files;
|
|
108
|
+
try {
|
|
109
|
+
files = await (0, command_generator_1.generateProject)(structure);
|
|
110
|
+
genSpinner.succeed(chalk_1.default.green(`Generated ${files.length} file(s)`));
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
genSpinner.fail('Failed to generate project files');
|
|
114
|
+
throw err;
|
|
115
|
+
}
|
|
116
|
+
// Step 4: Write files to output directory
|
|
117
|
+
const writeSpinner = (0, ora_1.default)(`Writing to ${outputDir}...`).start();
|
|
118
|
+
for (const file of files) {
|
|
119
|
+
const dest = path.join(outputDir, file.relativePath);
|
|
120
|
+
await fse.outputFile(dest, file.content, 'utf-8');
|
|
121
|
+
}
|
|
122
|
+
// Make the bin file executable
|
|
123
|
+
const binPath = path.join(outputDir, 'bin', opts.name);
|
|
124
|
+
if (await fse.pathExists(binPath)) {
|
|
125
|
+
await fse.chmod(binPath, 0o755);
|
|
126
|
+
}
|
|
127
|
+
writeSpinner.succeed(chalk_1.default.green('Done!'));
|
|
128
|
+
console.log('');
|
|
129
|
+
console.log(chalk_1.default.bold('Next steps:'));
|
|
130
|
+
console.log(chalk_1.default.cyan(` cd ${opts.output}`));
|
|
131
|
+
console.log(chalk_1.default.cyan(' npm install'));
|
|
132
|
+
console.log(chalk_1.default.cyan(' npm run build'));
|
|
133
|
+
console.log(chalk_1.default.cyan(` ./${path.join('bin', opts.name)} --help`));
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oas-parser.d.ts","sourceRoot":"","sources":["../../src/parser/oas-parser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI1C,wBAAsB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAyBzE"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.parseOAS = parseOAS;
|
|
40
|
+
const swagger_parser_1 = __importDefault(require("@apidevtools/swagger-parser"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
async function parseOAS(input) {
|
|
44
|
+
const isUrl = /^https?:\/\//.test(input);
|
|
45
|
+
let source;
|
|
46
|
+
if (isUrl) {
|
|
47
|
+
source = input;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
source = path.resolve(process.cwd(), input);
|
|
51
|
+
if (!fs.existsSync(source)) {
|
|
52
|
+
throw new Error(`OAS file not found: ${source}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// dereference() resolves all $ref nodes and validates the spec against OAS JSON Schema
|
|
56
|
+
const api = await swagger_parser_1.default.dereference(source);
|
|
57
|
+
// Guard: only support OAS 3.x (not Swagger 2.0)
|
|
58
|
+
if (!api.openapi || !api.openapi.startsWith('3.')) {
|
|
59
|
+
const version = api.openapi ?? api['swagger'];
|
|
60
|
+
throw new Error(`Unsupported spec version: "${version}". Only OpenAPI 3.x is supported.`);
|
|
61
|
+
}
|
|
62
|
+
return api;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=oas-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oas-parser.js","sourceRoot":"","sources":["../../src/parser/oas-parser.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,4BAyBC;AA9BD,iFAAwD;AAExD,2CAA6B;AAC7B,uCAAyB;AAElB,KAAK,UAAU,QAAQ,CAAC,KAAa;IAC1C,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEzC,IAAI,MAAc,CAAC;IACnB,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,GAAG,KAAK,CAAC;IACjB,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,uBAAuB,MAAM,EAAE,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,uFAAuF;IACvF,MAAM,GAAG,GAAG,MAAM,wBAAa,CAAC,WAAW,CAAC,MAAM,CAAuB,CAAC;IAE1E,gDAAgD;IAChD,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAClD,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAK,GAA0C,CAAC,SAAS,CAAC,CAAC;QACtF,MAAM,IAAI,KAAK,CACb,8BAA8B,OAAO,mCAAmC,CACzE,CAAC;IACJ,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
English | [中文](./README.zh.md)
|
|
2
|
+
|
|
3
|
+
# {{structure.name}}
|
|
4
|
+
|
|
5
|
+
{{structure.description}}
|
|
6
|
+
|
|
7
|
+
| | |
|
|
8
|
+
|---|---|
|
|
9
|
+
| **Base URL** | `{{structure.baseUrl}}` |
|
|
10
|
+
| **Version** | `{{structure.version}}` |
|
|
11
|
+
| **Auth** | {{#eq structure.authConfig.type "bearer"}}Bearer token (`{{structure.authConfig.envVar}}`){{/eq}}{{#eq structure.authConfig.type "apiKey"}}API key (`{{structure.authConfig.envVar}}`){{/eq}}{{#eq structure.authConfig.type "basic"}}Basic auth (`{{structure.authConfig.envVar}}`){{/eq}}{{#eq structure.authConfig.type "none"}}None{{/eq}} |
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install && npm run build && npm link
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
{{#eq structure.authConfig.type "bearer"}}
|
|
20
|
+
```bash
|
|
21
|
+
export {{structure.authConfig.envVar}}=your-token-here
|
|
22
|
+
```
|
|
23
|
+
{{/eq}}
|
|
24
|
+
{{#eq structure.authConfig.type "apiKey"}}
|
|
25
|
+
```bash
|
|
26
|
+
export {{structure.authConfig.envVar}}=your-api-key
|
|
27
|
+
```
|
|
28
|
+
{{/eq}}
|
|
29
|
+
{{#eq structure.authConfig.type "basic"}}
|
|
30
|
+
```bash
|
|
31
|
+
export {{structure.authConfig.envVar}}=username:password
|
|
32
|
+
```
|
|
33
|
+
{{/eq}}
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
$ {{structure.name}} --help
|
|
37
|
+
Usage: {{structure.name}} [options] [command]
|
|
38
|
+
|
|
39
|
+
{{structure.description}}
|
|
40
|
+
|
|
41
|
+
Commands:
|
|
42
|
+
{{#each structure.groups}} {{pad name 26}}{{description}}
|
|
43
|
+
{{/each}}{{#each structure.flatCommands}} {{pad name 26}}{{description}}
|
|
44
|
+
{{/each}}
|
|
45
|
+
Options:
|
|
46
|
+
--endpoint <url> Override the base API URL (default: "{{structure.baseUrl}}")
|
|
47
|
+
--format <format> Output format (choices: "json", "yaml", "table", default: "json")
|
|
48
|
+
--verbose Enable verbose request logging
|
|
49
|
+
-V, --version output the version number
|
|
50
|
+
-h, --help display help for command
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Commands
|
|
56
|
+
|
|
57
|
+
{{#each structure.groups}}
|
|
58
|
+
### `{{../structure.name}} {{name}}`
|
|
59
|
+
|
|
60
|
+
{{description}}
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
$ {{../../structure.name}} {{name}} --help
|
|
64
|
+
Usage: {{../../structure.name}} {{name}} [options] [command]
|
|
65
|
+
|
|
66
|
+
{{description}}
|
|
67
|
+
|
|
68
|
+
Commands:
|
|
69
|
+
{{#each subcommands}} {{pad name 26}}{{description}}
|
|
70
|
+
{{/each}}
|
|
71
|
+
Options:
|
|
72
|
+
-h, --help display help for command
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
{{#each subcommands}}
|
|
76
|
+
#### `{{../../structure.name}} {{../name}} {{name}}`
|
|
77
|
+
|
|
78
|
+
{{description}} — `{{uppercase method}} {{path}}`
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
$ {{../../../structure.name}} {{../../name}} {{name}} --help
|
|
82
|
+
Usage: {{../../../structure.name}} {{../../name}} {{name}} [options]
|
|
83
|
+
|
|
84
|
+
{{description}}
|
|
85
|
+
|
|
86
|
+
Options:
|
|
87
|
+
{{#each options}} {{pad (optionFlag name required type) 28}}{{description}}{{#if defaultValue}} (default: {{defaultValue}}){{/if}}{{#if enum}} (choices: {{join enum ", "}}){{/if}}
|
|
88
|
+
{{/each}} -h, --help display help for command
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Example:**
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
$ {{../../../structure.name}} {{../../name}} {{name}}{{#each options}}{{#if required}} --{{name}} <{{name}}>{{/if}}{{/each}}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
{{#if (sampleResponseJson this)}}
|
|
98
|
+
**Response:**
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{{sampleResponseJson this}}
|
|
102
|
+
```
|
|
103
|
+
{{/if}}
|
|
104
|
+
{{#if (subcommandHelpText this)}}
|
|
105
|
+
**Schema:**
|
|
106
|
+
```
|
|
107
|
+
{{subcommandHelpText this}}
|
|
108
|
+
```
|
|
109
|
+
{{/if}}
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
{{/each}}
|
|
113
|
+
{{/each}}
|
|
114
|
+
{{#if (hasItems structure.flatCommands)}}
|
|
115
|
+
## Top-Level Commands
|
|
116
|
+
|
|
117
|
+
Untagged operations registered directly on the CLI root.
|
|
118
|
+
|
|
119
|
+
{{#each structure.flatCommands}}
|
|
120
|
+
### `{{../structure.name}} {{name}}`
|
|
121
|
+
|
|
122
|
+
{{description}} — `{{uppercase method}} {{path}}`
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
$ {{../../structure.name}} {{name}} --help
|
|
126
|
+
Usage: {{../../structure.name}} {{name}} [options]
|
|
127
|
+
|
|
128
|
+
{{description}}
|
|
129
|
+
|
|
130
|
+
Options:
|
|
131
|
+
{{#each options}} {{pad (optionFlag name required type) 28}}{{description}}{{#if defaultValue}} (default: {{defaultValue}}){{/if}}{{#if enum}} (choices: {{join enum ", "}}){{/if}}
|
|
132
|
+
{{/each}} -h, --help display help for command
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Example:**
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
$ {{../../structure.name}} {{name}}{{#each options}}{{#if required}} --{{name}} <{{name}}>{{/if}}{{/each}}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
{{#if (sampleResponseJson this)}}
|
|
142
|
+
**Response:**
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{{sampleResponseJson this}}
|
|
146
|
+
```
|
|
147
|
+
{{/if}}
|
|
148
|
+
{{#if (subcommandHelpText this)}}
|
|
149
|
+
**Schema:**
|
|
150
|
+
```
|
|
151
|
+
{{subcommandHelpText this}}
|
|
152
|
+
```
|
|
153
|
+
{{/if}}
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
{{/each}}
|
|
157
|
+
{{/if}}
|
|
158
|
+
|
|
159
|
+
## Global Options
|
|
160
|
+
|
|
161
|
+
| Option | Description | Default |
|
|
162
|
+
|--------|-------------|---------|
|
|
163
|
+
| `--endpoint <url>` | Override the base API URL | `{{structure.baseUrl}}` |
|
|
164
|
+
| `--format <format>` | Output format | `json` (choices: `json`, `yaml`, `table`) |
|
|
165
|
+
| `--verbose` | Log HTTP method + URL before each request | `false` |
|
|
166
|
+
|
|
167
|
+
## Request Body
|
|
168
|
+
|
|
169
|
+
For `POST`, `PUT`, `PATCH` commands use `--data` to pass the request body:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# Inline JSON
|
|
173
|
+
{{structure.name}} <group> <command> --data '{"key": "value"}'
|
|
174
|
+
|
|
175
|
+
# From a file
|
|
176
|
+
{{structure.name}} <group> <command> --data @payload.json
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Output Formats
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Default: pretty-printed JSON
|
|
183
|
+
{{structure.name}} <group> <command> [options]
|
|
184
|
+
|
|
185
|
+
# Table view (great for arrays)
|
|
186
|
+
{{structure.name}} <group> <command> [options] --format table
|
|
187
|
+
|
|
188
|
+
# Pipe to jq for filtering
|
|
189
|
+
{{structure.name}} <group> <command> [options] | jq '.items[]'
|
|
190
|
+
|
|
191
|
+
# Save to file
|
|
192
|
+
{{structure.name}} <group> <command> [options] > result.json
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
_Generated by [openapi2cli](https://github.com/tronsfey928/openapi2cli) from OpenAPI spec v{{structure.version}}._
|