Package Status
Allows to expand the OpenAPI JSON specification description
fields with the arbitrary markdown files translated to HTML.
Assume we have the OpenAPI specification definitions in contract/definitions/my-api-definitions.oas.json
file in the project with this folder structure.
contract
├── definitions
│ └── my-api-definitions.oas.json
├── merged
│ └── my-api-definitions-merged.oas.json
└── docs
├── one.md
└── nested
└── two.md
In the desired places of the specification in the description
fields we add the merge tags of the kind {% merge 'path/file.md' %}
.
{
"tags": [
{
"name": "pet",
"description": "Everything about your Pets\n\r{% merge './one.md' %}"
}
],
"id": {
"description": "{% merge './nested/two.md' %}",
"type": "integer"
}
}
We can combine tags with inlined description text as for the first example. Then the merged content is added into the existing description
field preserving the content outer to the merge tag. This way you can insert the merged markdown content within the description
field content.
Or you can use "merge" tag alone in a description
field as for the second example.
Assuming the above project you wil get the markdown files content merged into the description
fields using the following oas-markdown-merger
basic CLI usage example:
npx oas-markdown-merger --source ./definitions/my-api-definitions.oas.json \
--destination ./merged/my-api-definitions-merged.oas.json \
--merges-base ./docs
The destination file ./merged/my-api-definitions-merged.oas.json
will have the description
fields containing the content of the respective markdown files translated to HTML (sanitized).
Not only CLI but also Programmatic Usage is available.
npm install oas-markdown-merger
# Output CLI help
npx oas-markdown-merger --help
# Use the project root as the base path for markdown files mentions in "merge" tags.
npx oas-markdown-merger --source source.json --destination destination.json
# Use the desired folder as the markdown files base path
npx oas-markdown-merger --source source.json --destination destination.json --merges-base ./docs
Using optional --merge-base
parameter we can place our markdown documents into a separated location for better modularization (the latter CLI example above). Using different sub-folders in "merge" tags we can further separate different docs in their own locations like shown in the Overview.
The usage similar to the CLI above with files containing OAS definitions, but now programmatically.
// Import the package and assign arguments for brevity.
import { OASMarkdownMergerFacade } from 'oas-markdown-merger';
const source = './definitions/my-api-definitions.oas.json';
const destination = './merged/my-api-definitions-merged.oas.json';
Use the project root as the base path for markdown files mentions in "merge" tags.
const facade = OASMarkdownMergerFacade.create();
await facade.merge(source, destination);
Use the desired folder as the markdown files base path. The optional parameter for .create()
method denotes the merging markdown files base path.
const facade = OASMarkdownMergerFacade.create('./docs');
await facade.merge(source, destination);
The package does not restrict the source and destination to be files only. For consumers desiring to build the markdown merge into their code it is possible to use memory variables for source and destination.
There are several scenarios for this use case. They assume using the above folders structure and content.
Merge the entire OAS definitions document or just a part of any JSON document potentially containing description
fields with "merge" tags. Note that the merge operation mutates the source in-place in case there are mergeable (containing "merge" tags) description
field.
Example 1: Default mergesBasePath
Note OASMarkdownMergerFacade.create
method's mergesBasePath
parameter is omitted and it defaults to the project working directory (project.cwd()
).
Note the "merge" tag contains ./docs/one.md
filename providing the file location in ./docs
folder.
import { OASMarkdownMergerFacade } from 'oas-markdown-merger';
const oas = { field: 'something', tags: [{ description: "{% merge './docs/one.md' %}" }] };
const merger = OASMarkdownMergerFacade.create();
merger.mergeInMemory(oas); // Mutates the source in-place
Example 2: Custom mergesBasePath
It assumes the merged files will be located in a specific merge files base directory ./docs
.
Note the first "merge" tag now contains ./one.md
and the second filename providing the file location in ./docs
folder.
import { OASMarkdownMergerFacade } from 'oas-markdown-merger';
const oas = {
field: 'something',
tags: [{ description: "{% merge './one.md' %}" }, { description: "{% merge './nested/two.md' %}" }]
};
const merger = OASMarkdownMergerFacade.create('./docs');
merger.mergeInMemory(oas);
You could use the in-memory merge even more granularly, for a single description
value.
Example 3: Custom mergesBasePath
import { MergeableDescriptionVO } from 'oas-markdown-merger';
const key = 'description';
const jsonPath = ['tags', '0', 'description'];
const keyValue = `Everything about your Pets {% merge './one.md' %}`;
const mergesBasePath = './docs';
const mergeable = MergeableDescriptionVO.create(key, jsonPath, keyValue, mergesBasePath);
if (mergeable) {
const merged = mergeable.merged();
}
Here merged
variable will contain keyValue
merged with the HTML-translated markdown from ./docs/one.md
. The MergeableDescriptionVO.create()
can return null
. This denotes the provided input is not actually mergeable due to either its key
is not equal description
value or keyValue
not contain the valid "merge" tag.
Note in this particular example the jsonPath
(see (JSON Path Segments)(https://www.rfc-editor.org/rfc/rfc9535#section-1.4.2)) parameter / argument is not essential and can be set to []
.
But in real life it keeps the target location of the mergeable value in the source JSON document nearby the the value itself (hence one of the MergeableDescriptionVO
value object reasons to exist). It allows to decouple the OAS / JSON traversing from merging markdown files and from further merged value assignment.
In-memory merge can be useful in scenarios where the consumer code e.g. bundles OpenAPI $ref
'ed files into single OAS definitions bundle like swagger-cli bundle
command does.
Note, however swagger-cli
is mentioned here just as an OAS bundler example, it does use oas-markdown-merger
. Nevertheless you can use oas-markdown-merger
in your OAS definitions build pipelines on OAS definitions previously bundled with any desired tool.
The package is written in TypeScript with the careful JSDoc blocks available on hover for public interface (e.g. in VS Code).
The project is production-ready and actively maintained.
Potentially valuable use cases / functionality suggestions as well as usage questions are welcome in Discussions.
If there is a pull request, I would receive it on integration
branch for discussion and manual merge.
This project is licensed under the MIT License - see the LICENSE file for details.
The implementation documentation is here.