@andrezz/openapimd 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +145 -0
- package/dist/cli/args.d.ts +10 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +56 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/help.d.ts +4 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +25 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +6 -0
- package/dist/cli.js.map +1 -0
- package/dist/convert.d.ts +17 -0
- package/dist/convert.d.ts.map +1 -0
- package/dist/convert.js +36 -0
- package/dist/convert.js.map +1 -0
- package/dist/errors.d.ts +18 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +22 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/loaders/file-loader.d.ts +6 -0
- package/dist/loaders/file-loader.d.ts.map +1 -0
- package/dist/loaders/file-loader.js +20 -0
- package/dist/loaders/file-loader.js.map +1 -0
- package/dist/loaders/loader.d.ts +15 -0
- package/dist/loaders/loader.d.ts.map +1 -0
- package/dist/loaders/loader.js +21 -0
- package/dist/loaders/loader.js.map +1 -0
- package/dist/loaders/url-loader.d.ts +12 -0
- package/dist/loaders/url-loader.d.ts.map +1 -0
- package/dist/loaders/url-loader.js +42 -0
- package/dist/loaders/url-loader.js.map +1 -0
- package/dist/parsers/json-parser.d.ts +6 -0
- package/dist/parsers/json-parser.d.ts.map +1 -0
- package/dist/parsers/json-parser.js +12 -0
- package/dist/parsers/json-parser.js.map +1 -0
- package/dist/parsers/parser.d.ts +11 -0
- package/dist/parsers/parser.d.ts.map +1 -0
- package/dist/parsers/parser.js +47 -0
- package/dist/parsers/parser.js.map +1 -0
- package/dist/parsers/yaml-parser.d.ts +6 -0
- package/dist/parsers/yaml-parser.d.ts.map +1 -0
- package/dist/parsers/yaml-parser.js +13 -0
- package/dist/parsers/yaml-parser.js.map +1 -0
- package/dist/renderers/document-renderer.d.ts +12 -0
- package/dist/renderers/document-renderer.d.ts.map +1 -0
- package/dist/renderers/document-renderer.js +76 -0
- package/dist/renderers/document-renderer.js.map +1 -0
- package/dist/renderers/markdown.d.ts +10 -0
- package/dist/renderers/markdown.d.ts.map +1 -0
- package/dist/renderers/markdown.js +46 -0
- package/dist/renderers/markdown.js.map +1 -0
- package/dist/renderers/renderer.d.ts +16 -0
- package/dist/renderers/renderer.d.ts.map +1 -0
- package/dist/renderers/renderer.js +12 -0
- package/dist/renderers/renderer.js.map +1 -0
- package/dist/renderers/sections.d.ts +22 -0
- package/dist/renderers/sections.d.ts.map +1 -0
- package/dist/renderers/sections.js +209 -0
- package/dist/renderers/sections.js.map +1 -0
- package/dist/renderers/single-renderer.d.ts +8 -0
- package/dist/renderers/single-renderer.d.ts.map +1 -0
- package/dist/renderers/single-renderer.js +23 -0
- package/dist/renderers/single-renderer.js.map +1 -0
- package/dist/run.d.ts +2 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +52 -0
- package/dist/run.js.map +1 -0
- package/dist/template.d.ts +6 -0
- package/dist/template.d.ts.map +1 -0
- package/dist/template.js +11 -0
- package/dist/template.js.map +1 -0
- package/dist/types.d.ts +159 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +11 -0
- package/dist/utils.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/dist/writers/writer.d.ts +8 -0
- package/dist/writers/writer.d.ts.map +1 -0
- package/dist/writers/writer.js +15 -0
- package/dist/writers/writer.js.map +1 -0
- package/package.json +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 andrezz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# @andrezz/openapimd
|
|
2
|
+
|
|
3
|
+
[](https://github.com/andrezz/openapimd/actions)
|
|
4
|
+
[](https://www.npmjs.com/package/@andrezz/openapimd)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
|
|
7
|
+
Convert OpenAPI specifications (JSON or YAML) into clean Markdown documentation.
|
|
8
|
+
|
|
9
|
+
`openapimd` is a small CLI and library that reads an OpenAPI 3.x document from
|
|
10
|
+
a local file or a URL and renders it as Markdown. It supports two output
|
|
11
|
+
templates: a single self-contained file, or a structured set of files with an
|
|
12
|
+
index.
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
15
|
+
|
|
16
|
+
- Node.js >= 18
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
20
|
+
- Read OpenAPI specs from **local files** or **URLs** (http/https).
|
|
21
|
+
- Accept **JSON** and **YAML** inputs (format auto-detected from extension or content type).
|
|
22
|
+
- Two output templates:
|
|
23
|
+
- `single` (default) — everything in one Markdown file.
|
|
24
|
+
- `document` — an `index.md` plus one file per tag under `spec/*.md` and a `spec/schemas.md`.
|
|
25
|
+
- Configurable output path (defaults to the current directory).
|
|
26
|
+
- Full TypeScript support with a public library API.
|
|
27
|
+
- Cross-platform, with a single runtime dependency (`yaml`).
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
The package is published to the public [npm registry](https://www.npmjs.com/package/@andrezz/openapimd),
|
|
32
|
+
so it can be installed with no extra configuration:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install @andrezz/openapimd
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Global install (CLI)
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install --global @andrezz/openapimd
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
After a global install, the `openapimd` command is available on your `PATH`.
|
|
45
|
+
|
|
46
|
+
### Run without installing
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx @andrezz/openapimd openapi.json
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
### Command line
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
openapimd <input> [options]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`<input>` is a path to a local file or a URL.
|
|
61
|
+
|
|
62
|
+
| Option | Description |
|
|
63
|
+
| --- | --- |
|
|
64
|
+
| `-o, --output <path>` | Output file (single template) or directory (document template). Defaults to the current directory. |
|
|
65
|
+
| `-t, --template <type>` | Rendering template: `single` (default) or `document`. |
|
|
66
|
+
| `-h, --help` | Show help. |
|
|
67
|
+
| `-V, --version` | Show the version. |
|
|
68
|
+
|
|
69
|
+
### Examples
|
|
70
|
+
|
|
71
|
+
Convert a local JSON file into `./openapi.md`:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
openapimd openapi.json
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Convert a remote YAML file into a specific directory:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
openapimd https://api.example.com/openapi.yaml -o ./docs
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Write to a custom file name (single template):
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
openapimd openapi.json -o ./docs/api.md
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Generate the multi-file documentation:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
openapimd openapi.json -t document -o ./docs
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The `document` template produces:
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
docs/
|
|
99
|
+
├── index.md # overview + endpoint index
|
|
100
|
+
└── spec/
|
|
101
|
+
├── <tag>.md # one file per tag (or default.md for untagged operations)
|
|
102
|
+
└── schemas.md # data models
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Programmatic API
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { convert } from '@andrezz/openapimd';
|
|
109
|
+
|
|
110
|
+
const result = await convert('openapi.json', {
|
|
111
|
+
output: './docs',
|
|
112
|
+
template: 'document',
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
console.log(result.outputDir); // absolute output directory
|
|
116
|
+
console.log(result.files); // absolute paths of the generated files
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Development
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# Install dependencies
|
|
123
|
+
npm install
|
|
124
|
+
|
|
125
|
+
# Run the test suite
|
|
126
|
+
npm test
|
|
127
|
+
|
|
128
|
+
# Run tests with coverage (threshold is 80%)
|
|
129
|
+
npm run test:coverage
|
|
130
|
+
|
|
131
|
+
# Compile to dist/
|
|
132
|
+
npm run build
|
|
133
|
+
|
|
134
|
+
# Try the CLI locally
|
|
135
|
+
node dist/cli.js openapi.json
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Contributing
|
|
139
|
+
|
|
140
|
+
Issues and pull requests are welcome. See the
|
|
141
|
+
[issue tracker](https://github.com/andrezz/openapimd/issues) to get started.
|
|
142
|
+
|
|
143
|
+
## License
|
|
144
|
+
|
|
145
|
+
[MIT](./LICENSE) © andrezz
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TemplateType } from '../template.js';
|
|
2
|
+
export interface CliOptions {
|
|
3
|
+
source?: string;
|
|
4
|
+
output?: string;
|
|
5
|
+
template?: TemplateType;
|
|
6
|
+
help: boolean;
|
|
7
|
+
version: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function parseArgs(argv: string[]): CliOptions;
|
|
10
|
+
//# sourceMappingURL=args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE7D,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAgDpD"}
|
package/dist/cli/args.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { CliUsageError } from '../errors.js';
|
|
2
|
+
import { parseTemplate } from '../template.js';
|
|
3
|
+
export function parseArgs(argv) {
|
|
4
|
+
const options = { help: false, version: false };
|
|
5
|
+
const positionals = [];
|
|
6
|
+
for (let index = 0; index < argv.length; index++) {
|
|
7
|
+
const argument = argv[index];
|
|
8
|
+
if (argument === '--') {
|
|
9
|
+
positionals.push(...argv.slice(index + 1));
|
|
10
|
+
break;
|
|
11
|
+
}
|
|
12
|
+
if (argument === '-h' || argument === '--help') {
|
|
13
|
+
options.help = true;
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (argument === '-V' || argument === '--version') {
|
|
17
|
+
options.version = true;
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (argument === '-o' || argument === '--output') {
|
|
21
|
+
options.output = readValue(argv, index, argument);
|
|
22
|
+
index++;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (argument.startsWith('--output=')) {
|
|
26
|
+
options.output = argument.slice('--output='.length);
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (argument === '-t' || argument === '--template') {
|
|
30
|
+
options.template = parseTemplate(readValue(argv, index, argument));
|
|
31
|
+
index++;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (argument.startsWith('--template=')) {
|
|
35
|
+
options.template = parseTemplate(argument.slice('--template='.length));
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (argument.startsWith('-') && argument !== '-') {
|
|
39
|
+
throw new CliUsageError(`Unknown option "${argument}".`);
|
|
40
|
+
}
|
|
41
|
+
positionals.push(argument);
|
|
42
|
+
}
|
|
43
|
+
if (positionals.length > 1) {
|
|
44
|
+
throw new CliUsageError('Only one input source is allowed.');
|
|
45
|
+
}
|
|
46
|
+
options.source = positionals[0];
|
|
47
|
+
return options;
|
|
48
|
+
}
|
|
49
|
+
function readValue(argv, index, option) {
|
|
50
|
+
const value = argv[index + 1];
|
|
51
|
+
if (!value) {
|
|
52
|
+
throw new CliUsageError(`Missing value for "${option}".`);
|
|
53
|
+
}
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAgB,MAAM,gBAAgB,CAAC;AAU7D,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,OAAO,GAAe,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5D,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAW,CAAC;QAEvC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,WAAW,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;YAC3C,MAAM;QACR,CAAC;QACD,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC/C,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,SAAS;QACX,CAAC;QACD,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;YAClD,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;YACvB,SAAS;QACX,CAAC;QACD,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;YACjD,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;YAClD,KAAK,EAAE,CAAC;YACR,SAAS;QACX,CAAC;QACD,IAAI,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YACrC,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YACpD,SAAS;QACX,CAAC;QACD,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;YACnD,OAAO,CAAC,QAAQ,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;YACnE,KAAK,EAAE,CAAC;YACR,SAAS;QACX,CAAC;QACD,IAAI,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YACvC,OAAO,CAAC,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;YACvE,SAAS;QACX,CAAC;QACD,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,KAAK,GAAG,EAAE,CAAC;YACjD,MAAM,IAAI,aAAa,CAAC,mBAAmB,QAAQ,IAAI,CAAC,CAAC;QAC3D,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,aAAa,CAAC,mCAAmC,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAChC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,SAAS,CAAC,IAAc,EAAE,KAAa,EAAE,MAAc;IAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,aAAa,CAAC,sBAAsB,MAAM,IAAI,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const HELP_TEXT = "Usage: openapimd <input> [options]\n\nConvert an OpenAPI specification (JSON or YAML) into Markdown documentation.\nThe <input> can be a path to a local file or a URL (http/https).\n\nOptions:\n -o, --output <path> Output file (single template) or directory\n (document template). Defaults to the current directory.\n -t, --template <type> Rendering template: \"single\" (default) or \"document\".\n -h, --help Show this help message.\n -V, --version Show the version number.\n\nExamples:\n openapimd openapi.json\n openapimd https://example.com/openapi.yaml -o ./docs\n openapimd openapi.json -t document -o ./docs\n";
|
|
2
|
+
export declare function printHelp(stream?: NodeJS.WritableStream): void;
|
|
3
|
+
export declare function printVersion(stream?: NodeJS.WritableStream): void;
|
|
4
|
+
//# sourceMappingURL=help.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,SAAS,sqBAgBrB,CAAC;AAEF,wBAAgB,SAAS,CAAC,MAAM,GAAE,MAAM,CAAC,cAA+B,GAAG,IAAI,CAE9E;AAED,wBAAgB,YAAY,CAAC,MAAM,GAAE,MAAM,CAAC,cAA+B,GAAG,IAAI,CAEjF"}
|
package/dist/cli/help.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { VERSION } from '../version.js';
|
|
2
|
+
export const HELP_TEXT = `Usage: openapimd <input> [options]
|
|
3
|
+
|
|
4
|
+
Convert an OpenAPI specification (JSON or YAML) into Markdown documentation.
|
|
5
|
+
The <input> can be a path to a local file or a URL (http/https).
|
|
6
|
+
|
|
7
|
+
Options:
|
|
8
|
+
-o, --output <path> Output file (single template) or directory
|
|
9
|
+
(document template). Defaults to the current directory.
|
|
10
|
+
-t, --template <type> Rendering template: "single" (default) or "document".
|
|
11
|
+
-h, --help Show this help message.
|
|
12
|
+
-V, --version Show the version number.
|
|
13
|
+
|
|
14
|
+
Examples:
|
|
15
|
+
openapimd openapi.json
|
|
16
|
+
openapimd https://example.com/openapi.yaml -o ./docs
|
|
17
|
+
openapimd openapi.json -t document -o ./docs
|
|
18
|
+
`;
|
|
19
|
+
export function printHelp(stream = process.stdout) {
|
|
20
|
+
stream.write(HELP_TEXT);
|
|
21
|
+
}
|
|
22
|
+
export function printVersion(stream = process.stdout) {
|
|
23
|
+
stream.write(`${VERSION}\n`);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=help.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,MAAM,CAAC,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;CAgBxB,CAAC;AAEF,MAAM,UAAU,SAAS,CAAC,MAAM,GAA0B,OAAO,CAAC,MAAM;IACtE,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAM,GAA0B,OAAO,CAAC,MAAM;IACzE,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;AAC/B,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;IACvC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1B,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { TemplateType } from './template.js';
|
|
2
|
+
import { FileWriter } from './writers/writer.js';
|
|
3
|
+
export interface ConvertOptions {
|
|
4
|
+
output?: string;
|
|
5
|
+
template?: TemplateType;
|
|
6
|
+
}
|
|
7
|
+
export interface ConvertResult {
|
|
8
|
+
outputDir: string;
|
|
9
|
+
files: string[];
|
|
10
|
+
}
|
|
11
|
+
export declare class Converter {
|
|
12
|
+
private readonly writer;
|
|
13
|
+
constructor(writer?: FileWriter);
|
|
14
|
+
convert(source: string, options?: ConvertOptions): Promise<ConvertResult>;
|
|
15
|
+
}
|
|
16
|
+
export declare function convert(source: string, options?: ConvertOptions): Promise<ConvertResult>;
|
|
17
|
+
//# sourceMappingURL=convert.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAKA,OAAO,EAAmB,YAAY,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,EAAE,UAAU,EAAY,MAAM,qBAAqB,CAAC;AAE3D,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAOD,qBAAa,SAAS;IACR,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAnC,YAA6B,MAAM,GAAE,UAA2B,EAAI;IAE9D,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CAYlF;CACF;AAcD,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CAE5F"}
|
package/dist/convert.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { basename, dirname, resolve } from 'node:path';
|
|
2
|
+
import { LoaderFactory } from './loaders/loader.js';
|
|
3
|
+
import { parseSource } from './parsers/parser.js';
|
|
4
|
+
import { RendererFactory } from './renderers/renderer.js';
|
|
5
|
+
import { TEMPLATE_SINGLE } from './template.js';
|
|
6
|
+
import { FsWriter } from './writers/writer.js';
|
|
7
|
+
export class Converter {
|
|
8
|
+
writer;
|
|
9
|
+
constructor(writer = new FsWriter()) {
|
|
10
|
+
this.writer = writer;
|
|
11
|
+
}
|
|
12
|
+
async convert(source, options = {}) {
|
|
13
|
+
const template = options.template ?? TEMPLATE_SINGLE;
|
|
14
|
+
const loader = LoaderFactory.create(source);
|
|
15
|
+
const loaded = await loader.load(source);
|
|
16
|
+
const spec = parseSource(loaded);
|
|
17
|
+
const { outputDir, fileName } = resolveTargets(options.output, template);
|
|
18
|
+
const renderer = RendererFactory.create(template, { fileName });
|
|
19
|
+
const files = await this.writer.write(outputDir, renderer.render(spec));
|
|
20
|
+
return { outputDir, files };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function resolveTargets(output, template) {
|
|
24
|
+
const base = (output ?? '').trim();
|
|
25
|
+
if (template === TEMPLATE_SINGLE && isMarkdownFile(base)) {
|
|
26
|
+
return { outputDir: resolve(dirname(base)), fileName: basename(base) };
|
|
27
|
+
}
|
|
28
|
+
return { outputDir: resolve(base || process.cwd()), fileName: 'openapi.md' };
|
|
29
|
+
}
|
|
30
|
+
function isMarkdownFile(path) {
|
|
31
|
+
return /\.(md|markdown)$/i.test(path);
|
|
32
|
+
}
|
|
33
|
+
export function convert(source, options = {}) {
|
|
34
|
+
return new Converter().convert(source, options);
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=convert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.js","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAgB,MAAM,eAAe,CAAC;AAE9D,OAAO,EAAc,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAiB3D,MAAM,OAAO,SAAS;IACS,MAAM;IAAnC,YAA6B,MAAM,GAAe,IAAI,QAAQ,EAAE;sBAAnC,MAAM;IAAgC,CAAC;IAEpE,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,OAAO,GAAmB,EAAE;QACxD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,eAAe,CAAC;QAErD,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,IAAI,GAAgB,WAAW,CAAC,MAAM,CAAC,CAAC;QAE9C,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAExE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;CACF;AAED,SAAS,cAAc,CAAC,MAA0B,EAAE,QAAsB;IACxE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,QAAQ,KAAK,eAAe,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QACzD,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACzE,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;AAC/E,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,OAAO,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,MAAc,EAAE,OAAO,GAAmB,EAAE;IAClE,OAAO,IAAI,SAAS,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare class OpenApiMdError extends Error {
|
|
2
|
+
constructor(message: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class SourceNotFoundError extends OpenApiMdError {
|
|
5
|
+
}
|
|
6
|
+
export declare class SourceFetchError extends OpenApiMdError {
|
|
7
|
+
}
|
|
8
|
+
export declare class SourceUnsupportedError extends OpenApiMdError {
|
|
9
|
+
}
|
|
10
|
+
export declare class ParseError extends OpenApiMdError {
|
|
11
|
+
}
|
|
12
|
+
export declare class InvalidSpecError extends OpenApiMdError {
|
|
13
|
+
}
|
|
14
|
+
export declare class UnsupportedTemplateError extends OpenApiMdError {
|
|
15
|
+
}
|
|
16
|
+
export declare class CliUsageError extends OpenApiMdError {
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAO,EAAE,MAAM,EAI1B;CACF;AAED,qBAAa,mBAAoB,SAAQ,cAAc;CAAG;AAE1D,qBAAa,gBAAiB,SAAQ,cAAc;CAAG;AAEvD,qBAAa,sBAAuB,SAAQ,cAAc;CAAG;AAE7D,qBAAa,UAAW,SAAQ,cAAc;CAAG;AAEjD,qBAAa,gBAAiB,SAAQ,cAAc;CAAG;AAEvD,qBAAa,wBAAyB,SAAQ,cAAc;CAAG;AAE/D,qBAAa,aAAc,SAAQ,cAAc;CAAG"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export class OpenApiMdError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = new.target.name;
|
|
5
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export class SourceNotFoundError extends OpenApiMdError {
|
|
9
|
+
}
|
|
10
|
+
export class SourceFetchError extends OpenApiMdError {
|
|
11
|
+
}
|
|
12
|
+
export class SourceUnsupportedError extends OpenApiMdError {
|
|
13
|
+
}
|
|
14
|
+
export class ParseError extends OpenApiMdError {
|
|
15
|
+
}
|
|
16
|
+
export class InvalidSpecError extends OpenApiMdError {
|
|
17
|
+
}
|
|
18
|
+
export class UnsupportedTemplateError extends OpenApiMdError {
|
|
19
|
+
}
|
|
20
|
+
export class CliUsageError extends OpenApiMdError {
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC;QAC5B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,cAAc;CAAG;AAE1D,MAAM,OAAO,gBAAiB,SAAQ,cAAc;CAAG;AAEvD,MAAM,OAAO,sBAAuB,SAAQ,cAAc;CAAG;AAE7D,MAAM,OAAO,UAAW,SAAQ,cAAc;CAAG;AAEjD,MAAM,OAAO,gBAAiB,SAAQ,cAAc;CAAG;AAEvD,MAAM,OAAO,wBAAyB,SAAQ,cAAc;CAAG;AAE/D,MAAM,OAAO,aAAc,SAAQ,cAAc;CAAG"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { convert, Converter } from './convert.js';
|
|
2
|
+
export type { ConvertOptions, ConvertResult } from './convert.js';
|
|
3
|
+
export { TEMPLATE_SINGLE, TEMPLATE_DOCUMENT, TEMPLATE_TYPES, parseTemplate } from './template.js';
|
|
4
|
+
export type { TemplateType } from './template.js';
|
|
5
|
+
export { CliUsageError, InvalidSpecError, OpenApiMdError, ParseError, SourceFetchError, SourceNotFoundError, SourceUnsupportedError, UnsupportedTemplateError, } from './errors.js';
|
|
6
|
+
export type { ComponentsObject, ContentObject, InfoObject, OpenApiSpec, OperationObject, ParameterObject, PathItemObject, PathsObject, ReferenceObject, RequestBodyObject, ResponseObject, ResponsesObject, SchemaObject, SecuritySchemeObject, ServerObject, TagObject, } from './types.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElE,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAClG,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,WAAW,EACX,eAAe,EACf,eAAe,EACf,cAAc,EACd,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,YAAY,EACZ,SAAS,GACV,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { convert, Converter } from './convert.js';
|
|
2
|
+
export { TEMPLATE_SINGLE, TEMPLATE_DOCUMENT, TEMPLATE_TYPES, parseTemplate } from './template.js';
|
|
3
|
+
export { CliUsageError, InvalidSpecError, OpenApiMdError, ParseError, SourceFetchError, SourceNotFoundError, SourceUnsupportedError, UnsupportedTemplateError, } from './errors.js';
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGlD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGlG,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-loader.d.ts","sourceRoot":"","sources":["../../src/loaders/file-loader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgB,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGvE,qBAAa,UAAW,YAAW,YAAY;IAC7C,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE/B;IAEK,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAUhD;CACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { SourceNotFoundError } from '../errors.js';
|
|
3
|
+
import { detectFormat } from './loader.js';
|
|
4
|
+
import { UrlLoader } from './url-loader.js';
|
|
5
|
+
export class FileLoader {
|
|
6
|
+
canLoad(source) {
|
|
7
|
+
return !UrlLoader.isUrl(source);
|
|
8
|
+
}
|
|
9
|
+
async load(source) {
|
|
10
|
+
let content;
|
|
11
|
+
try {
|
|
12
|
+
content = await readFile(source, 'utf8');
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
throw new SourceNotFoundError(`Unable to read file "${source}": ${error.message}`);
|
|
16
|
+
}
|
|
17
|
+
return { content, format: detectFormat(source), sourceName: source };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=file-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-loader.js","sourceRoot":"","sources":["../../src/loaders/file-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,YAAY,EAA8B,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,OAAO,UAAU;IACrB,OAAO,CAAC,MAAc;QACpB,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAc;QACvB,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,mBAAmB,CAC3B,wBAAwB,MAAM,MAAO,KAAe,CAAC,OAAO,EAAE,CAC/D,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IACvE,CAAC;CACF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type SourceFormat = 'json' | 'yaml';
|
|
2
|
+
export interface LoadedSource {
|
|
3
|
+
content: string;
|
|
4
|
+
format: SourceFormat | undefined;
|
|
5
|
+
sourceName: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SourceLoader {
|
|
8
|
+
canLoad(source: string): boolean;
|
|
9
|
+
load(source: string): Promise<LoadedSource>;
|
|
10
|
+
}
|
|
11
|
+
export declare function detectFormat(value: string): SourceFormat | undefined;
|
|
12
|
+
export declare class LoaderFactory {
|
|
13
|
+
static create(source: string): SourceLoader;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/loaders/loader.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC7C;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CASpE;AAED,qBAAa,aAAa;IACxB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAK1C;CACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { FileLoader } from './file-loader.js';
|
|
2
|
+
import { UrlLoader } from './url-loader.js';
|
|
3
|
+
export function detectFormat(value) {
|
|
4
|
+
const lower = value.toLowerCase();
|
|
5
|
+
if (lower.endsWith('.json') || lower.includes('json')) {
|
|
6
|
+
return 'json';
|
|
7
|
+
}
|
|
8
|
+
if (lower.endsWith('.yaml') || lower.endsWith('.yml') || lower.includes('yaml')) {
|
|
9
|
+
return 'yaml';
|
|
10
|
+
}
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
export class LoaderFactory {
|
|
14
|
+
static create(source) {
|
|
15
|
+
if (UrlLoader.isUrl(source)) {
|
|
16
|
+
return new UrlLoader();
|
|
17
|
+
}
|
|
18
|
+
return new FileLoader();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/loaders/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAe5C,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAChF,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,OAAO,aAAa;IACxB,MAAM,CAAC,MAAM,CAAC,MAAc;QAC1B,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,OAAO,IAAI,SAAS,EAAE,CAAC;QACzB,CAAC;QACD,OAAO,IAAI,UAAU,EAAE,CAAC;IAC1B,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { LoadedSource, SourceLoader } from './loader.js';
|
|
2
|
+
export type FetchFn = (input: string) => Promise<Response>;
|
|
3
|
+
export declare class UrlLoader implements SourceLoader {
|
|
4
|
+
private readonly fetchFn;
|
|
5
|
+
constructor(fetchFn?: FetchFn);
|
|
6
|
+
static isUrl(source: string): boolean;
|
|
7
|
+
canLoad(source: string): boolean;
|
|
8
|
+
load(source: string): Promise<LoadedSource>;
|
|
9
|
+
private pathOf;
|
|
10
|
+
private formatFromResponse;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=url-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-loader.d.ts","sourceRoot":"","sources":["../../src/loaders/url-loader.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEvE,MAAM,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE3D,qBAAa,SAAU,YAAW,YAAY;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAElC,YAAY,OAAO,GAAE,OAA4C,EAEhE;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEpC;IAED,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE/B;IAEK,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAmBhD;IAED,OAAO,CAAC,MAAM;IAQd,OAAO,CAAC,kBAAkB;CAI3B"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { SourceFetchError } from '../errors.js';
|
|
2
|
+
import { detectFormat } from './loader.js';
|
|
3
|
+
export class UrlLoader {
|
|
4
|
+
fetchFn;
|
|
5
|
+
constructor(fetchFn = (input) => globalThis.fetch(input)) {
|
|
6
|
+
this.fetchFn = fetchFn;
|
|
7
|
+
}
|
|
8
|
+
static isUrl(source) {
|
|
9
|
+
return /^https?:\/\//i.test(source);
|
|
10
|
+
}
|
|
11
|
+
canLoad(source) {
|
|
12
|
+
return UrlLoader.isUrl(source);
|
|
13
|
+
}
|
|
14
|
+
async load(source) {
|
|
15
|
+
let response;
|
|
16
|
+
try {
|
|
17
|
+
response = await this.fetchFn(source);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
throw new SourceFetchError(`Unable to fetch "${source}": ${error.message}`);
|
|
21
|
+
}
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
throw new SourceFetchError(`Unable to fetch "${source}": HTTP ${response.status} ${response.statusText}`);
|
|
24
|
+
}
|
|
25
|
+
const content = await response.text();
|
|
26
|
+
const format = detectFormat(this.pathOf(source)) ?? this.formatFromResponse(response);
|
|
27
|
+
return { content, format, sourceName: source };
|
|
28
|
+
}
|
|
29
|
+
pathOf(url) {
|
|
30
|
+
try {
|
|
31
|
+
return new URL(url).pathname;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return '';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
formatFromResponse(response) {
|
|
38
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
39
|
+
return detectFormat(contentType);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=url-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-loader.js","sourceRoot":"","sources":["../../src/loaders/url-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,YAAY,EAA8B,MAAM,aAAa,CAAC;AAIvE,MAAM,OAAO,SAAS;IACH,OAAO,CAAU;IAElC,YAAY,OAAO,GAAY,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC;QAC/D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAc;QACzB,OAAO,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,CAAC,MAAc;QACpB,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAc;QACvB,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,gBAAgB,CACxB,oBAAoB,MAAM,MAAO,KAAe,CAAC,OAAO,EAAE,CAC3D,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,gBAAgB,CACxB,oBAAoB,MAAM,WAAW,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAC9E,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QACtF,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IACjD,CAAC;IAEO,MAAM,CAAC,GAAW;QACxB,IAAI,CAAC;YACH,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,kBAAkB,CAAC,QAAkB;QAC3C,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QAC/D,OAAO,YAAY,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/json-parser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,qBAAa,UAAW,YAAW,UAAU;IAC3C,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAMlC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ParseError } from '../errors.js';
|
|
2
|
+
export class JsonParser {
|
|
3
|
+
parse(content) {
|
|
4
|
+
try {
|
|
5
|
+
return JSON.parse(content);
|
|
6
|
+
}
|
|
7
|
+
catch (error) {
|
|
8
|
+
throw new ParseError(`Invalid JSON: ${error.message}`);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=json-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-parser.js","sourceRoot":"","sources":["../../src/parsers/json-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI1C,MAAM,OAAO,UAAU;IACrB,KAAK,CAAC,OAAe;QACnB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAgB,CAAC;QAC5C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,UAAU,CAAC,iBAAkB,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { LoadedSource } from '../loaders/loader.js';
|
|
2
|
+
import { OpenApiSpec } from '../types.js';
|
|
3
|
+
export interface SpecParser {
|
|
4
|
+
parse(content: string): OpenApiSpec;
|
|
5
|
+
}
|
|
6
|
+
export declare function parseSource(source: LoadedSource): OpenApiSpec;
|
|
7
|
+
export declare class AutoParser implements SpecParser {
|
|
8
|
+
parse(content: string): OpenApiSpec;
|
|
9
|
+
}
|
|
10
|
+
export declare function validate(value: unknown, sourceName: string): OpenApiSpec;
|
|
11
|
+
//# sourceMappingURL=parser.d.ts.map
|