@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.
Files changed (95) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +145 -0
  3. package/dist/cli/args.d.ts +10 -0
  4. package/dist/cli/args.d.ts.map +1 -0
  5. package/dist/cli/args.js +56 -0
  6. package/dist/cli/args.js.map +1 -0
  7. package/dist/cli/help.d.ts +4 -0
  8. package/dist/cli/help.d.ts.map +1 -0
  9. package/dist/cli/help.js +25 -0
  10. package/dist/cli/help.js.map +1 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +6 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/convert.d.ts +17 -0
  16. package/dist/convert.d.ts.map +1 -0
  17. package/dist/convert.js +36 -0
  18. package/dist/convert.js.map +1 -0
  19. package/dist/errors.d.ts +18 -0
  20. package/dist/errors.d.ts.map +1 -0
  21. package/dist/errors.js +22 -0
  22. package/dist/errors.js.map +1 -0
  23. package/dist/index.d.ts +7 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +4 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/loaders/file-loader.d.ts +6 -0
  28. package/dist/loaders/file-loader.d.ts.map +1 -0
  29. package/dist/loaders/file-loader.js +20 -0
  30. package/dist/loaders/file-loader.js.map +1 -0
  31. package/dist/loaders/loader.d.ts +15 -0
  32. package/dist/loaders/loader.d.ts.map +1 -0
  33. package/dist/loaders/loader.js +21 -0
  34. package/dist/loaders/loader.js.map +1 -0
  35. package/dist/loaders/url-loader.d.ts +12 -0
  36. package/dist/loaders/url-loader.d.ts.map +1 -0
  37. package/dist/loaders/url-loader.js +42 -0
  38. package/dist/loaders/url-loader.js.map +1 -0
  39. package/dist/parsers/json-parser.d.ts +6 -0
  40. package/dist/parsers/json-parser.d.ts.map +1 -0
  41. package/dist/parsers/json-parser.js +12 -0
  42. package/dist/parsers/json-parser.js.map +1 -0
  43. package/dist/parsers/parser.d.ts +11 -0
  44. package/dist/parsers/parser.d.ts.map +1 -0
  45. package/dist/parsers/parser.js +47 -0
  46. package/dist/parsers/parser.js.map +1 -0
  47. package/dist/parsers/yaml-parser.d.ts +6 -0
  48. package/dist/parsers/yaml-parser.d.ts.map +1 -0
  49. package/dist/parsers/yaml-parser.js +13 -0
  50. package/dist/parsers/yaml-parser.js.map +1 -0
  51. package/dist/renderers/document-renderer.d.ts +12 -0
  52. package/dist/renderers/document-renderer.d.ts.map +1 -0
  53. package/dist/renderers/document-renderer.js +76 -0
  54. package/dist/renderers/document-renderer.js.map +1 -0
  55. package/dist/renderers/markdown.d.ts +10 -0
  56. package/dist/renderers/markdown.d.ts.map +1 -0
  57. package/dist/renderers/markdown.js +46 -0
  58. package/dist/renderers/markdown.js.map +1 -0
  59. package/dist/renderers/renderer.d.ts +16 -0
  60. package/dist/renderers/renderer.d.ts.map +1 -0
  61. package/dist/renderers/renderer.js +12 -0
  62. package/dist/renderers/renderer.js.map +1 -0
  63. package/dist/renderers/sections.d.ts +22 -0
  64. package/dist/renderers/sections.d.ts.map +1 -0
  65. package/dist/renderers/sections.js +209 -0
  66. package/dist/renderers/sections.js.map +1 -0
  67. package/dist/renderers/single-renderer.d.ts +8 -0
  68. package/dist/renderers/single-renderer.d.ts.map +1 -0
  69. package/dist/renderers/single-renderer.js +23 -0
  70. package/dist/renderers/single-renderer.js.map +1 -0
  71. package/dist/run.d.ts +2 -0
  72. package/dist/run.d.ts.map +1 -0
  73. package/dist/run.js +52 -0
  74. package/dist/run.js.map +1 -0
  75. package/dist/template.d.ts +6 -0
  76. package/dist/template.d.ts.map +1 -0
  77. package/dist/template.js +11 -0
  78. package/dist/template.js.map +1 -0
  79. package/dist/types.d.ts +159 -0
  80. package/dist/types.d.ts.map +1 -0
  81. package/dist/types.js +2 -0
  82. package/dist/types.js.map +1 -0
  83. package/dist/utils.d.ts +5 -0
  84. package/dist/utils.d.ts.map +1 -0
  85. package/dist/utils.js +11 -0
  86. package/dist/utils.js.map +1 -0
  87. package/dist/version.d.ts +2 -0
  88. package/dist/version.d.ts.map +1 -0
  89. package/dist/version.js +2 -0
  90. package/dist/version.js.map +1 -0
  91. package/dist/writers/writer.d.ts +8 -0
  92. package/dist/writers/writer.d.ts.map +1 -0
  93. package/dist/writers/writer.js +15 -0
  94. package/dist/writers/writer.js.map +1 -0
  95. 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
+ [![CI](https://github.com/andrezz/openapimd/actions/workflows/ci.yml/badge.svg)](https://github.com/andrezz/openapimd/actions)
4
+ [![npm version](https://img.shields.io/npm/v/@andrezz/openapimd)](https://www.npmjs.com/package/@andrezz/openapimd)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./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"}
@@ -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"}
@@ -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,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ import { run } from './run.js';
3
+ run(process.argv.slice(2)).then((code) => {
4
+ process.exitCode = code;
5
+ });
6
+ //# sourceMappingURL=cli.js.map
@@ -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"}
@@ -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"}
@@ -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"}
@@ -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,6 @@
1
+ import { LoadedSource, SourceLoader } from './loader.js';
2
+ export declare class FileLoader implements SourceLoader {
3
+ canLoad(source: string): boolean;
4
+ load(source: string): Promise<LoadedSource>;
5
+ }
6
+ //# sourceMappingURL=file-loader.d.ts.map
@@ -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,6 @@
1
+ import { OpenApiSpec } from '../types.js';
2
+ import { SpecParser } from './parser.js';
3
+ export declare class JsonParser implements SpecParser {
4
+ parse(content: string): OpenApiSpec;
5
+ }
6
+ //# sourceMappingURL=json-parser.d.ts.map
@@ -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