-
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: migration of the codebase to TypeScript (#56)
- Loading branch information
Showing
8 changed files
with
294 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { merge } from 'lodash'; | ||
import yaml from 'js-yaml'; | ||
|
||
//import type { Schema } from '@asyncapi/parser'; | ||
import { JSONSchema7 } from 'json-schema'; | ||
|
||
export interface Document { | ||
_doc: JSONSchema7; | ||
} | ||
|
||
/** | ||
* @class | ||
* | ||
* @example | ||
* | ||
* const document = new Document(parsedJSONList, base); | ||
* | ||
* console.log(document.json()); // get json object | ||
* console.log(document.yml()); // get yaml string | ||
* console.log(document.string()); // get json string | ||
*/ | ||
|
||
export class Document { | ||
/** | ||
* | ||
* @param {Object[]} parsedJSONList | ||
* @param {Object} base | ||
*/ | ||
constructor(parsedJSONList: JSONSchema7[], base: JSONSchema7) { | ||
for (const resolvedJSON of parsedJSONList) { | ||
this._doc = merge(this._doc, resolvedJSON); | ||
} | ||
|
||
if (typeof base !== "undefined") { | ||
this._doc = merge(this._doc, base); | ||
} | ||
} | ||
|
||
/** | ||
* @return {Object} | ||
*/ | ||
json() { | ||
return this._doc; | ||
} | ||
|
||
/** | ||
* @return {string} | ||
*/ | ||
yml() { | ||
return yaml.dump(this._doc); | ||
} | ||
|
||
/** | ||
* @return {string} | ||
*/ | ||
string(){ | ||
return JSON.stringify(this._doc); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { ParserError } from './parsererror'; | ||
|
||
export { ParserError }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export class ParserError extends Error { | ||
constructor({ type, title }: { type: string; title: string }) { | ||
super(); | ||
this.message = title; | ||
this.name = type; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { toJS, resolve } from "./util"; | ||
import { Document } from "./document"; | ||
|
||
//import { Schema } from '@asyncapi/parser'; | ||
import { JSONSchema7 } from 'json-schema'; | ||
|
||
/** | ||
* | ||
* @param {string[] | Object[]} files files that are to be bundled | ||
* @param {Object} options | ||
* @param {string | object} options.base base object whose prperties will be retained. | ||
* @param {boolean} options.referenceIntoComponents pass true value to resolve references into component | ||
* | ||
* @return {Document} | ||
* | ||
* @example | ||
* | ||
* const bundle = requrie('@asyncapi/bundler'); | ||
* const fs = require('fs'); | ||
* const path = requrie('path'); | ||
* | ||
* const document = await bundle(fs.readFileSync( | ||
* path.resolve('./asyncapi.yaml', 'utf-8') | ||
* )); | ||
* | ||
* console.log(document.yml()); | ||
*/ | ||
export const bundle = async (files: JSONSchema7[], options: any = {}) => { | ||
if (typeof options.base !== "undefined") { | ||
options.base = toJS(options.base); | ||
} | ||
|
||
const parsedJsons = files.map(file => toJS(file)) as JSONSchema7[]; | ||
/** | ||
* Bundle all external references for each files. | ||
*/ | ||
const resolvedJsons = await resolve(parsedJsons, {referenceIntoComponents: options.referenceIntoComponents}); | ||
|
||
return new Document(resolvedJsons as JSONSchema7[], options.base); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import $RefParser from '@apidevtools/json-schema-ref-parser'; | ||
import { JSONPath } from 'jsonpath-plus'; | ||
import { merge } from 'lodash'; | ||
|
||
//import { Schema } from '@asyncapi/parser'; | ||
import { JSONSchema7 } from 'json-schema'; | ||
|
||
class ExternalComponents { | ||
ref; | ||
resolvedJSON; | ||
constructor(ref: string, resolvedJSON: string) { | ||
this.ref = ref; | ||
this.resolvedJSON = resolvedJSON; | ||
} | ||
|
||
getKey() { | ||
const keys = this.ref.split('/'); | ||
return keys[keys.length - 1] | ||
} | ||
|
||
getValue() { | ||
return this.resolvedJSON; | ||
} | ||
} | ||
|
||
/** | ||
* resolves external references and updates $refs | ||
* @param {Object[]} JSONSchema | ||
*/ | ||
export async function parse(JSONSchema: JSONSchema7) { | ||
const $ref = await $RefParser.resolve(JSONSchema); | ||
const refs = crawlChanelPropertiesForRefs(JSONSchema); | ||
for (let ref of refs) { | ||
if (isExternalReference(ref)) { | ||
const componentObject = await resolveExternalRefs(JSONSchema, $ref); | ||
if (JSONSchema.components) { | ||
merge(JSONSchema.components, componentObject); | ||
} else { | ||
JSONSchema.components = componentObject | ||
} | ||
} | ||
} | ||
} | ||
|
||
function crawlChanelPropertiesForRefs(JSONSchema: JSONSchema7) { | ||
return JSONPath({ json: JSONSchema, path: `$.channels.*.*.message['$ref']` }); | ||
} | ||
|
||
/** | ||
* This function checks for external reference. | ||
* @param {string} ref | ||
* @returns {boolean} | ||
*/ | ||
function isExternalReference(ref: string) { | ||
return !ref.startsWith('#') | ||
} | ||
|
||
/** | ||
* | ||
* @param {Object[]} parsedJSON | ||
* @param {$RefParser} $refs | ||
* @returns {ExternalComponents} | ||
*/ | ||
async function resolveExternalRefs(parsedJSON: JSONSchema7, $refs: JSONSchema7) { | ||
const componentObj = { messages: {} }; | ||
JSONPath({ json: parsedJSON, resultType: 'all', path: '$.channels.*.*.message' }).forEach(({ parent, parentProperty }) => { | ||
const ref = parent[parentProperty]['$ref']; | ||
if (isExternalReference(ref)) { | ||
const value = $refs.get(ref); | ||
const component = new ExternalComponents(ref, value); | ||
componentObj.messages[String(component.getKey())] = component.getValue() | ||
parent[parentProperty]['$ref'] = `#/components/messages/${component.getKey()}`; | ||
} | ||
}) | ||
return componentObj | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { ParserError } from "./errors"; | ||
import $RefParser from '@apidevtools/json-schema-ref-parser'; | ||
import { parse } from './parser'; | ||
import yaml from "js-yaml"; | ||
import { cloneDeep } from 'lodash'; | ||
|
||
//import { Schema } from '@asyncapi/parser'; | ||
import { JSONSchema7 } from 'json-schema'; | ||
|
||
export const toJS = (asyncapiYAMLorJSON: JSONSchema7) => { | ||
|
||
if (!asyncapiYAMLorJSON) { | ||
throw new ParserError({ | ||
type: "null-or-falsy-document", | ||
title: "Document can't be null or falsey.", | ||
}); | ||
} | ||
|
||
if ( | ||
asyncapiYAMLorJSON.constructor && | ||
asyncapiYAMLorJSON.constructor.name === "Object" | ||
) { | ||
return asyncapiYAMLorJSON | ||
} | ||
|
||
if (typeof asyncapiYAMLorJSON !== "string") { | ||
throw new ParserError({ | ||
type: "invalid-document-type", | ||
title: "The AsyncAPI document has to be either a string or a JS object.", | ||
}); | ||
} | ||
|
||
if (JSON.stringify(asyncapiYAMLorJSON).trimStart().startsWith("{")) { | ||
throw new ParserError({ | ||
type: 'invalid-yaml', | ||
title: 'The provided yaml is not valid.' | ||
}) | ||
} | ||
return yaml.load(asyncapiYAMLorJSON); | ||
}; | ||
|
||
export const validate = async ( | ||
parsedJSONs: JSONSchema7[], | ||
parser: { parse(asyncapi: string | any): Promise<any> } | ||
) => { | ||
for (const parsedJSON of parsedJSONs) { | ||
await parser.parse(cloneDeep(parsedJSON)); | ||
} | ||
}; | ||
|
||
/** | ||
* | ||
* @param {Object} asyncapiDocuments | ||
* @param {Object} options | ||
* @param {boolean} options.referenceIntoComponents | ||
* @returns {Array<Object>} | ||
*/ | ||
export const resolve = async (asyncapiDocuments: JSONSchema7[], options: any) => { | ||
let docs = []; | ||
|
||
for (const asyncapiDocument of asyncapiDocuments) { | ||
if (options.referenceIntoComponents) { | ||
await parse(asyncapiDocument as JSONSchema7); | ||
} | ||
const bundledAsyncAPIDocument = await $RefParser.bundle(asyncapiDocument as JSONSchema7); | ||
docs.push(bundledAsyncAPIDocument); | ||
} | ||
|
||
return docs; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
"compilerOptions": { | ||
"outDir": "./lib", | ||
"baseUrl": "./src", | ||
"target": "es6", | ||
"lib": [ | ||
"esnext" | ||
], | ||
"declaration": true, | ||
"allowJs": true, | ||
"skipLibCheck": true, | ||
"esModuleInterop": true, | ||
"allowSyntheticDefaultImports": true, | ||
"strict": true, | ||
"forceConsistentCasingInFileNames": true, | ||
"noFallthroughCasesInSwitch": true, | ||
"module": "esnext", | ||
"moduleResolution": "node", | ||
"resolveJsonModule": true, | ||
"isolatedModules": true, | ||
}, | ||
"include": [ | ||
"src" | ||
] | ||
} |