asyncapi / bundler

Combine multiple AsyncAPI specification files into one.
Apache License 2.0
29 stars 15 forks source link

feat: add `x-origin` property #147

Closed aeworxet closed 6 months ago

aeworxet commented 9 months ago

This PR adds the generation of the property x-origin during the dereferencing process. Property x-origin is used for origin tracing in Bundler and component naming in Optimizer.

It originated from this comment in a year-long discussion: 

The $ref usually also carries a semantical meaning to understand easier what it is (example "$ref : financial-system.yaml#/components/schemas/bankAccountIdentifier"). If the bundling just resolves this ref inline, the semantical meaning of the $ref pointer gets lost and cannot be recovered in later steps. The optimizer would need to invent an artificial component name for the "bankAccountIdentifier" when moving it to the components section.

Thus, property x-origin contains historical values of dereferenced $refs, which are also used by Optimizer starting from its version v1.0.0, to give meaningful names to components it moves through the AsyncAPI Document.

Partial resolution of https://github.com/asyncapi/bundler/issues/141

aeworxet commented 9 months ago

@KhudaDad414 @derberg @asyncapi/bounty_team

savvyintegrations commented 7 months ago

For anyone waiting on this PR who doesn't want to fork, and doesn't need x-origin per se (but simply better deref), you can use @apidevtools/json-schema-ref-parser in your local script before calling bundler, i.e., just dereference first, e.g.:

import bundle from '@asyncapi/bundler';
import $RefParser from "@apidevtools/json-schema-ref-parser";
import { writeFileSync } from 'fs';
import { resolve } from "node:path"
import { mkdir } from "node:fs/promises"

process.chdir("specs")

const srcFileName = 'events.asyncapi.yml';
const outputBase = resolve("../generated/docs/specs") + "/"
const outputPath = `${outputBase}${srcFileName}`;

try {
    await mkdir(outputBase, {recursive: true})
    const clonedSchema = await $RefParser.dereference(srcFileName, {
        dereference: {
            excludedPathMatcher: (path) => path.includes("operations")
        },
        mutateInputSchema: false
    });
    const document = await bundle([clonedSchema], {
        referenceIntoComponents: true,
    });
    writeFileSync(outputPath, document.yml());
    console.log(`Bundled ${srcFileName} to ${outputPath}`)
} catch (err) {
    console.error(err);
}
aeworxet commented 6 months ago

This PR is ready for merge, but it should be merged only AFTER https://github.com/asyncapi/optimizer/pull/216 is merged (it will be merged only to next not master) and Optimizer 1.0.0 is released, due to the transfer of functionality of moving components into components to Optimizer starting from its version v1.0.0.

sonarcloud[bot] commented 6 months ago

Quality Gate Passed Quality Gate passed

Issues
0 New issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
0.0% Duplication on New Code

See analysis details on SonarCloud

aeworxet commented 6 months ago

/rtm

asyncapi-bot commented 6 months ago

:tada: This PR is included in version 0.5.0 :tada:

The release is available on:

Your semantic-release bot :package::rocket: