Skip to content

Commit 1c1a1b9

Browse files
committed
feat(asyncapi-plugin): enhance schema parsing with @redocly/openapi-core integration
1 parent 5fb88e4 commit 1c1a1b9

8 files changed

Lines changed: 755 additions & 889 deletions

File tree

packages/asyncapi-plugin/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@
3535
"@qraft/plugin": "workspace:*",
3636
"ansi-colors": "^4.1.3",
3737
"commander": "^14.0.2",
38+
"js-yaml": "^4.1.0",
3839
"ora": "^8.2.0"
3940
},
4041
"devDependencies": {
4142
"@asyncapi/parser": "^3.4.0",
4243
"@openapi-qraft/eslint-config": "workspace:*",
4344
"@openapi-qraft/rollup-config": "workspace:*",
45+
"@types/js-yaml": "^4.0.9",
4446
"@types/node": "^20.16.5",
4547
"eslint": "^9.39.1",
4648
"memfs": "^4.11.1",

packages/asyncapi-plugin/src/lib/readSchema.ts

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import type { Readable } from 'node:stream';
22
// eslint-disable-next-line import-x/no-extraneous-dependencies
33
import type { AsyncAPIDocumentInterface } from '@asyncapi/parser';
4+
import fs from 'node:fs';
45
import { fileURLToPath } from 'node:url';
56
// eslint-disable-next-line import-x/no-extraneous-dependencies
6-
import { fromFile, fromURL, Parser } from '@asyncapi/parser';
7+
import { Parser } from '@asyncapi/parser';
8+
import { load } from 'js-yaml';
79

810
export interface AsyncAPISchemaResult {
911
document: AsyncAPIDocumentInterface;
@@ -28,17 +30,21 @@ export async function readSchema(
2830

2931
if (source instanceof URL) {
3032
if (source.protocol === 'file:') {
31-
parseResult = await fromFile(parser, fileURLToPath(source)).parse();
33+
rawSchemaSource = fs.readFileSync(fileURLToPath(source), 'utf-8');
34+
parseResult = await parser.parse(rawSchemaSource);
3235
} else {
33-
parseResult = await fromURL(parser, source.toString()).parse();
36+
rawSchemaSource = await fetchContent(source.toString());
37+
parseResult = await parser.parse(rawSchemaSource);
3438
}
3539
} else if (
3640
typeof source === 'string' &&
3741
(source.startsWith('http://') || source.startsWith('https://'))
3842
) {
39-
parseResult = await fromURL(parser, source).parse();
43+
rawSchemaSource = await fetchContent(source);
44+
parseResult = await parser.parse(rawSchemaSource);
4045
} else if (typeof source === 'string') {
41-
parseResult = await fromFile(parser, source).parse();
46+
rawSchemaSource = fs.readFileSync(source, 'utf-8');
47+
parseResult = await parser.parse(rawSchemaSource);
4248
} else {
4349
rawSchemaSource = await streamToString(source);
4450
parseResult = await parser.parse(rawSchemaSource);
@@ -57,16 +63,35 @@ export async function readSchema(
5763
}
5864

5965
const rawSchema = rawSchemaSource
60-
? (JSON.parse(rawSchemaSource) as Record<string, unknown>)
66+
? parseRawSchema(rawSchemaSource)
6167
: (document.json() as Record<string, unknown>);
6268

6369
return { document, rawSchema };
6470
}
6571

72+
function parseRawSchema(content: string): Record<string, unknown> {
73+
const trimmed = content.trim();
74+
if (trimmed[0] === '{' || trimmed[0] === '[') {
75+
return JSON.parse(trimmed);
76+
}
77+
return load(trimmed) as Record<string, unknown>;
78+
}
79+
80+
async function fetchContent(url: string): Promise<string> {
81+
const response = await fetch(url);
82+
if (!response.ok) {
83+
throw new Error(
84+
`Failed to fetch ${url}: ${response.status} ${response.statusText}`
85+
);
86+
}
87+
return response.text();
88+
}
89+
6690
async function streamToString(stream: Readable): Promise<string> {
67-
const chunks: Buffer[] = [];
91+
let result = '';
92+
stream.setEncoding('utf-8');
6893
for await (const chunk of stream) {
69-
chunks.push(Buffer.from(chunk));
94+
result += chunk;
7095
}
71-
return Buffer.concat(chunks).toString('utf-8');
96+
return result;
7297
}

0 commit comments

Comments
 (0)