Skip to content

Commit

Permalink
feat: add x-origin property
Browse files Browse the repository at this point in the history
  • Loading branch information
aeworxet committed Mar 11, 2024
1 parent 9e34bd4 commit 6389f8e
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 47 deletions.
8 changes: 3 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ import { resolveV3Document } from './v3/parser';
export default async function bundle(files: string[], options: any = {}) {
if (typeof options.base !== 'undefined') {
options.base = toJS(options.base);
await parse(options.base);
await parse(options.base, options);
}

const parsedJsons = files.map(file => toJS(file)) as AsyncAPIObject[];
Expand All @@ -89,15 +89,13 @@ export default async function bundle(files: string[], options: any = {}) {
let resolvedJsons;

if (majorVersion === 3) {
resolvedJsons = await resolveV3Document(parsedJsons);
resolvedJsons = await resolveV3Document(parsedJsons, options);
} else {
/**
* Bundle all external references for each file.
* @private
*/
resolvedJsons = await resolve(parsedJsons, {
referenceIntoComponents: options.referenceIntoComponents,
});
resolvedJsons = await resolve(parsedJsons, options);
}

return new Document(resolvedJsons as AsyncAPIObject[], options.base);
Expand Down
61 changes: 34 additions & 27 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,53 +11,60 @@ const parser = new Parser();
* @param {Object[]} JSONSchema
* @private
*/
export async function parse(JSONSchema: AsyncAPIObject) {
export async function parse(JSONSchema: AsyncAPIObject, options: any = {}) {
let validationResult: any[] = [];
addXOrigins(JSONSchema);

const dereferencedJSONSchema = await $RefParser.dereference(JSONSchema, {
dereference: {
circular: false,
// excludedPathMatcher: (path: string): boolean => {
// return (
// // prettier-ignore
// !!(/#\/channels\/[a-zA-Z0-9]*\/servers/).exec(path) ||
// !!(/#\/operations\/[a-zA-Z0-9]*\/channel/).exec(path) ||
// !!(/#\/operations\/[a-zA-Z0-9]*\/messages/).exec(path) ||
// !!(/#\/operations\/[a-zA-Z0-9]*\/reply\/channel/).exec(path) ||
// !!(/#\/operations\/[a-zA-Z0-9]*\/reply\/messages/).exec(path) ||
// !!(/#\/components\/channels\/[a-zA-Z0-9]*\/servers/).exec(path) ||
// !!(/#\/components\/operations\/[a-zA-Z0-9]*\/channel/).exec(path) ||
// !!(/#\/components\/operations\/[a-zA-Z0-9]*\/messages/).exec(path) ||
// !!(/#\/components\/operations\/[a-zA-Z0-9]*\/reply\/channel/).exec(
// path
// ) ||
// !!(/#\/components\/operations\/[a-zA-Z0-9]*\/reply\/messages/).exec(
// path
// )
// );
// },
excludedPathMatcher: (path: string): boolean => {
return (
// prettier-ignore
!!(/#\/[a-zA-Z0-9]*/).exec(path)// ||
// !!(/#\/channels\/[a-zA-Z0-9]*\/servers/).exec(path) ||
// !!(/#\/operations\/[a-zA-Z0-9]*\/channel/).exec(path) ||
// !!(/#\/operations\/[a-zA-Z0-9]*\/messages/).exec(path) ||
// !!(/#\/operations\/[a-zA-Z0-9]*\/reply\/channel/).exec(path) ||
// !!(/#\/operations\/[a-zA-Z0-9]*\/reply\/messages/).exec(path) ||
// !!(/#\/components\/channels\/[a-zA-Z0-9]*\/servers/).exec(path) ||
// !!(/#\/components\/operations\/[a-zA-Z0-9]*\/channel/).exec(path) ||
// !!(/#\/components\/operations\/[a-zA-Z0-9]*\/messages/).exec(path) ||
// !!(/#\/components\/operations\/[a-zA-Z0-9]*\/reply\/channel/).exec(
// path
// ) ||
// !!(/#\/components\/operations\/[a-zA-Z0-9]*\/reply\/messages/).exec(
// path
// )
);
},
},
});

const result = await parser.validate(
JSON.parse(JSON.stringify(dereferencedJSONSchema))
);
// Option `noValidation: true` is used by the testing system, which
// intentionally feeds Bundler wrong AsyncAPI Documents, thus it is not
// documented.
if (!options.noValidation) {
validationResult = await parser.validate(
JSON.parse(JSON.stringify(dereferencedJSONSchema))
);
}

// If Parser's `validate()` function returns a non-empty array with at least
// one `severity: 0`, that means there was at least one error during
// validation, not a `warning: 1`, `info: 2`, or `hint: 3`. Thus, array's
// elements with `severity: 0` are outputted as a list of remarks, and the
// program exits without doing anything further.
if (
result.length !== 0 &&
result.map(element => element.severity).includes(0)
validationResult.length !== 0 &&
validationResult.map(element => element.severity).includes(0)
) {
console.log(
'Validation of the resulting AsyncAPI Document failed.\nList of remarks:\n',
result.filter(element => element.severity === 0)
validationResult.filter(element => element.severity === 0)
);
throw new Error();
}

return result;
return dereferencedJSONSchema;
}
2 changes: 1 addition & 1 deletion src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export const resolve = async (
// await parse(asyncapiDocument);
// }
addXOrigins(asyncapiDocument); // eslint-disable-line @typescript-eslint/no-use-before-define
await parse(asyncapiDocument);
await parse(asyncapiDocument, options);
// const bundledAsyncAPIDocument = await $RefParser.bundle(asyncapiDocument);
docs.push(asyncapiDocument);
}
Expand Down
33 changes: 22 additions & 11 deletions src/v3/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import { AsyncAPIObject } from 'spec-types';

const parser = new Parser();

export async function parse(JSONSchema: AsyncAPIObject) {
export async function parse(JSONSchema: AsyncAPIObject, options: any = {}) {
let validationResult: any[] = [];

addXOrigins(JSONSchema);

const dereferencedJSONSchema = await $RefParser.dereference(JSONSchema, {
Expand All @@ -15,6 +17,7 @@ export async function parse(JSONSchema: AsyncAPIObject) {
excludedPathMatcher: (path: string): boolean => {
return (
// prettier-ignore
!!(/#\/[a-zA-Z0-9]*/).exec(path) ||
!!(/#\/channels\/[a-zA-Z0-9]*\/servers/).exec(path) ||
!!(/#\/operations\/[a-zA-Z0-9]*\/channel/).exec(path) ||
!!(/#\/operations\/[a-zA-Z0-9]*\/messages/).exec(path) ||
Expand All @@ -34,38 +37,46 @@ export async function parse(JSONSchema: AsyncAPIObject) {
},
});

const result = await parser.validate(
JSON.parse(JSON.stringify(dereferencedJSONSchema))
);

// Option `noValidation: true` is used by the testing system, which
// intentionally feeds Bundler wrong AsyncAPI Documents, thus it is not
// documented.
if (!options.noValidation) {
validationResult = await parser.validate(
JSON.parse(JSON.stringify(dereferencedJSONSchema))
);
}

// If Parser's `validate()` function returns a non-empty array with at least
// one `severity: 0`, that means there was at least one error during
// validation, not a `warning: 1`, `info: 2`, or `hint: 3`. Thus, array's
// elements with `severity: 0` are outputted as a list of remarks, and the
// program exits without doing anything further.
if (
result.length !== 0 &&
result.map(element => element.severity).includes(0)
validationResult.length !== 0 &&
validationResult.map(element => element.severity).includes(0)
) {
console.log(
'Validation of the resulting AsyncAPI Document failed.\nList of remarks:\n',
result.filter(element => element.severity === 0)
validationResult.filter(element => element.severity === 0)
);
throw new Error();
}

return result;
return dereferencedJSONSchema;
}

export async function resolveV3Document(asyncapiDocuments: AsyncAPIObject[]) {
export async function resolveV3Document(
asyncapiDocuments: AsyncAPIObject[],
options: any = {}
) {
const docs = [];

// Graceful `return` doesn't stop Bundler from writing an invalid
// `asyncapi.yaml` (while it should,) thus the full program is abnormally
// terminated through `try...catch`, which is a forced decision.
try {
for (const asyncapiDocument of asyncapiDocuments) {
await parse(asyncapiDocument);
await parse(asyncapiDocument, options);
docs.push(asyncapiDocument);
}
} catch (e) {} // eslint-disable-line no-empty
Expand Down
8 changes: 5 additions & 3 deletions tests/lib/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('[integration testing] bundler should ', () => {
path.resolve(process.cwd(), './tests/base.yml'),
'utf-8'
),
validate: false,
noValidation: true,
}
);

Expand All @@ -36,6 +36,7 @@ describe('[integration testing] bundler should ', () => {
),
{
referenceIntoComponents: false,
noValidation: true,
}
)
).resolves;
Expand All @@ -54,6 +55,7 @@ describe('[integration testing] bundler should ', () => {
),
{
referenceIntoComponents: false,
noValidation: true,
}
)
).resolves;
Expand All @@ -65,7 +67,7 @@ describe('[integration testing] bundler should ', () => {
expect(
await bundle(
files.map(file => fs.readFileSync(path.resolve(process.cwd(), file), 'utf-8')),
{ referenceIntoComponents: false, base: fs.readFileSync(path.resolve(process.cwd(), './tests/base-option/base.yaml'), 'utf-8') }
{ referenceIntoComponents: false, base: fs.readFileSync(path.resolve(process.cwd(), './tests/base-option/base.yaml'), 'utf-8'), noValidation: true, }
)
).resolves;

Expand All @@ -76,7 +78,7 @@ describe('[integration testing] bundler should ', () => {
expect(
await bundle(
files.map(file => fs.readFileSync(path.resolve(process.cwd(), file), 'utf-8')),
{baseDir: './tests/specfiles'}
{baseDir: './tests/specfiles', noValidation: true}
)
).resolves
})
Expand Down

0 comments on commit 6389f8e

Please sign in to comment.