From 0e4cf6f8096ffabd6bcfbe4252c850ae1c1f18c1 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sat, 28 Mar 2020 15:01:00 +0100 Subject: [PATCH 001/110] Initial commit from generator --- .filters/all.js | 157 ++++++++++++++++++ .hooks/rename-njk.js | 22 +++ .partials/channel/publish.njk | 19 +++ .partials/channel/reply.njk | 60 +++++++ .partials/channel/request.njk | 27 +++ .partials/channel/subscribe.njk | 39 +++++ .partials/index/publish.njk | 10 ++ .partials/index/reply.njk | 11 ++ .partials/index/request.njk | 10 ++ .partials/index/subscribe.njk | 10 ++ README.md | 10 +- __package.json.njk | 44 +++++ package-lock.json | 49 ++++++ package.json | 18 ++ src/channels/$$channel$$.ts.njk | 32 ++++ src/index.ts.njk | 75 +++++++++ src/messages/$$message$$.ts.njk | 79 +++++++++ src/schema/$$everySchema$$.ts.njk | 32 ++++ src/test/testclient/index.ts.njk | 70 ++++++++ .../testchannels/$$channel$$.ts.njk | 32 ++++ tsconfig.json | 15 ++ 21 files changed, 819 insertions(+), 2 deletions(-) create mode 100644 .filters/all.js create mode 100644 .hooks/rename-njk.js create mode 100644 .partials/channel/publish.njk create mode 100644 .partials/channel/reply.njk create mode 100644 .partials/channel/request.njk create mode 100644 .partials/channel/subscribe.njk create mode 100644 .partials/index/publish.njk create mode 100644 .partials/index/reply.njk create mode 100644 .partials/index/request.njk create mode 100644 .partials/index/subscribe.njk create mode 100644 __package.json.njk create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/channels/$$channel$$.ts.njk create mode 100644 src/index.ts.njk create mode 100644 src/messages/$$message$$.ts.njk create mode 100644 src/schema/$$everySchema$$.ts.njk create mode 100644 src/test/testclient/index.ts.njk create mode 100644 src/test/testclient/testchannels/$$channel$$.ts.njk create mode 100644 tsconfig.json diff --git a/.filters/all.js b/.filters/all.js new file mode 100644 index 000000000..13ff56e4f --- /dev/null +++ b/.filters/all.js @@ -0,0 +1,157 @@ +const URL = require('url'); +const path = require('path'); + +module.exports = ({ Nunjucks, _ }) => { + Nunjucks.addFilter('kebabCase', string => { + return _.kebabCase(string); + }); + + Nunjucks.addFilter('camelCase', string => { + return camelCase(string); + }); + function camelCase(string) { + return _.camelCase(string); + } + + Nunjucks.addFilter('firstLowerCase', string => { + return _.lowerFirst(string); + }); + + Nunjucks.addFilter('firstUpperCase', string => { + return string.charAt(0).toUpperCase() + string.slice(1); + }); + + + + Nunjucks.addFilter('pascalCase', string => { + return pascalCase(string); + }); + function pascalCase(string) { + string = _.camelCase(string); + return string.charAt(0).toUpperCase() + string.slice(1); + } + + Nunjucks.addFilter('toTsType', jsonSchemaType => { + switch (jsonSchemaType.toLowerCase()) { + case 'string': + return 'String'; + case 'integer': + case 'number': + return 'Number'; + case 'boolean': + return 'Boolean'; + } + }); + + Nunjucks.addFilter('constructorParameters', schema => { + let returnString = ''; + if (schema.allOf()) { + schema.allOf().forEach(element => { + returnString += `${camelCase(element.uid())}: ${pascalCase(element.uid())}Schema,`; + }); + } else if (schema.oneOf()) { + returnString += `oneOf: ${getTypeFromOneOf(schema.oneOf())},`; + } else if (schema.anyOf()) { + schema.anyOf().forEach(element => { + returnString += `${camelCase(element.uid())}: ${pascalCase(element.uid())}Schema,`; + }); + } else if (schema.uid()) { + returnString += `${camelCase(schema.uid())}: ${pascalCase(schema.uid())}Schema,`; + } + if (returnString.length > 1) { + returnString = returnString.slice(0, -1); + } + return returnString; + }); + + Nunjucks.addFilter('schemaConstructor', properties => { + let returnString = ''; + for (const [key, value] of Object.entries(properties)) { + returnString += `${key},`; + } + if (returnString.length > 1) { + returnString = returnString.slice(0, -1); + } + return returnString; + }); + + Nunjucks.addFilter('oneLine', string => { + if (!string) return string; + return string.replace(/\n/g, ' '); + }); + + function getTypeFromOneOf(oneFromSchema) { + let type = ''; + + if (oneFromSchema.oneOf().length > 0) { + type += `${getTypeFromOneOf(oneFromSchema.oneOf())}Schema`; + } + + for (var i = 0; i < oneOfSchema.length; i++) { + let schema = oneOfSchema[i]; + if (type !== '') { + type += '|'; + } + if (oneOfSchema.length == i + 1) { + type += schema.uid() + } else { + type += schema.uid() + '|' + } + } + return type; + } + Nunjucks.addFilter('oneOfSchemaType', getTypeFromOneOf); + + Nunjucks.addFilter('fileName', string => { + return _.camelCase(string); + }); + + + Nunjucks.addFilter('tsPayload', (server) => { + return "STRING"; + }); + + Nunjucks.addFilter('tsEncoding', (server) => { + return "STRING"; + }); + + + Nunjucks.addFilter('isPubsub', channel => { + let tempChannel = channel._json; + if (tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'pubsub') { + return true; + } + return false; + }); + + Nunjucks.addFilter('hasNatsBindings', obj => { + if (obj.bindings.nats) { + return true; + } + return false; + }); + + Nunjucks.addFilter('isRequestReply', channel => { + let tempChannel = channel._json; + if (tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'requestReply') { + return true; + } + return false; + }); + + Nunjucks.addFilter('isRequester', channel => { + let tempChannel = channel._json; + if (tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'requestReply' && tempChannel.bindings.nats.requestReply && tempChannel.bindings.nats.requestReply.is == 'requester') { + return true; + } + return false; + }); + + Nunjucks.addFilter('isReplier', channel => { + let tempChannel = channel._json; + if (tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'requestReply' && tempChannel.bindings.nats.requestReply && tempChannel.bindings.nats.requestReply.is == 'replier') { + return true; + } + return false; + }); +}; diff --git a/.hooks/rename-njk.js b/.hooks/rename-njk.js new file mode 100644 index 000000000..7b313ce6f --- /dev/null +++ b/.hooks/rename-njk.js @@ -0,0 +1,22 @@ +const fs = require('fs'); +const path = require('path'); +var renameAllSync = function (dir) { + files = fs.readdirSync(dir); + files.forEach(function (file) { + let filepath = path.resolve(dir, file); + if (fs.statSync(filepath).isDirectory()) { + renameAllSync(filepath); + } else if (path.extname(filepath) === '.njk') { + let baseName = path.basename(filepath, '.ts.njk'); + let newName = + baseName.charAt(0).toUpperCase() + baseName.slice(1) + '.ts'; + let newPath = path.resolve(dir, newName); + fs.renameSync(filepath, newPath); + } + }); +}; +module.exports = register => { + register('generate:after', generator => { + renameAllSync(path.resolve(generator.targetDir)); + }); +}; diff --git a/.partials/channel/publish.njk b/.partials/channel/publish.njk new file mode 100644 index 000000000..7e81ac914 --- /dev/null +++ b/.partials/channel/publish.njk @@ -0,0 +1,19 @@ + +{% macro publish(channelName, publishMessage, server) %} + +export function publish(requestMessage: {{publishMessage.uid() | pascalCase}}Message, nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let dataToPublish = utils.beforePublish(requestMessage, Payload.{{server | tsPayload}}, '{{server | tsEncoding}}'); + nc.publish('{{channelName}}', dataToPublish); + resolve(); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }); +}; +{% endmacro %} diff --git a/.partials/channel/reply.njk b/.partials/channel/reply.njk new file mode 100644 index 000000000..1238ee5f4 --- /dev/null +++ b/.partials/channel/reply.njk @@ -0,0 +1,60 @@ + +{% macro reply(channelName, subscribtionMessage, publishMessage, server) %} +export function reply(onRequest: (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message) => {{publishMessage.uid() | pascalCase}}Message, onReplyError: (err: NatsError) => void, nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + + let subscribeOptions: SubscriptionOptions = {}; + {%- if subscribtionMessage | hasNatsBindings %} + {%- if subscribtionMessage.bindings().nats().queue() | length %} + //If queue + subscribeOptions.queue = '{{subscribtionMessage.bindings().nats().queue().name()}}'; + {%- endif %} + {%- if subscribtionMessage.bindings().nats().unsubAfter() | length %} + //If unsubafter + subscribeOptions.max = {{subscribtionMessage.bindings().nats().unsubAfter()}}; + {%- endif %} + {%- endif %} + + let subscription = nc.subscribe('{{channelName}}', (err, msg) => { + if (err) { + onRequest(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.{{server | tsPayload}}, '{{server | tsEncoding}}'); + let requestData = new {{subscribtionMessage.name() | pascalCase}}Message(); + requestData.copyFrom(processedData); + + let responseObject = onRequest(undefined, requestData); + if (msg.reply) { + try { + let requestData = utils.beforeResponse(responseObject, Payload.{{server | tsPayload}}, '{{server | tsEncoding}}'); + nc.publish(msg.reply, requestData); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + console.error(error) + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + +{% endmacro %} diff --git a/.partials/channel/request.njk b/.partials/channel/request.njk new file mode 100644 index 000000000..a66f8a13d --- /dev/null +++ b/.partials/channel/request.njk @@ -0,0 +1,27 @@ + +{% macro request(channelName, publishMessage, subscribtionMessage, server) %} +export function request(requestMessage: {{publishMessage.uid() | pascalCase}}Message, nc?: Client): Promise<{{subscribtionMessage.uid() | pascalCase}}Message> { + return new Promise<{{subscribtionMessage.uid() | pascalCase}}Message>(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.{{server | tsPayload}}, '{{server | tsEncoding}}'); + resolve({{subscribtionMessage.uid() | pascalCase}}Message.toMessage(processedData)); + } + }, { max: 1 }); + let requestData = utils.beforeRequest(requestMessage, Payload.{{server | tsPayload}}, '{{server | tsEncoding}}'); + nc.publish('{{channelName}}', requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + +{% endmacro %} diff --git a/.partials/channel/subscribe.njk b/.partials/channel/subscribe.njk new file mode 100644 index 000000000..271b13891 --- /dev/null +++ b/.partials/channel/subscribe.njk @@ -0,0 +1,39 @@ + +{% macro subscribe(channelName, subscribtionMessage, server) %} +export function subscribe(onDataCallback : (err?: NatsError, msg?: {{subscribtionMessage.uid() | camelCase}}) => void, nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let subscribeOptions: SubscriptionOptions = {}; + {%- if subscribtionMessage | hasNatsBindings %} + {%- if subscribtionMessage.bindings().nats().queue() | length %} + //If queue + subscribeOptions.queue = '{{subscribtionMessage.bindings().nats().queue().name()}}'; + {%- endif %} + {%- if subscribtionMessage.bindings().nats().unsubAfter() | length %} + //If unsubafter + subscribeOptions.max = {{subscribtionMessage.bindings().nats().unsubAfter()}}; + {%- endif %} + {%- endif %} + + let subscription = nc.subscribe('{{channelName}}', (err, msg) => { + if(err){ + onDataCallback(err); + }else{ + let processedData = utils.processRecievedData(msg.data, Payload.{{server | tsPayload}}, '{{server | tsEncoding}}'); + let publishedData = new {{subscribtionMessage.name() | camelCase}}(); + publishedData.copyFrom(processedData); + onDataCallback(undefined, publishedData); + } + }, subscribeOptions); + resolve(subscription); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }) +} + +{% endmacro %} diff --git a/.partials/index/publish.njk b/.partials/index/publish.njk new file mode 100644 index 000000000..e99b7d24e --- /dev/null +++ b/.partials/index/publish.njk @@ -0,0 +1,10 @@ + +{% macro publish(channelName, message, messageDescription) %} + /** + * {{messageDescription}} + * @param requestMessage The message to publish. + */ + public publishTo{{channelName | pascalCase }}(requestMessage: {{ message.uid() | pascalCase }}Message): Promise { + return {{ channelName | camelCase }}Channel.publish(requestMessage, this.nc); + } +{% endmacro %} diff --git a/.partials/index/reply.njk b/.partials/index/reply.njk new file mode 100644 index 000000000..7f325226f --- /dev/null +++ b/.partials/index/reply.njk @@ -0,0 +1,11 @@ + +{% macro reply(channelName, subscribeMessage, publishMessage, messageDescription) %} + /** + * {{messageDescription}} + * @param onRequest Called when request recieved. + * @param onReplyError Called when it was not possible to send the reply. + */ + public replyTo{{channelName | pascalCase }}(onRequest : (err?: NatsError, msg?: {{ subscribeMessage.uid() | pascalCase }}Message) => {{ publishMessage.uid() | pascalCase }}Message, onReplyError : (err: NatsError) => void): Promise { + return {{ channelName | camelCase }}Channel.reply(onRequest, onReplyError, this.nc); + } +{% endmacro %} diff --git a/.partials/index/request.njk b/.partials/index/request.njk new file mode 100644 index 000000000..270f6399f --- /dev/null +++ b/.partials/index/request.njk @@ -0,0 +1,10 @@ + +{% macro request(channelName, publishMessage, subscribeMessage, messageDescription) %} + /** + * {{messageDescription}} + * @param requestMessage The request message to send. + */ + public request{{channelName | pascalCase }}(requestMessage: {{ publishMessage.uid() | pascalCase }}Message): Promise<{{ subscribeMessage.uid() | pascalCase }}Message> { + return {{ channelName | camelCase }}Channel.request(requestMessage, this.nc); + } +{% endmacro %} diff --git a/.partials/index/subscribe.njk b/.partials/index/subscribe.njk new file mode 100644 index 000000000..52c5a44db --- /dev/null +++ b/.partials/index/subscribe.njk @@ -0,0 +1,10 @@ + +{% macro subscribe(channelName, message, messageDescription) %} + /** + * {{messageDescription}} + * @param onDataCallback Called when message recieved. + */ + public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsError, msg?: {{ message.uid() | pascalCase }}Message) => void): Promise { + return {{ channelName | camelCase }}Channel.subscribe(onDataCallback, this.nc); + } +{% endmacro %} diff --git a/README.md b/README.md index 2a1f5f1d6..54c11a905 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,8 @@ -# ts-nats-template -Typescript template for NATS +# {{ asyncapi.info().title() }} + +{{ asyncapi.info().description() | safe }} + + + +Available nats encodings: +https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings diff --git a/__package.json.njk b/__package.json.njk new file mode 100644 index 000000000..b560b8c29 --- /dev/null +++ b/__package.json.njk @@ -0,0 +1,44 @@ +{ +{% set name = "NatsTSclient" %} +{% set version = "1.0.0" %} +{% set description = "" %} + {%- if asyncapi.info() | length %} + {%- if asyncapi.info().title() | length %} + {% set name = asyncapi.info().title() | kebabCase %} + {%- endif %} + {%- if asyncapi.info().description() | length %} + {% set description = asyncapi.info().description() | oneLine %} + {%- endif %} + {%- if asyncapi.info().version() | length %} + {% set username = asyncapi.info().version() %} + {%- endif %} + {%- endif %} + "name": "{{name}}", + "description": "{{description}}", + "version": "{{version}}", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "watch": "tsc --watch", + "build": "tsc", + "start": "node src/api/index.js", + "postinstall": "link-module-alias" + }, + "_moduleAliasIgnoreWarning": true, + "_moduleAliases": { + "#messages": "./src/messages", + "#schemas": "./src/schema", + "#channels": "./src/channels" + }, + "dependencies": { + "@types/uuid": "3.4.5", + "link-module-alias": "^1.2.0", + "msgpack-lite": "^0.1.26", + "ts-nats": "1.2.4", + "node-yaml-config": "0.0.5", + "typescript": "3.4.3", + "uuid": "3.3.3", + "winston": "3.2.1", + "winston-daily-rotate-file": "3.10.0" + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..ad3c488cb --- /dev/null +++ b/package-lock.json @@ -0,0 +1,49 @@ +{ + "name": "@asyncapi/nats-ts-template", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=" + }, + "filenamify": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.1.0.tgz", + "integrity": "sha512-KQV/uJDI9VQgN7sHH1Zbk6+42cD6mnQ2HONzkXUfPJ+K2FC8GZ1dpewbbHw0Sz8Tf5k3EVdHVayM4DoAwWlmtg==", + "requires": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, + "trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", + "requires": { + "escape-string-regexp": "^1.0.2" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 000000000..343f9327a --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "@asyncapi/nats-ts-template", + "version": "0.1.0", + "description": "Nats typescript template for the AsyncAPI generator.", + "keywords": [ + "asyncapi", + "generator", + "ts", + "nats", + "template" + ], + "author": "Jonas Lagoni (jonas-lt@live.dk)", + "license": "Apache-2.0", + "dependencies": { + "filenamify": "^4.1.0", + "lodash": "^4.17.15" + } +} diff --git a/src/channels/$$channel$$.ts.njk b/src/channels/$$channel$$.ts.njk new file mode 100644 index 000000000..e52e78632 --- /dev/null +++ b/src/channels/$$channel$$.ts.njk @@ -0,0 +1,32 @@ + +{%- from "../../.partials/channel/publish.njk" import publish %} +{%- from "../../.partials/channel/reply.njk" import reply %} +{%- from "../../.partials/channel/request.njk" import request %} +{%- from "../../.partials/channel/subscribe.njk" import subscribe %} +{%- if channel.hasPublish() %} +import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '../messages/{{ channel.publish().message(0).uid() | pascalCase}}' +{%- endif %} +{%- if channel.hasSubscribe() %} +import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '../messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' +{%- endif %} + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + +{%- if channel | isRequestReply %} + {%- if channel | isRequester %} + {{ request(channelName, channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} + {%- endif %} + {%- if channel | isReplier %} + {{ reply(channelName, channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server)) }} + {%- endif %} +{%- endif %} + +{%- if channel | isPubsub %} + {%- if channel.hasSubscribe() %} + {{ subscribe(channelName, channel.subscribe().message(0), asyncapi.server(params.server)) }} + {%- endif %} + {%- if channel.hasPublish() %} + {{ publish(channelName, channel.publish().message(0), asyncapi.server(params.server)) }} + {%- endif %} +{%- endif %} diff --git a/src/index.ts.njk b/src/index.ts.njk new file mode 100644 index 000000000..f4b65d75f --- /dev/null +++ b/src/index.ts.njk @@ -0,0 +1,75 @@ + +{%- from "../.partials/index/publish.njk" import publish %} +{%- from "../.partials/index/reply.njk" import reply %} +{%- from "../.partials/index/request.njk" import request %} +{%- from "../.partials/index/subscribe.njk" import subscribe %} + +import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; + +{%- for channelName, channel in asyncapi.channels() %} +import * as {{ channelName | camelCase }}Channel from "./channels/{{ channelName | firstUpperCase }}"; +{%- endfor %} + +{%- for messageName, message in asyncapi.allMessages() %} +import {default as {{ messageName | pascalCase }}Message} from "./messages/{{ messageName | pascalCase }}"; +{%- endfor %} + +export default class NatsAsyncApiClient { + public jsonClient?: Client; + public stringClient?: Client; + public binaryClient?: Client; + public options: NatsConnectionOptions; + constructor(options : NatsConnectionOptions) { + options = this.setDefaultOptions(options); + this.options = options; + this.connect(options); + } + + /** + * Try to connect to the NATS server. + * @param options The connection options for NATS + */ + private async connect(options : NatsConnectionOptions){ + try{ + {%- if asyncapi | containsJsonPayload %} + + {%- endif %} + this.nc = await connect(options); + }catch(e){ + console.error("Could not connect to NATS: " + e) + } + } + + /** + * Set the default options based on the AsyncAPI file. + * @param options to set + */ + private setDefaultOptions(options: NatsConnectionOptions){ + //If server binding options sat set the options + options.encoding = 'utf8'; + options.payload = Payload.BINARY; + return options; + } + + {%- for channelName, channel in asyncapi.channels() %} + + {%- if channel | isRequestReply %} + {%- if channel | isRequester %} + {{request(channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description())}} + {%- endif %} + {%- if channel | isReplier %} + {{reply(channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description())}} + {%- endif %} + {%- endif %} + + {%- if channel | isPubsub %} + {%- if channel.hasSubscribe() %} + {{subscribe(channelName, channel.subscribe().message(0), channel.description())}} + {%- endif %} + {%- if channel.hasPublish() %} + {{publish(channelName, channel.publish().message(0), channel.description())}} + {%- endif %} + {%- endif %} + + {%- endfor %} +} diff --git a/src/messages/$$message$$.ts.njk b/src/messages/$$message$$.ts.njk new file mode 100644 index 000000000..cd640f61b --- /dev/null +++ b/src/messages/$$message$$.ts.njk @@ -0,0 +1,79 @@ +{%- macro initProperties(schema, required=true) %} + {%- if schema.allOf() | length %} + {%- for allOfSchema in schema.allOf() %} + {{initProperties(allOfSchema)}} + {%- endfor %} + {%- elif schema.oneOf() | length %} + oneOf:{{schema.oneOf() | oneOfSchemaType}} + {%- elif schema.anyOf() | length %} + {%- for anyOfSchema in schema.anyOf() %} + {{initProperties(anyOfSchema, false)}} + {%- endfor %} + {%- elif schema.uid() | length %} + {{initProperty(schema.uid(), schema.uid())}} + {%- endif %} +{%- endmacro %} +{%- macro setConstructorProperties(schema) %} + {%- if schema.allOf() | length %} + {%- for allOfSchema in schema.allOf() %} + {{setConstructorProperties(allOfSchema)}} + {%- endfor %} + {%- elif schema.oneOf() | length %} + {{setProperty("oneOf")}} + {%- elif schema.anyOf() | length %} + {%- for anyOfSchema in schema.anyOf() %} + {{setConstructorProperties(anyOfSchema)}} + {%- endfor %} + {%- elif schema.uid() | length %} + {{setProperty(schema.uid())}} + {%- endif %} +{%- endmacro %} +{%- macro importSchemas(schema) %} + {%- if schema.allOf() | length %} + {%- for allOfSchema in schema.allOf() %} + {{importSchemas(allOfSchema)}} + {%- endfor %} + {%- elif schema.oneOf() | length %} + {{importSchema("OneOf")}} + {%- for oneOfSchema in schema.oneOf() %} + {{importSchemas(oneOfSchema)}} + {%- endfor %} + {%- elif schema.anyOf() | length %} + {%- for anyOfSchema in schema.anyOf() %} + {{importSchemas(anyOfSchema)}} + {%- endfor %} + {%- elif schema.uid() | length %} + {{importSchema(schema.uid())}} + {%- endif %} +{%- endmacro %} +{%- macro initProperty(propertyName, propertyType) %} + {{propertyName | camelCase}}:{{propertyType | pascalCase}}Schema; +{% endmacro %} + +{%- macro setProperty(propertyName) %} + this.{{propertyName | camelCase}} = {{propertyName | camelCase}}; +{% endmacro %} + +{%- macro importSchema(propertyName) %} +import { default as {{propertyName | pascalCase}}Schema } from '../schema/{{propertyName | pascalCase}}'; +{% endmacro %} +{{ importSchemas(message.payload()) }} + +export default class {{ message.name() | pascalCase}} { + {{ initProperties(message.payload()) }} + + constructor( + {{message.payload() | constructorParameters}} + ){ + {{setConstructorProperties(message.payload())}} + } + + /** + * Parses a JSON string to an object of {{ message.name() | pascalCase}} message class. + * @param json string to be parsed as {{ message.name() | pascalCase}}. + */ + public static toMessage(json: string): {{ message.name() | pascalCase }} { + return JSON.parse(json); + } + +} diff --git a/src/schema/$$everySchema$$.ts.njk b/src/schema/$$everySchema$$.ts.njk new file mode 100644 index 000000000..88dfb8053 --- /dev/null +++ b/src/schema/$$everySchema$$.ts.njk @@ -0,0 +1,32 @@ + +{% macro initProperties(schema, required=true) %} + {%- if schema.allOf() | length %} + {%- for allOfSchema in schema.allOf() %} + {{initProperties(allOfSchema)}} + {%- endfor %} + {%- endif %} + + {%- if schema.oneOf() | length %} + test:{{schema.oneOf() | oneOfSchemaType}} + {%- endif %} + + {%- if schema.anyOf() | length %} + {%- for oneOfSchema in schema.anyOf() %} + {{initProperties(oneOfSchema, false)}} + {%- endfor %} + {%- endif %} + + {%- if schema.properties() | length %} + {%- for propertyName, property in schema.properties() %} + {{ propertyName}}{% if not required or not property.required() %}?{% endif %}: {{ property.type() | toTsType }} + {%- endfor %} + {%- endif %} + +{% endmacro %} + + +export default class {{ schema.uid() | camelCase }} { + + {{ initProperties(schema) }} + +} diff --git a/src/test/testclient/index.ts.njk b/src/test/testclient/index.ts.njk new file mode 100644 index 000000000..c921b81c1 --- /dev/null +++ b/src/test/testclient/index.ts.njk @@ -0,0 +1,70 @@ + +{%- from "../../../.partials/index/publish.njk" import publish %} +{%- from "../../../.partials/index/reply.njk" import reply %} +{%- from "../../../.partials/index/request.njk" import request %} +{%- from "../../../.partials/index/subscribe.njk" import subscribe %} + +import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; + +{%- for channelName, channel in asyncapi.channels() %} +import * as {{ channelName | camelCase }}Channel from "./testchannels/{{ channelName | firstUpperCase }}"; +{%- endfor %} + +{%- for messageName, message in asyncapi.allMessages() %} +import {default as {{ messageName | pascalCase }}Message} from "../../messages/{{ messageName | pascalCase }}"; +{%- endfor %} + +export default class NatsAsyncApiClient { + public nc?: Client; + public options: NatsConnectionOptions; + constructor(options : NatsConnectionOptions) { + options = this.setDefaultOptions(options); + this.options = options; + this.connect(options); + } + + /** + * Try to connect to the NATS server. + * @param options The connection options for NATS + */ + private async connect(options : NatsConnectionOptions){ + try{ + this.nc = await connect(options); + }catch(e){ + console.error("Could not connect to NATS: " + e) + } + } + + /** + * Set the default options from the AsyncAPI file. + * @param options The options to set + */ + private setDefaultOptions(options: NatsConnectionOptions){ + //If server binding options sat set the options + options.encoding = 'utf8'; + options.payload = Payload.BINARY; + return options; + } + + {%- for channelName, channel in asyncapi.channels() %} + + {%- if channel | isRequestReply %} + {%- if channel | isRequester %} + {{reply(channelName, channel.publish().message(0), channel.subscribe().message(0), channel)}} + {%- endif %} + {%- if channel | isReplier %} + {{request(channelName, channel.subscribe().message(0), channel.publish().message(0), channel)}} + {%- endif %} + {%- endif %} + + {%- if channel | isPubsub %} + {%- if channel.hasSubscribe() %} + {{publish(channelName, channel.subscribe().message(0), channel)}} + {%- endif %} + {%- if channel.hasPublish() %} + {{subscribe(channelName, channel.publish().message(0), channel)}} + {%- endif %} + {%- endif %} + + {%- endfor %} +} diff --git a/src/test/testclient/testchannels/$$channel$$.ts.njk b/src/test/testclient/testchannels/$$channel$$.ts.njk new file mode 100644 index 000000000..58d9a5960 --- /dev/null +++ b/src/test/testclient/testchannels/$$channel$$.ts.njk @@ -0,0 +1,32 @@ + +{%- from "../../../../.partials/channel/publish.njk" import publish %} +{%- from "../../../../.partials/channel/reply.njk" import reply %} +{%- from "../../../../.partials/channel/request.njk" import request %} +{%- from "../../../../.partials/channel/subscribe.njk" import subscribe %} +{%- if channel.hasPublish() %} +import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '../../../messages/{{ channel.publish().message(0).uid() | pascalCase}}' +{%- endif %} +{%- if channel.hasSubscribe() %} +import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '../../../messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' +{%- endif %} + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + +{%- if channel | isRequestReply %} + {%- if channel | isRequester %} + {{ reply(channelName, channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} + {%- endif %} + {%- if channel | isReplier %} + {{ request(channelName, channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server)) }} + {%- endif %} +{%- endif %} + +{%- if channel | isPubsub %} + {%- if channel.hasSubscribe() %} + {{ publish(channelName, channel.subscribe().message(0), asyncapi.server(params.server)) }} + {%- endif %} + {%- if channel.hasPublish() %} + {{ subscribe(channelName, channel.publish().message(0), asyncapi.server(params.server)) }} + {%- endif %} +{%- endif %} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..7355e5a16 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "declaration": true, + "strict": true, + "noImplicitAny": true, + "removeComments": true, + "preserveConstEnums": true, + "sourceMap": true, + "outDir": "dist/" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "**/*.spec.ts"] +} From 45a885f9982406b5d2ea10e00c0ac8cef098ceef Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sat, 28 Mar 2020 15:02:03 +0100 Subject: [PATCH 002/110] Removed unintended package-lock.json --- package-lock.json | 49 ----------------------------------------------- 1 file changed, 49 deletions(-) delete mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index ad3c488cb..000000000 --- a/package-lock.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@asyncapi/nats-ts-template", - "version": "0.1.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=" - }, - "filenamify": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.1.0.tgz", - "integrity": "sha512-KQV/uJDI9VQgN7sHH1Zbk6+42cD6mnQ2HONzkXUfPJ+K2FC8GZ1dpewbbHw0Sz8Tf5k3EVdHVayM4DoAwWlmtg==", - "requires": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.1", - "trim-repeated": "^1.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "requires": { - "escape-string-regexp": "^1.0.2" - } - }, - "trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", - "requires": { - "escape-string-regexp": "^1.0.2" - } - } - } -} From e164ec90d1c0eef84f19e42e67b255c1a77f7367 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sat, 28 Mar 2020 18:49:43 +0100 Subject: [PATCH 003/110] Changed name of npm package to "ts-nats-template" --- package.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 343f9327a..1ee8fb7fd 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,18 @@ { - "name": "@asyncapi/nats-ts-template", - "version": "0.1.0", - "description": "Nats typescript template for the AsyncAPI generator.", - "keywords": [ - "asyncapi", - "generator", - "ts", - "nats", - "template" - ], - "author": "Jonas Lagoni (jonas-lt@live.dk)", - "license": "Apache-2.0", - "dependencies": { - "filenamify": "^4.1.0", - "lodash": "^4.17.15" - } + "name": "@asyncapi/ts-nats-template", + "version": "0.1.0", + "description": "Nats typescript template for the AsyncAPI generator.", + "keywords": [ + "asyncapi", + "generator", + "ts", + "nats", + "template" + ], + "author": "Jonas Lagoni (jonas-lt@live.dk)", + "license": "Apache-2.0", + "dependencies": { + "filenamify": "^4.1.0", + "lodash": "^4.17.15" + } } From cd9b8ac0c0e630ac8fb362c64153ac60220b2626 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sat, 28 Mar 2020 18:58:27 +0100 Subject: [PATCH 004/110] Added .gitignore for node_modules --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..b512c09d4 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file From a25d71a9375d9b282a14814cde29dcd77f84b008 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sat, 28 Mar 2020 18:58:47 +0100 Subject: [PATCH 005/110] Added missing dependency for all filter --- .filters/all.js | 324 +++++++++++++++++++++++++----------------------- 1 file changed, 170 insertions(+), 154 deletions(-) diff --git a/.filters/all.js b/.filters/all.js index 13ff56e4f..28e4cd8ee 100644 --- a/.filters/all.js +++ b/.filters/all.js @@ -1,157 +1,173 @@ const URL = require('url'); const path = require('path'); - -module.exports = ({ Nunjucks, _ }) => { - Nunjucks.addFilter('kebabCase', string => { - return _.kebabCase(string); - }); - - Nunjucks.addFilter('camelCase', string => { - return camelCase(string); - }); - function camelCase(string) { - return _.camelCase(string); - } - - Nunjucks.addFilter('firstLowerCase', string => { - return _.lowerFirst(string); - }); - - Nunjucks.addFilter('firstUpperCase', string => { - return string.charAt(0).toUpperCase() + string.slice(1); - }); - - - - Nunjucks.addFilter('pascalCase', string => { - return pascalCase(string); - }); - function pascalCase(string) { - string = _.camelCase(string); - return string.charAt(0).toUpperCase() + string.slice(1); - } - - Nunjucks.addFilter('toTsType', jsonSchemaType => { - switch (jsonSchemaType.toLowerCase()) { - case 'string': - return 'String'; - case 'integer': - case 'number': - return 'Number'; - case 'boolean': - return 'Boolean'; - } - }); - - Nunjucks.addFilter('constructorParameters', schema => { - let returnString = ''; - if (schema.allOf()) { - schema.allOf().forEach(element => { - returnString += `${camelCase(element.uid())}: ${pascalCase(element.uid())}Schema,`; - }); - } else if (schema.oneOf()) { - returnString += `oneOf: ${getTypeFromOneOf(schema.oneOf())},`; - } else if (schema.anyOf()) { - schema.anyOf().forEach(element => { - returnString += `${camelCase(element.uid())}: ${pascalCase(element.uid())}Schema,`; - }); - } else if (schema.uid()) { - returnString += `${camelCase(schema.uid())}: ${pascalCase(schema.uid())}Schema,`; - } - if (returnString.length > 1) { - returnString = returnString.slice(0, -1); - } - return returnString; - }); - - Nunjucks.addFilter('schemaConstructor', properties => { - let returnString = ''; - for (const [key, value] of Object.entries(properties)) { - returnString += `${key},`; - } - if (returnString.length > 1) { - returnString = returnString.slice(0, -1); - } - return returnString; - }); - - Nunjucks.addFilter('oneLine', string => { - if (!string) return string; - return string.replace(/\n/g, ' '); - }); - - function getTypeFromOneOf(oneFromSchema) { - let type = ''; - - if (oneFromSchema.oneOf().length > 0) { - type += `${getTypeFromOneOf(oneFromSchema.oneOf())}Schema`; - } - - for (var i = 0; i < oneOfSchema.length; i++) { - let schema = oneOfSchema[i]; - if (type !== '') { - type += '|'; - } - if (oneOfSchema.length == i + 1) { - type += schema.uid() - } else { - type += schema.uid() + '|' - } - } - return type; - } - Nunjucks.addFilter('oneOfSchemaType', getTypeFromOneOf); - - Nunjucks.addFilter('fileName', string => { - return _.camelCase(string); - }); - - - Nunjucks.addFilter('tsPayload', (server) => { - return "STRING"; - }); - - Nunjucks.addFilter('tsEncoding', (server) => { - return "STRING"; - }); - - - Nunjucks.addFilter('isPubsub', channel => { - let tempChannel = channel._json; - if (tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'pubsub') { - return true; - } - return false; - }); - - Nunjucks.addFilter('hasNatsBindings', obj => { - if (obj.bindings.nats) { - return true; - } - return false; - }); - - Nunjucks.addFilter('isRequestReply', channel => { - let tempChannel = channel._json; - if (tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'requestReply') { - return true; - } - return false; - }); - - Nunjucks.addFilter('isRequester', channel => { - let tempChannel = channel._json; - if (tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'requestReply' && tempChannel.bindings.nats.requestReply && tempChannel.bindings.nats.requestReply.is == 'requester') { - return true; - } - return false; - }); - - Nunjucks.addFilter('isReplier', channel => { - let tempChannel = channel._json; - if (tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'requestReply' && tempChannel.bindings.nats.requestReply && tempChannel.bindings.nats.requestReply.is == 'replier') { - return true; - } - return false; - }); +const _ = require('lodash'); + +module.exports = ({ Nunjucks }) => { + Nunjucks.addFilter('kebabCase', string => { + return _.kebabCase(string); + }); + + Nunjucks.addFilter('camelCase', string => { + return camelCase(string); + }); + function camelCase(string) { + return _.camelCase(string); + } + + Nunjucks.addFilter('firstLowerCase', string => { + return _.lowerFirst(string); + }); + + Nunjucks.addFilter('firstUpperCase', string => { + return string.charAt(0).toUpperCase() + string.slice(1); + }); + + Nunjucks.addFilter('pascalCase', string => { + return pascalCase(string); + }); + function pascalCase(string) { + string = _.camelCase(string); + return string.charAt(0).toUpperCase() + string.slice(1); + } + + Nunjucks.addFilter('toTsType', jsonSchemaType => { + switch (jsonSchemaType.toLowerCase()) { + case 'string': + return 'String'; + case 'integer': + case 'number': + return 'Number'; + case 'boolean': + return 'Boolean'; + } + }); + + Nunjucks.addFilter('constructorParameters', schema => { + let returnString = ''; + if (schema.allOf()) { + schema.allOf().forEach(element => { + returnString += `${camelCase(element.uid())}: ${pascalCase( + element.uid() + )}Schema,`; + }); + } else if (schema.oneOf()) { + returnString += `oneOf: ${getTypeFromOneOf(schema.oneOf())},`; + } else if (schema.anyOf()) { + schema.anyOf().forEach(element => { + returnString += `${camelCase(element.uid())}: ${pascalCase( + element.uid() + )}Schema,`; + }); + } else if (schema.uid()) { + returnString += `${camelCase(schema.uid())}: ${pascalCase( + schema.uid() + )}Schema,`; + } + if (returnString.length > 1) { + returnString = returnString.slice(0, -1); + } + return returnString; + }); + + Nunjucks.addFilter('schemaConstructor', properties => { + let returnString = ''; + for (const [key, value] of Object.entries(properties)) { + returnString += `${key},`; + } + if (returnString.length > 1) { + returnString = returnString.slice(0, -1); + } + return returnString; + }); + + Nunjucks.addFilter('oneLine', string => { + if (!string) return string; + return string.replace(/\n/g, ' '); + }); + + function getTypeFromOneOf(oneFromSchema) { + let type = ''; + + if (oneFromSchema.oneOf().length > 0) { + type += `${getTypeFromOneOf(oneFromSchema.oneOf())}Schema`; + } + + for (var i = 0; i < oneOfSchema.length; i++) { + let schema = oneOfSchema[i]; + if (type !== '') { + type += '|'; + } + if (oneOfSchema.length == i + 1) { + type += schema.uid(); + } else { + type += schema.uid() + '|'; + } + } + return type; + } + Nunjucks.addFilter('oneOfSchemaType', getTypeFromOneOf); + + Nunjucks.addFilter('fileName', string => { + return _.camelCase(string); + }); + + Nunjucks.addFilter('tsPayload', server => { + return 'STRING'; + }); + + Nunjucks.addFilter('tsEncoding', server => { + return 'STRING'; + }); + + Nunjucks.addFilter('isPubsub', channel => { + let tempChannel = channel._json; + if (tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'pubsub') { + return true; + } + return false; + }); + + Nunjucks.addFilter('hasNatsBindings', obj => { + if (obj.bindings.nats) { + return true; + } + return false; + }); + + Nunjucks.addFilter('isRequestReply', channel => { + let tempChannel = channel._json; + if ( + tempChannel.bindings.nats && + tempChannel.bindings.nats.is == 'requestReply' + ) { + return true; + } + return false; + }); + + Nunjucks.addFilter('isRequester', channel => { + let tempChannel = channel._json; + if ( + tempChannel.bindings.nats && + tempChannel.bindings.nats.is == 'requestReply' && + tempChannel.bindings.nats.requestReply && + tempChannel.bindings.nats.requestReply.is == 'requester' + ) { + return true; + } + return false; + }); + + Nunjucks.addFilter('isReplier', channel => { + let tempChannel = channel._json; + if ( + tempChannel.bindings.nats && + tempChannel.bindings.nats.is == 'requestReply' && + tempChannel.bindings.nats.requestReply && + tempChannel.bindings.nats.requestReply.is == 'replier' + ) { + return true; + } + return false; + }); }; From bb6da67a774666ec39618e3c89cb2db8f8f156c5 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sat, 28 Mar 2020 20:04:10 +0100 Subject: [PATCH 006/110] Changed rename hooks to exclude node_modules because when template is installed by links. --- .filters/all.js | 5 +++++ .hooks/rename-njk.js | 38 +++++++++++++++++++++----------------- src/index.ts.njk | 12 ++++++++---- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/.filters/all.js b/.filters/all.js index 28e4cd8ee..bdbe57fda 100644 --- a/.filters/all.js +++ b/.filters/all.js @@ -10,6 +10,11 @@ module.exports = ({ Nunjucks }) => { Nunjucks.addFilter('camelCase', string => { return camelCase(string); }); + + Nunjucks.addFilter('containsJsonPayload', server => { + return true; + }); + function camelCase(string) { return _.camelCase(string); } diff --git a/.hooks/rename-njk.js b/.hooks/rename-njk.js index 7b313ce6f..d0fe71780 100644 --- a/.hooks/rename-njk.js +++ b/.hooks/rename-njk.js @@ -1,22 +1,26 @@ const fs = require('fs'); const path = require('path'); -var renameAllSync = function (dir) { - files = fs.readdirSync(dir); - files.forEach(function (file) { - let filepath = path.resolve(dir, file); - if (fs.statSync(filepath).isDirectory()) { - renameAllSync(filepath); - } else if (path.extname(filepath) === '.njk') { - let baseName = path.basename(filepath, '.ts.njk'); - let newName = - baseName.charAt(0).toUpperCase() + baseName.slice(1) + '.ts'; - let newPath = path.resolve(dir, newName); - fs.renameSync(filepath, newPath); - } - }); +var renameAllSync = function(dir) { + files = fs.readdirSync(dir); + files.forEach(function(file) { + let filepath = path.resolve(dir, file); + if (fs.statSync(filepath).isDirectory()) { + renameAllSync(filepath); + } else if ( + path.extname(filepath) === '.njk' && + !dir.includes('node_modules') + ) { + let baseName = path.basename(filepath, '.ts.njk'); + let newName = + baseName.charAt(0).toUpperCase() + baseName.slice(1) + '.ts'; + let newPath = path.resolve(dir, newName); + console.log(newPath); + fs.renameSync(filepath, newPath); + } + }); }; module.exports = register => { - register('generate:after', generator => { - renameAllSync(path.resolve(generator.targetDir)); - }); + register('generate:after', generator => { + renameAllSync(path.resolve(generator.targetDir)); + }); }; diff --git a/src/index.ts.njk b/src/index.ts.njk index f4b65d75f..ead90c3c1 100644 --- a/src/index.ts.njk +++ b/src/index.ts.njk @@ -22,14 +22,13 @@ export default class NatsAsyncApiClient { constructor(options : NatsConnectionOptions) { options = this.setDefaultOptions(options); this.options = options; - this.connect(options); + this.connect(); } /** - * Try to connect to the NATS server. - * @param options The connection options for NATS + * Try to connect to the NATS server with the different payloads. */ - private async connect(options : NatsConnectionOptions){ + private async connect(){ try{ {%- if asyncapi | containsJsonPayload %} @@ -40,6 +39,11 @@ export default class NatsAsyncApiClient { } } + private async connectJsonPayload(){ + + return connect(options); + } + /** * Set the default options based on the AsyncAPI file. * @param options to set From f43787a3d63e05f5d588e8416f1e150cc97c4119 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sat, 28 Mar 2020 20:14:09 +0100 Subject: [PATCH 007/110] Ensured rename-njk hook renames all .njk files. --- .hooks/rename-njk.js | 4 +--- src/index.ts.njk | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.hooks/rename-njk.js b/.hooks/rename-njk.js index d0fe71780..91e4f3782 100644 --- a/.hooks/rename-njk.js +++ b/.hooks/rename-njk.js @@ -10,9 +10,7 @@ var renameAllSync = function(dir) { path.extname(filepath) === '.njk' && !dir.includes('node_modules') ) { - let baseName = path.basename(filepath, '.ts.njk'); - let newName = - baseName.charAt(0).toUpperCase() + baseName.slice(1) + '.ts'; + let newName = path.basename(filepath, '.njk'); let newPath = path.resolve(dir, newName); console.log(newPath); fs.renameSync(filepath, newPath); diff --git a/src/index.ts.njk b/src/index.ts.njk index ead90c3c1..2bcc810f8 100644 --- a/src/index.ts.njk +++ b/src/index.ts.njk @@ -19,6 +19,11 @@ export default class NatsAsyncApiClient { public stringClient?: Client; public binaryClient?: Client; public options: NatsConnectionOptions; + + /** + * + * @param options options to use, payload is omitted if sat in the AsyncAPI document. + */ constructor(options : NatsConnectionOptions) { options = this.setDefaultOptions(options); this.options = options; @@ -30,20 +35,20 @@ export default class NatsAsyncApiClient { */ private async connect(){ try{ - {%- if asyncapi | containsJsonPayload %} + this.options.payload = Payload.BINARY; + this.binaryClient = await connect(this.options); + this.options.payload = Payload.STRING; + this.stringClient = await connect(this.options); + {%- if asyncapi | containsJsonPayload %} + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); {%- endif %} - this.nc = await connect(options); }catch(e){ console.error("Could not connect to NATS: " + e) } } - private async connectJsonPayload(){ - - return connect(options); - } - /** * Set the default options based on the AsyncAPI file. * @param options to set @@ -51,7 +56,6 @@ export default class NatsAsyncApiClient { private setDefaultOptions(options: NatsConnectionOptions){ //If server binding options sat set the options options.encoding = 'utf8'; - options.payload = Payload.BINARY; return options; } From 06aeb7eab9ac77f3d91b3aa81d66de815a57b4f8 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sat, 28 Mar 2020 22:24:59 +0100 Subject: [PATCH 008/110] Added check for which client to use based on message and default content type for all the client methods. --- .partials/index/publish.njk | 13 +++++++++++-- .partials/index/reply.njk | 13 +++++++++++-- .partials/index/request.njk | 13 +++++++++++-- .partials/index/subscribe.njk | 13 +++++++++++-- src/index.ts.njk | 16 +++++++++------- src/test/testclient/index.ts.njk | 8 ++++---- 6 files changed, 57 insertions(+), 19 deletions(-) diff --git a/.partials/index/publish.njk b/.partials/index/publish.njk index e99b7d24e..c5893bcee 100644 --- a/.partials/index/publish.njk +++ b/.partials/index/publish.njk @@ -1,10 +1,19 @@ -{% macro publish(channelName, message, messageDescription) %} +{% macro publish(defaultContentType, channelName, message, messageDescription) %} /** * {{messageDescription}} * @param requestMessage The message to publish. */ public publishTo{{channelName | pascalCase }}(requestMessage: {{ message.uid() | pascalCase }}Message): Promise { - return {{ channelName | camelCase }}Channel.publish(requestMessage, this.nc); + {%- if message | isBinaryPayload(defaultContentType) %} + Client nc = this.binaryClient; + {%- endif %} + {%- if message | isStringPayload(defaultContentType) %} + Client nc = this.stringClient; + {%- endif %} + {%- if message | isJsonPayload(defaultContentType) %} + Client nc = this.jsonClient; + {%- endif %} + return {{ channelName | camelCase }}Channel.publish(requestMessage, nc); } {% endmacro %} diff --git a/.partials/index/reply.njk b/.partials/index/reply.njk index 7f325226f..68fe7dfee 100644 --- a/.partials/index/reply.njk +++ b/.partials/index/reply.njk @@ -1,11 +1,20 @@ -{% macro reply(channelName, subscribeMessage, publishMessage, messageDescription) %} +{% macro reply(defaultContentType, channelName, subscribeMessage, publishMessage, messageDescription) %} /** * {{messageDescription}} * @param onRequest Called when request recieved. * @param onReplyError Called when it was not possible to send the reply. */ public replyTo{{channelName | pascalCase }}(onRequest : (err?: NatsError, msg?: {{ subscribeMessage.uid() | pascalCase }}Message) => {{ publishMessage.uid() | pascalCase }}Message, onReplyError : (err: NatsError) => void): Promise { - return {{ channelName | camelCase }}Channel.reply(onRequest, onReplyError, this.nc); + {%- if message | isBinaryPayload(defaultContentType) %} + Client nc = this.binaryClient; + {%- endif %} + {%- if message | isStringPayload(defaultContentType) %} + Client nc = this.stringClient; + {%- endif %} + {%- if message | isJsonPayload(defaultContentType) %} + Client nc = this.jsonClient; + {%- endif %} + return {{ channelName | camelCase }}Channel.reply(onRequest, onReplyError, nc); } {% endmacro %} diff --git a/.partials/index/request.njk b/.partials/index/request.njk index 270f6399f..728d08315 100644 --- a/.partials/index/request.njk +++ b/.partials/index/request.njk @@ -1,10 +1,19 @@ -{% macro request(channelName, publishMessage, subscribeMessage, messageDescription) %} +{% macro request(defaultContentType, channelName, publishMessage, subscribeMessage, messageDescription) %} /** * {{messageDescription}} * @param requestMessage The request message to send. */ public request{{channelName | pascalCase }}(requestMessage: {{ publishMessage.uid() | pascalCase }}Message): Promise<{{ subscribeMessage.uid() | pascalCase }}Message> { - return {{ channelName | camelCase }}Channel.request(requestMessage, this.nc); + {%- if message | isBinaryPayload(defaultContentType) %} + Client nc = this.binaryClient; + {%- endif %} + {%- if message | isStringPayload(defaultContentType) %} + Client nc = this.stringClient; + {%- endif %} + {%- if message | isJsonPayload(defaultContentType) %} + Client nc = this.jsonClient; + {%- endif %} + return {{ channelName | camelCase }}Channel.request(requestMessage, nc); } {% endmacro %} diff --git a/.partials/index/subscribe.njk b/.partials/index/subscribe.njk index 52c5a44db..1b3ab6ace 100644 --- a/.partials/index/subscribe.njk +++ b/.partials/index/subscribe.njk @@ -1,10 +1,19 @@ -{% macro subscribe(channelName, message, messageDescription) %} +{% macro subscribe(defaultContentType, channelName, message, messageDescription) %} /** * {{messageDescription}} * @param onDataCallback Called when message recieved. */ public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsError, msg?: {{ message.uid() | pascalCase }}Message) => void): Promise { - return {{ channelName | camelCase }}Channel.subscribe(onDataCallback, this.nc); + {%- if message | isBinaryPayload(defaultContentType) %} + Client nc = this.binaryClient; + {%- endif %} + {%- if message | isStringPayload(defaultContentType) %} + Client nc = this.stringClient; + {%- endif %} + {%- if message | isJsonPayload(defaultContentType) %} + Client nc = this.jsonClient; + {%- endif %} + return {{ channelName | camelCase }}Channel.subscribe(onDataCallback, nc); } {% endmacro %} diff --git a/src/index.ts.njk b/src/index.ts.njk index 2bcc810f8..9131f8ce8 100644 --- a/src/index.ts.njk +++ b/src/index.ts.njk @@ -25,8 +25,7 @@ export default class NatsAsyncApiClient { * @param options options to use, payload is omitted if sat in the AsyncAPI document. */ constructor(options : NatsConnectionOptions) { - options = this.setDefaultOptions(options); - this.options = options; + this.options = this.setDefaultOptions(options); this.connect(); } @@ -35,11 +34,14 @@ export default class NatsAsyncApiClient { */ private async connect(){ try{ - + {%- if asyncapi | containsBinaryPayload %} this.options.payload = Payload.BINARY; this.binaryClient = await connect(this.options); + {%- endif %} + {%- if asyncapi | containsStringPayload %} this.options.payload = Payload.STRING; this.stringClient = await connect(this.options); + {%- endif %} {%- if asyncapi | containsJsonPayload %} this.options.payload = Payload.JSON; this.jsonClient = await connect(this.options); @@ -63,19 +65,19 @@ export default class NatsAsyncApiClient { {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{request(channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description())}} + {{request(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description())}} {%- endif %} {%- if channel | isReplier %} - {{reply(channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description())}} + {{reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description())}} {%- endif %} {%- endif %} {%- if channel | isPubsub %} {%- if channel.hasSubscribe() %} - {{subscribe(channelName, channel.subscribe().message(0), channel.description())}} + {{subscribe(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.description())}} {%- endif %} {%- if channel.hasPublish() %} - {{publish(channelName, channel.publish().message(0), channel.description())}} + {{publish(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.description())}} {%- endif %} {%- endif %} diff --git a/src/test/testclient/index.ts.njk b/src/test/testclient/index.ts.njk index c921b81c1..f8b0545a4 100644 --- a/src/test/testclient/index.ts.njk +++ b/src/test/testclient/index.ts.njk @@ -50,19 +50,19 @@ export default class NatsAsyncApiClient { {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{reply(channelName, channel.publish().message(0), channel.subscribe().message(0), channel)}} + {{reply(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel)}} {%- endif %} {%- if channel | isReplier %} - {{request(channelName, channel.subscribe().message(0), channel.publish().message(0), channel)}} + {{request(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel)}} {%- endif %} {%- endif %} {%- if channel | isPubsub %} {%- if channel.hasSubscribe() %} - {{publish(channelName, channel.subscribe().message(0), channel)}} + {{publish(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel)}} {%- endif %} {%- if channel.hasPublish() %} - {{subscribe(channelName, channel.publish().message(0), channel)}} + {{subscribe(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel)}} {%- endif %} {%- endif %} From bcd4061f6ecadd1f14fc4dd51b2e841e8f7ff936 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 30 Mar 2020 15:08:13 +0200 Subject: [PATCH 009/110] Added separated README.md file for the template and the generated client. --- .hooks/rename-readme.js | 11 +++++++++++ README.md | 11 +++++------ __README.md | 8 ++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 .hooks/rename-readme.js create mode 100644 __README.md diff --git a/.hooks/rename-readme.js b/.hooks/rename-readme.js new file mode 100644 index 000000000..8e9023ebe --- /dev/null +++ b/.hooks/rename-readme.js @@ -0,0 +1,11 @@ +const fs = require('fs'); +const path = require('path'); + +module.exports = register => { + register('generate:after', generator => { + fs.renameSync( + path.resolve(generator.targetDir, './__README.md'), + path.resolve(generator.targetDir, './README.md') + ); + }); +}; diff --git a/README.md b/README.md index 54c11a905..5530c31e7 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ -# {{ asyncapi.info().title() }} +# Template usage -{{ asyncapi.info().description() | safe }} +## content types - - -Available nats encodings: -https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings +For binary payloads use: `binary` content type +For json payloads use: `json` content type +For string payloads use: `string` content type diff --git a/__README.md b/__README.md new file mode 100644 index 000000000..54c11a905 --- /dev/null +++ b/__README.md @@ -0,0 +1,8 @@ +# {{ asyncapi.info().title() }} + +{{ asyncapi.info().description() | safe }} + + + +Available nats encodings: +https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings From 09fc722baa1f59cfe2b11dd96b165c579be6a933 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 30 Mar 2020 15:09:02 +0200 Subject: [PATCH 010/110] Added new generator hook to rename package file --- .hooks/rename-packagefile.js | 11 +++++++++++ __package.json.njk | 8 +++++--- 2 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 .hooks/rename-packagefile.js diff --git a/.hooks/rename-packagefile.js b/.hooks/rename-packagefile.js new file mode 100644 index 000000000..e2e300488 --- /dev/null +++ b/.hooks/rename-packagefile.js @@ -0,0 +1,11 @@ +const fs = require('fs'); +const path = require('path'); + +module.exports = register => { + register('generate:after', generator => { + fs.renameSync( + path.resolve(generator.targetDir, './__package.json'), + path.resolve(generator.targetDir, './package.json') + ); + }); +}; diff --git a/__package.json.njk b/__package.json.njk index b560b8c29..5c9a02e0b 100644 --- a/__package.json.njk +++ b/__package.json.njk @@ -1,7 +1,7 @@ { -{% set name = "NatsTSclient" %} -{% set version = "1.0.0" %} -{% set description = "" %} +{%- set name = "NatsTSclient" %} +{%- set version = "1.0.0" %} +{%- set description = "" %} {%- if asyncapi.info() | length %} {%- if asyncapi.info().title() | length %} {% set name = asyncapi.info().title() | kebabCase %} @@ -31,7 +31,9 @@ "#channels": "./src/channels" }, "dependencies": { + "@types/klaw-sync": "^6.0.0", "@types/uuid": "3.4.5", + "klaw-sync": "6.0.0", "link-module-alias": "^1.2.0", "msgpack-lite": "^0.1.26", "ts-nats": "1.2.4", From a5db1827970bdfea52a368d254b189eff1d0882d Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 30 Mar 2020 15:26:11 +0200 Subject: [PATCH 011/110] feat: implemented hooks to control the flow of information outside of the generated code. fix: Ensured the right client is used for the right channels. fix: The channelname is not realized based on paramters and converted to NATS channel. --- .filters/all.js | 111 +++++++++++++++++- .partials/channel/publish.njk | 24 +++- .partials/channel/reply.njk | 17 ++- .partials/channel/request.njk | 22 +++- .partials/channel/subscribe.njk | 17 ++- .partials/index/publish.njk | 12 +- .partials/index/reply.njk | 12 +- .partials/index/request.njk | 12 +- .partials/index/subscribe.njk | 12 +- README.md | 10 ++ __package.json.njk | 4 +- package-lock.json | 49 ++++++++ src/channels/$$channel$$.ts.njk | 13 +- src/channels/utils.ts | 11 ++ src/hooks.ts | 64 ++++++++++ src/index.ts.njk | 4 +- .../testchannels/$$channel$$.ts.njk | 8 +- tsconfig.json | 9 +- 18 files changed, 352 insertions(+), 59 deletions(-) create mode 100644 package-lock.json create mode 100644 src/channels/utils.ts create mode 100644 src/hooks.ts diff --git a/.filters/all.js b/.filters/all.js index bdbe57fda..2b08f9ff8 100644 --- a/.filters/all.js +++ b/.filters/all.js @@ -11,8 +11,92 @@ module.exports = ({ Nunjucks }) => { return camelCase(string); }); - Nunjucks.addFilter('containsJsonPayload', server => { - return true; + /** + * Figure out if our message content type or default content type matches a given payload. + * @param {*} messageContentType to check + * @param {*} defaultContentType to check + * @param {*} payload to find + */ + function containsPayload(messageContentType, defaultContentType, payload) { + if ( + (messageContentType != null && + messageContentType.toLowerCase() == payload) || + (defaultContentType != null && defaultContentType == payload) + ) { + return true; + } + return false; + } + Nunjucks.addFilter( + 'isBinaryPayload', + (messageContentType, defaultContentType) => { + return containsPayload(messageContentType, defaultContentType, 'binary'); + } + ); + Nunjucks.addFilter( + 'isStringPayload', + (messageContentType, defaultContentType) => { + return containsPayload(messageContentType, defaultContentType, 'string'); + } + ); + Nunjucks.addFilter( + 'isJsonPayload', + (messageContentType, defaultContentType) => { + return containsPayload(messageContentType, defaultContentType, 'json'); + } + ); + + /** + * Figure out if a payload is located in the document. + * @param {*} document to look through + * @param {*} payload to find + */ + function containsPayloadInDocument(document, payload) { + if ( + document.defaultContentType() != null && + document.defaultContentType().toLowerCase() == payload + ) { + return true; + } + if (document.channels() != null) { + for (let channelName in document.channels()) { + let channel = document.channels()[channelName]; + if ( + (channel.hasPublish() && + channel + .publish() + .message() + .contentType() != null && + channel + .publish() + .message() + .contentType() + .toLowerCase() == payload) || + (channel.hasSubscribe() && + channel + .subscribe() + .message() + .contentType() != null && + channel + .subscribe() + .message() + .contentType() + .toLowerCase() == payload) + ) { + return true; + } + } + } + return false; + } + Nunjucks.addFilter('containsBinaryPayload', document => { + return containsPayloadInDocument(document, 'binary'); + }); + Nunjucks.addFilter('containsStringPayload', document => { + return containsPayloadInDocument(document, 'string'); + }); + Nunjucks.addFilter('containsJsonPayload', document => { + return containsPayloadInDocument(document, 'json'); }); function camelCase(string) { @@ -35,18 +119,32 @@ module.exports = ({ Nunjucks }) => { return string.charAt(0).toUpperCase() + string.slice(1); } - Nunjucks.addFilter('toTsType', jsonSchemaType => { + function toTsType(jsonSchemaType) { switch (jsonSchemaType.toLowerCase()) { case 'string': - return 'String'; + return 'string'; case 'integer': case 'number': return 'Number'; case 'boolean': return 'Boolean'; } - }); + } + Nunjucks.addFilter('toTsType', toTsType); + Nunjucks.addFilter('realizeParametersForChannel', parameters => { + let returnString = ''; + + for (paramName in parameters) { + returnString += `${paramName}:${toTsType( + parameters[paramName].schema().type() + )},`; + } + if (returnString.length >= 1) { + returnString = returnString.slice(0, -1); + } + return returnString; + }); Nunjucks.addFilter('constructorParameters', schema => { let returnString = ''; if (schema.allOf()) { @@ -85,6 +183,9 @@ module.exports = ({ Nunjucks }) => { return returnString; }); + Nunjucks.addFilter('print', string => { + console.log(string); + }); Nunjucks.addFilter('oneLine', string => { if (!string) return string; return string.replace(/\n/g, ' '); diff --git a/.partials/channel/publish.njk b/.partials/channel/publish.njk index 7e81ac914..9d3d8cfce 100644 --- a/.partials/channel/publish.njk +++ b/.partials/channel/publish.njk @@ -1,12 +1,26 @@ -{% macro publish(channelName, publishMessage, server) %} +{% macro publish(channelName, parameters, publishMessage, server) %} -export function publish(requestMessage: {{publishMessage.uid() | pascalCase}}Message, nc?: Client): Promise { - return new Promise(async (resolve, reject) => { +export function publish( + requestMessage: {{publishMessage.uid() | pascalCase}}Message, + {% if parameters | length %} + {{parameters | realizeParametersForChannel}} + {% endif %}{% if parameters | length %},{% endif %} + nc?: Client + ): Promise { + return new Promise(async (resolve, reject) => { if (nc) { try{ - let dataToPublish = utils.beforePublish(requestMessage, Payload.{{server | tsPayload}}, '{{server | tsEncoding}}'); - nc.publish('{{channelName}}', dataToPublish); + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var dataToPublish; + for(let hook in publishDataHooks){ + dataToPublish = hook(requestMessage); + } + nc.publish(realizeChannelName('{{channelName}}', { + {% for parameterName, parameter in parameters %} + "{{parameterName}}": {{parameterName}} + {% endfor %} + }), dataToPublish); resolve(); }catch(e){ reject(e); diff --git a/.partials/channel/reply.njk b/.partials/channel/reply.njk index 1238ee5f4..1e9a40410 100644 --- a/.partials/channel/reply.njk +++ b/.partials/channel/reply.njk @@ -1,6 +1,13 @@ -{% macro reply(channelName, subscribtionMessage, publishMessage, server) %} -export function reply(onRequest: (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message) => {{publishMessage.uid() | pascalCase}}Message, onReplyError: (err: NatsError) => void, nc?: Client): Promise { +{% macro reply(channelName, parameters, subscribtionMessage, publishMessage, server) %} +export function reply( + onRequest: (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message) => {{publishMessage.uid() | pascalCase}}Message, + onReplyError: (err: NatsError) => void, + {% if parameters | length %},{% endif %} + {% if parameters | length %} + {{parameters | realizeParametersForChannel}} + {% endif %}{% if parameters | length %},{% endif %} + nc?: Client): Promise { return new Promise(async (resolve, reject) => { if (nc) { try { @@ -17,7 +24,11 @@ export function reply(onRequest: (err?: NatsError, msg?: {{subscribtionMessage.u {%- endif %} {%- endif %} - let subscription = nc.subscribe('{{channelName}}', (err, msg) => { + let subscription = nc.subscribe(realizeChannelName('{{channelName}}', { + {% for parameterName, parameter in parameters %} + "{{parameterName}}": {{parameterName}} + {% endfor %} + }), (err, msg) => { if (err) { onRequest(err); } else { diff --git a/.partials/channel/request.njk b/.partials/channel/request.njk index a66f8a13d..eca0b276c 100644 --- a/.partials/channel/request.njk +++ b/.partials/channel/request.njk @@ -1,6 +1,11 @@ -{% macro request(channelName, publishMessage, subscribtionMessage, server) %} -export function request(requestMessage: {{publishMessage.uid() | pascalCase}}Message, nc?: Client): Promise<{{subscribtionMessage.uid() | pascalCase}}Message> { +{% macro request(channelName, parameters, publishMessage, subscribtionMessage, server) %} +export function request( + requestMessage: {{publishMessage.uid() | pascalCase}}Message, + {% if parameters | length %} + {{parameters | realizeParametersForChannel}} + {% endif %}{% if parameters | length %},{% endif %} + nc?: Client): Promise<{{subscribtionMessage.uid() | pascalCase}}Message> { return new Promise<{{subscribtionMessage.uid() | pascalCase}}Message>(async (resolve, reject) => { if (nc) { try { @@ -13,8 +18,17 @@ export function request(requestMessage: {{publishMessage.uid() | pascalCase}}Mes resolve({{subscribtionMessage.uid() | pascalCase}}Message.toMessage(processedData)); } }, { max: 1 }); - let requestData = utils.beforeRequest(requestMessage, Payload.{{server | tsPayload}}, '{{server | tsEncoding}}'); - nc.publish('{{channelName}}', requestData, inbox); + let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var requestData; + for(let hook in publishDataHooks){ + requestData = hook(requestMessage); + } + nc.publish(realizeChannelName('{{channelName}}', { + {% for parameterName, parameter in parameters %} + "{{parameterName}}": {{parameterName}} + {% endfor %} + }), requestData, inbox); }catch(e){ reject(e); } diff --git a/.partials/channel/subscribe.njk b/.partials/channel/subscribe.njk index 271b13891..4c43de417 100644 --- a/.partials/channel/subscribe.njk +++ b/.partials/channel/subscribe.njk @@ -1,6 +1,13 @@ -{% macro subscribe(channelName, subscribtionMessage, server) %} -export function subscribe(onDataCallback : (err?: NatsError, msg?: {{subscribtionMessage.uid() | camelCase}}) => void, nc?: Client): Promise { +{% macro subscribe(channelName, parameters, subscribtionMessage, server) %} + +import {getHooks, AvailableHooks} from '#hooks'; +export function subscribe( + onDataCallback : (err?: NatsError, msg?: {{subscribtionMessage.uid() | camelCase}}) => void, + {% if parameters | length %} + {{parameters | realizeParametersForChannel}} + {% endif %}{% if parameters | length %},{% endif %} + nc?: Client): Promise { return new Promise(async (resolve, reject) => { if (nc) { try{ @@ -16,7 +23,11 @@ export function subscribe(onDataCallback : (err?: NatsError, msg?: {{subscribtio {%- endif %} {%- endif %} - let subscription = nc.subscribe('{{channelName}}', (err, msg) => { + let subscription = nc.subscribe(realizeChannelName('{{channelName}}', { + {% for parameterName, parameter in parameters %} + "{{parameterName}}": {{parameterName}} + {% endfor %} + }), (err, msg) => { if(err){ onDataCallback(err); }else{ diff --git a/.partials/index/publish.njk b/.partials/index/publish.njk index c5893bcee..2edde59e9 100644 --- a/.partials/index/publish.njk +++ b/.partials/index/publish.njk @@ -5,14 +5,14 @@ * @param requestMessage The message to publish. */ public publishTo{{channelName | pascalCase }}(requestMessage: {{ message.uid() | pascalCase }}Message): Promise { - {%- if message | isBinaryPayload(defaultContentType) %} - Client nc = this.binaryClient; + {%- if message.contentType() | isBinaryPayload(defaultContentType) %} + const nc: Client = this.binaryClient!; {%- endif %} - {%- if message | isStringPayload(defaultContentType) %} - Client nc = this.stringClient; + {%- if message.contentType() | isStringPayload(defaultContentType) %} + const nc: Client = this.stringClient!; {%- endif %} - {%- if message | isJsonPayload(defaultContentType) %} - Client nc = this.jsonClient; + {%- if message.contentType() | isJsonPayload(defaultContentType) %} + const nc: Client = this.jsonClient!; {%- endif %} return {{ channelName | camelCase }}Channel.publish(requestMessage, nc); } diff --git a/.partials/index/reply.njk b/.partials/index/reply.njk index 68fe7dfee..0140c2ac6 100644 --- a/.partials/index/reply.njk +++ b/.partials/index/reply.njk @@ -6,14 +6,14 @@ * @param onReplyError Called when it was not possible to send the reply. */ public replyTo{{channelName | pascalCase }}(onRequest : (err?: NatsError, msg?: {{ subscribeMessage.uid() | pascalCase }}Message) => {{ publishMessage.uid() | pascalCase }}Message, onReplyError : (err: NatsError) => void): Promise { - {%- if message | isBinaryPayload(defaultContentType) %} - Client nc = this.binaryClient; + {%- if subscribeMessage.contentType() | isBinaryPayload(defaultContentType) %} + const nc: Client = this.binaryClient!; {%- endif %} - {%- if message | isStringPayload(defaultContentType) %} - Client nc = this.stringClient; + {%- if subscribeMessage.contentType() | isStringPayload(defaultContentType) %} + const nc: Client = this.stringClient!; {%- endif %} - {%- if message | isJsonPayload(defaultContentType) %} - Client nc = this.jsonClient; + {%- if subscribeMessage.contentType() | isJsonPayload(defaultContentType) %} + const nc: Client = this.jsonClient!; {%- endif %} return {{ channelName | camelCase }}Channel.reply(onRequest, onReplyError, nc); } diff --git a/.partials/index/request.njk b/.partials/index/request.njk index 728d08315..78409278b 100644 --- a/.partials/index/request.njk +++ b/.partials/index/request.njk @@ -5,14 +5,14 @@ * @param requestMessage The request message to send. */ public request{{channelName | pascalCase }}(requestMessage: {{ publishMessage.uid() | pascalCase }}Message): Promise<{{ subscribeMessage.uid() | pascalCase }}Message> { - {%- if message | isBinaryPayload(defaultContentType) %} - Client nc = this.binaryClient; + {%- if publishMessage.contentType() | isBinaryPayload(defaultContentType) %} + const nc: Client = this.binaryClient!; {%- endif %} - {%- if message | isStringPayload(defaultContentType) %} - Client nc = this.stringClient; + {%- if publishMessage.contentType() | isStringPayload(defaultContentType) %} + const nc: Client = this.stringClient!; {%- endif %} - {%- if message | isJsonPayload(defaultContentType) %} - Client nc = this.jsonClient; + {%- if publishMessage.contentType() | isJsonPayload(defaultContentType) %} + const nc: Client = this.jsonClient!; {%- endif %} return {{ channelName | camelCase }}Channel.request(requestMessage, nc); } diff --git a/.partials/index/subscribe.njk b/.partials/index/subscribe.njk index 1b3ab6ace..3c70d6591 100644 --- a/.partials/index/subscribe.njk +++ b/.partials/index/subscribe.njk @@ -5,14 +5,14 @@ * @param onDataCallback Called when message recieved. */ public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsError, msg?: {{ message.uid() | pascalCase }}Message) => void): Promise { - {%- if message | isBinaryPayload(defaultContentType) %} - Client nc = this.binaryClient; + {%- if message.contentType() | isBinaryPayload(defaultContentType) %} + const nc: Client = this.binaryClient!; {%- endif %} - {%- if message | isStringPayload(defaultContentType) %} - Client nc = this.stringClient; + {%- if message.contentType() | isStringPayload(defaultContentType) %} + const nc: Client = this.stringClient!; {%- endif %} - {%- if message | isJsonPayload(defaultContentType) %} - Client nc = this.jsonClient; + {%- if message.contentType() | isJsonPayload(defaultContentType) %} + const nc: Client = this.jsonClient!; {%- endif %} return {{ channelName | camelCase }}Channel.subscribe(onDataCallback, nc); } diff --git a/README.md b/README.md index 5530c31e7..d76ab49f3 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,13 @@ For binary payloads use: `binary` content type For json payloads use: `json` content type For string payloads use: `string` content type + +## Hooks + +Use the hooks to control the flow of information outside the generated code. + +These are the available hooks: + +| Hookname | Callback type | Description | +| BeforeSendingData | (Message: any) => new data | Called before sending any data. +| RevievedData | (recieved data: any) => new data | Called after data is recieved. diff --git a/__package.json.njk b/__package.json.njk index 5c9a02e0b..e0fdecf8b 100644 --- a/__package.json.njk +++ b/__package.json.njk @@ -28,11 +28,13 @@ "_moduleAliases": { "#messages": "./src/messages", "#schemas": "./src/schema", - "#channels": "./src/channels" + "#channels": "./src/channels", + "#hooks": "./src/hooks" }, "dependencies": { "@types/klaw-sync": "^6.0.0", "@types/uuid": "3.4.5", + "@types/node": "13.9.5", "klaw-sync": "6.0.0", "link-module-alias": "^1.2.0", "msgpack-lite": "^0.1.26", diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..e26efdc60 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,49 @@ +{ + "name": "@asyncapi/ts-nats-template", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=" + }, + "filenamify": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.1.0.tgz", + "integrity": "sha512-KQV/uJDI9VQgN7sHH1Zbk6+42cD6mnQ2HONzkXUfPJ+K2FC8GZ1dpewbbHw0Sz8Tf5k3EVdHVayM4DoAwWlmtg==", + "requires": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, + "trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", + "requires": { + "escape-string-regexp": "^1.0.2" + } + } + } +} diff --git a/src/channels/$$channel$$.ts.njk b/src/channels/$$channel$$.ts.njk index e52e78632..d187b840a 100644 --- a/src/channels/$$channel$$.ts.njk +++ b/src/channels/$$channel$$.ts.njk @@ -9,24 +9,23 @@ import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} {%- if channel.hasSubscribe() %} import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '../messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' {%- endif %} - import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{ request(channelName, channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} + {{ request(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} {%- endif %} {%- if channel | isReplier %} - {{ reply(channelName, channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server)) }} + {{ reply(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server)) }} {%- endif %} {%- endif %} {%- if channel | isPubsub %} {%- if channel.hasSubscribe() %} - {{ subscribe(channelName, channel.subscribe().message(0), asyncapi.server(params.server)) }} + {{ subscribe(channelName, channel.parameters(), channel.subscribe().message(0), asyncapi.server(params.server)) }} {%- endif %} {%- if channel.hasPublish() %} - {{ publish(channelName, channel.publish().message(0), asyncapi.server(params.server)) }} + {{ publish(channelName, channel.parameters(), channel.publish().message(0), asyncapi.server(params.server)) }} {%- endif %} {%- endif %} diff --git a/src/channels/utils.ts b/src/channels/utils.ts new file mode 100644 index 000000000..8810b700d --- /dev/null +++ b/src/channels/utils.ts @@ -0,0 +1,11 @@ +export function realizeChannelName(channelName: string, parameters: any) { + let returnString = channelName; + returnString = returnString.replace('/', '.'); + for (let parameterName in parameters) { + returnString = returnString.replace( + `{${parameterName}}`, + parameters[parameterName] + ); + } + return returnString; +} diff --git a/src/hooks.ts b/src/hooks.ts new file mode 100644 index 000000000..43138b0d0 --- /dev/null +++ b/src/hooks.ts @@ -0,0 +1,64 @@ +const HOOKS_DIRNAME = './hooks'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as walkSync from 'klaw-sync'; +export enum AvailableHooks { + RecievedData = 'RecievedData', + BeforeSendingData = 'BeforeSendingData' +} +export type RecievedDataHook = () => void; +export type BeforeSendingDataHook = (messageToSend: any) => void; +export var hooks: { + BeforeSendingData: [BeforeSendingDataHook]; + RecievedData: [RecievedDataHook]; +}; + +/** + * Loads the custom hooks. + */ +try { + const hooksPath = path.resolve(HOOKS_DIRNAME); + if (fs.existsSync(hooksPath)) { + const files = walkSync(hooksPath, { nodir: true }); + files.forEach((file: any) => { + require(file.path)((when: AvailableHooks, hook: any) => { + hooks[when] = hooks[when] || []; + hooks[when].push(hook); + }); + }); + } +} catch (e) { + e.message = `There was a problem registering the hooks: ${e.message}`; + throw e; +} + +/** + * Register a hook for BeforeSendingData + * @param hook + */ +export async function registerBeforeSendingData(hook: BeforeSendingDataHook) { + hooks[AvailableHooks.BeforeSendingData] + ? hooks[AvailableHooks.BeforeSendingData].push(hook) + : [hook]; +} + +/** + * Register a hook for BeforeSendingData + * @param hook + */ +export async function registerRecievedData(hook: RecievedDataHook) { + hooks[AvailableHooks.RecievedData] + ? hooks[AvailableHooks.RecievedData].push(hook) + : [hook]; +} + +/** + * Get all the hooks registered at a given hook point/name. + * @param hook to find hooks for + * @returns all hooks + */ +export function getHooks(hook: AvailableHooks): Function[] { + if (!Array.isArray(hooks[hook])) return []; + // Return valid hooks + return hooks[hook]; +} diff --git a/src/index.ts.njk b/src/index.ts.njk index 9131f8ce8..fb884c4a5 100644 --- a/src/index.ts.njk +++ b/src/index.ts.njk @@ -6,11 +6,11 @@ import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; -{%- for channelName, channel in asyncapi.channels() %} +{%- for channelName, _ in asyncapi.channels() %} import * as {{ channelName | camelCase }}Channel from "./channels/{{ channelName | firstUpperCase }}"; {%- endfor %} -{%- for messageName, message in asyncapi.allMessages() %} +{%- for messageName, _ in asyncapi.allMessages() %} import {default as {{ messageName | pascalCase }}Message} from "./messages/{{ messageName | pascalCase }}"; {%- endfor %} diff --git a/src/test/testclient/testchannels/$$channel$$.ts.njk b/src/test/testclient/testchannels/$$channel$$.ts.njk index 58d9a5960..327196486 100644 --- a/src/test/testclient/testchannels/$$channel$$.ts.njk +++ b/src/test/testclient/testchannels/$$channel$$.ts.njk @@ -15,18 +15,18 @@ import * as utils from '../utils'; {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{ reply(channelName, channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} + {{ reply(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} {%- endif %} {%- if channel | isReplier %} - {{ request(channelName, channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server)) }} + {{ request(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server)) }} {%- endif %} {%- endif %} {%- if channel | isPubsub %} {%- if channel.hasSubscribe() %} - {{ publish(channelName, channel.subscribe().message(0), asyncapi.server(params.server)) }} + {{ publish(channelName, channel.parameters(), channel.subscribe().message(0), asyncapi.server(params.server)) }} {%- endif %} {%- if channel.hasPublish() %} - {{ subscribe(channelName, channel.publish().message(0), asyncapi.server(params.server)) }} + {{ subscribe(channelName, channel.parameters(), channel.publish().message(0), asyncapi.server(params.server)) }} {%- endif %} {%- endif %} diff --git a/tsconfig.json b/tsconfig.json index 7355e5a16..9fb047824 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,14 @@ "removeComments": true, "preserveConstEnums": true, "sourceMap": true, - "outDir": "dist/" + "outDir": "dist/", + "baseUrl": "./src" /* Base directory to resolve non-absolute module names. */, + "paths": { + "#messages": ["messages"], + "#schemas": ["schema"], + "#channels": ["channels"], + "#hooks": ["hooks"] + } }, "include": ["src/**/*"], "exclude": ["node_modules", "**/*.spec.ts"] From ddec89173660b7a1c17fdec65ecc0adf2c5a4467 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Tue, 31 Mar 2020 18:15:22 +0200 Subject: [PATCH 012/110] Moved all files to accommodate new generator version.. --- {.filters => filters}/all.js | 0 {.hooks => hooks}/rename-njk.js | 0 {.hooks => hooks}/rename-packagefile.js | 0 {.hooks => hooks}/rename-readme.js | 0 .partials/channel/publish.njk => partials/channel/Publish.njk | 0 .partials/channel/reply.njk => partials/channel/Reply.njk | 0 .partials/channel/request.njk => partials/channel/Request.njk | 0 .partials/channel/subscribe.njk => partials/channel/Subscribe.njk | 0 .partials/index/publish.njk => partials/index/Publish.njk | 0 .partials/index/reply.njk => partials/index/Reply.njk | 0 .partials/index/request.njk => partials/index/Request.njk | 0 .partials/index/subscribe.njk => partials/index/Subscribe.njk | 0 __README.md => template/__README.md | 0 __package.json.njk => template/__package.json.njk | 0 {src => template/src}/channels/$$channel$$.ts.njk | 0 {src => template/src}/channels/utils.ts | 0 {src => template/src}/hooks.ts | 0 {src => template/src}/index.ts.njk | 0 {src => template/src}/messages/$$message$$.ts.njk | 0 {src => template/src}/schema/$$everySchema$$.ts.njk | 0 {src => template/src}/test/testclient/index.ts.njk | 0 .../src}/test/testclient/testchannels/$$channel$$.ts.njk | 0 tsconfig.json => template/tsconfig.json | 0 23 files changed, 0 insertions(+), 0 deletions(-) rename {.filters => filters}/all.js (100%) rename {.hooks => hooks}/rename-njk.js (100%) rename {.hooks => hooks}/rename-packagefile.js (100%) rename {.hooks => hooks}/rename-readme.js (100%) rename .partials/channel/publish.njk => partials/channel/Publish.njk (100%) rename .partials/channel/reply.njk => partials/channel/Reply.njk (100%) rename .partials/channel/request.njk => partials/channel/Request.njk (100%) rename .partials/channel/subscribe.njk => partials/channel/Subscribe.njk (100%) rename .partials/index/publish.njk => partials/index/Publish.njk (100%) rename .partials/index/reply.njk => partials/index/Reply.njk (100%) rename .partials/index/request.njk => partials/index/Request.njk (100%) rename .partials/index/subscribe.njk => partials/index/Subscribe.njk (100%) rename __README.md => template/__README.md (100%) rename __package.json.njk => template/__package.json.njk (100%) rename {src => template/src}/channels/$$channel$$.ts.njk (100%) rename {src => template/src}/channels/utils.ts (100%) rename {src => template/src}/hooks.ts (100%) rename {src => template/src}/index.ts.njk (100%) rename {src => template/src}/messages/$$message$$.ts.njk (100%) rename {src => template/src}/schema/$$everySchema$$.ts.njk (100%) rename {src => template/src}/test/testclient/index.ts.njk (100%) rename {src => template/src}/test/testclient/testchannels/$$channel$$.ts.njk (100%) rename tsconfig.json => template/tsconfig.json (100%) diff --git a/.filters/all.js b/filters/all.js similarity index 100% rename from .filters/all.js rename to filters/all.js diff --git a/.hooks/rename-njk.js b/hooks/rename-njk.js similarity index 100% rename from .hooks/rename-njk.js rename to hooks/rename-njk.js diff --git a/.hooks/rename-packagefile.js b/hooks/rename-packagefile.js similarity index 100% rename from .hooks/rename-packagefile.js rename to hooks/rename-packagefile.js diff --git a/.hooks/rename-readme.js b/hooks/rename-readme.js similarity index 100% rename from .hooks/rename-readme.js rename to hooks/rename-readme.js diff --git a/.partials/channel/publish.njk b/partials/channel/Publish.njk similarity index 100% rename from .partials/channel/publish.njk rename to partials/channel/Publish.njk diff --git a/.partials/channel/reply.njk b/partials/channel/Reply.njk similarity index 100% rename from .partials/channel/reply.njk rename to partials/channel/Reply.njk diff --git a/.partials/channel/request.njk b/partials/channel/Request.njk similarity index 100% rename from .partials/channel/request.njk rename to partials/channel/Request.njk diff --git a/.partials/channel/subscribe.njk b/partials/channel/Subscribe.njk similarity index 100% rename from .partials/channel/subscribe.njk rename to partials/channel/Subscribe.njk diff --git a/.partials/index/publish.njk b/partials/index/Publish.njk similarity index 100% rename from .partials/index/publish.njk rename to partials/index/Publish.njk diff --git a/.partials/index/reply.njk b/partials/index/Reply.njk similarity index 100% rename from .partials/index/reply.njk rename to partials/index/Reply.njk diff --git a/.partials/index/request.njk b/partials/index/Request.njk similarity index 100% rename from .partials/index/request.njk rename to partials/index/Request.njk diff --git a/.partials/index/subscribe.njk b/partials/index/Subscribe.njk similarity index 100% rename from .partials/index/subscribe.njk rename to partials/index/Subscribe.njk diff --git a/__README.md b/template/__README.md similarity index 100% rename from __README.md rename to template/__README.md diff --git a/__package.json.njk b/template/__package.json.njk similarity index 100% rename from __package.json.njk rename to template/__package.json.njk diff --git a/src/channels/$$channel$$.ts.njk b/template/src/channels/$$channel$$.ts.njk similarity index 100% rename from src/channels/$$channel$$.ts.njk rename to template/src/channels/$$channel$$.ts.njk diff --git a/src/channels/utils.ts b/template/src/channels/utils.ts similarity index 100% rename from src/channels/utils.ts rename to template/src/channels/utils.ts diff --git a/src/hooks.ts b/template/src/hooks.ts similarity index 100% rename from src/hooks.ts rename to template/src/hooks.ts diff --git a/src/index.ts.njk b/template/src/index.ts.njk similarity index 100% rename from src/index.ts.njk rename to template/src/index.ts.njk diff --git a/src/messages/$$message$$.ts.njk b/template/src/messages/$$message$$.ts.njk similarity index 100% rename from src/messages/$$message$$.ts.njk rename to template/src/messages/$$message$$.ts.njk diff --git a/src/schema/$$everySchema$$.ts.njk b/template/src/schema/$$everySchema$$.ts.njk similarity index 100% rename from src/schema/$$everySchema$$.ts.njk rename to template/src/schema/$$everySchema$$.ts.njk diff --git a/src/test/testclient/index.ts.njk b/template/src/test/testclient/index.ts.njk similarity index 100% rename from src/test/testclient/index.ts.njk rename to template/src/test/testclient/index.ts.njk diff --git a/src/test/testclient/testchannels/$$channel$$.ts.njk b/template/src/test/testclient/testchannels/$$channel$$.ts.njk similarity index 100% rename from src/test/testclient/testchannels/$$channel$$.ts.njk rename to template/src/test/testclient/testchannels/$$channel$$.ts.njk diff --git a/tsconfig.json b/template/tsconfig.json similarity index 100% rename from tsconfig.json rename to template/tsconfig.json From 2218dd28bbe5791347f3e39bedee655cf81ed1dd Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sun, 5 Apr 2020 03:50:22 +0200 Subject: [PATCH 013/110] Renamed template package and readme and removed unused hooks --- hooks/rename-packagefile.js | 11 ----------- hooks/rename-readme.js | 11 ----------- template/{__README.md => README.md.njk} | 0 template/{__package.json.njk => package.json.njk} | 12 ++++++++++-- 4 files changed, 10 insertions(+), 24 deletions(-) delete mode 100644 hooks/rename-packagefile.js delete mode 100644 hooks/rename-readme.js rename template/{__README.md => README.md.njk} (100%) rename template/{__package.json.njk => package.json.njk} (84%) diff --git a/hooks/rename-packagefile.js b/hooks/rename-packagefile.js deleted file mode 100644 index e2e300488..000000000 --- a/hooks/rename-packagefile.js +++ /dev/null @@ -1,11 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -module.exports = register => { - register('generate:after', generator => { - fs.renameSync( - path.resolve(generator.targetDir, './__package.json'), - path.resolve(generator.targetDir, './package.json') - ); - }); -}; diff --git a/hooks/rename-readme.js b/hooks/rename-readme.js deleted file mode 100644 index 8e9023ebe..000000000 --- a/hooks/rename-readme.js +++ /dev/null @@ -1,11 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -module.exports = register => { - register('generate:after', generator => { - fs.renameSync( - path.resolve(generator.targetDir, './__README.md'), - path.resolve(generator.targetDir, './README.md') - ); - }); -}; diff --git a/template/__README.md b/template/README.md.njk similarity index 100% rename from template/__README.md rename to template/README.md.njk diff --git a/template/__package.json.njk b/template/package.json.njk similarity index 84% rename from template/__package.json.njk rename to template/package.json.njk index e0fdecf8b..383cc2610 100644 --- a/template/__package.json.njk +++ b/template/package.json.njk @@ -22,7 +22,8 @@ "watch": "tsc --watch", "build": "tsc", "start": "node src/api/index.js", - "postinstall": "link-module-alias" + "postinstall": "link-module-alias", + "test": "mocha -r ts-node/register tests/\*\*/\*.spec.ts" }, "_moduleAliasIgnoreWarning": true, "_moduleAliases": { @@ -44,5 +45,12 @@ "uuid": "3.3.3", "winston": "3.2.1", "winston-daily-rotate-file": "3.10.0" - } + }, + "devDependencies": { + "@types/chai": "^4.2.11", + "@types/mocha": "^7.0.2", + "chai": "^4.2.0", + "mocha": "^7.1.1", + "ts-node": "^8.8.1" + } } From 53fee54f18ef00cde6c9d4fdac99b4771d730aea Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sun, 5 Apr 2020 03:50:55 +0200 Subject: [PATCH 014/110] Fix: template hooks --- template/src/hooks.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/template/src/hooks.ts b/template/src/hooks.ts index 43138b0d0..7dfcbfbd9 100644 --- a/template/src/hooks.ts +++ b/template/src/hooks.ts @@ -9,8 +9,8 @@ export enum AvailableHooks { export type RecievedDataHook = () => void; export type BeforeSendingDataHook = (messageToSend: any) => void; export var hooks: { - BeforeSendingData: [BeforeSendingDataHook]; - RecievedData: [RecievedDataHook]; + BeforeSendingData: BeforeSendingDataHook[]; + RecievedData: RecievedDataHook[]; }; /** @@ -22,7 +22,6 @@ try { const files = walkSync(hooksPath, { nodir: true }); files.forEach((file: any) => { require(file.path)((when: AvailableHooks, hook: any) => { - hooks[when] = hooks[when] || []; hooks[when].push(hook); }); }); From 38e70f2f3776e8797b215ecdeb7e16f5a2a73a1a Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sun, 5 Apr 2020 03:51:24 +0200 Subject: [PATCH 015/110] Test: added documents to test --- .../0.1.0/components/channel-bindings.yml | 9 ++ tests/docs/0.1.0/components/messages.yml | 31 +++++ tests/docs/0.1.0/components/parameters.yml | 4 + tests/docs/0.1.0/components/schemas.yml | 57 ++++++++ tests/docs/0.1.0/frontend.yml | 127 ++++++++++++++++++ tests/docs/0.1.0/light-controller.yml | 121 +++++++++++++++++ 6 files changed, 349 insertions(+) create mode 100644 tests/docs/0.1.0/components/channel-bindings.yml create mode 100644 tests/docs/0.1.0/components/messages.yml create mode 100644 tests/docs/0.1.0/components/parameters.yml create mode 100644 tests/docs/0.1.0/components/schemas.yml create mode 100644 tests/docs/0.1.0/frontend.yml create mode 100644 tests/docs/0.1.0/light-controller.yml diff --git a/tests/docs/0.1.0/components/channel-bindings.yml b/tests/docs/0.1.0/components/channel-bindings.yml new file mode 100644 index 000000000..8e2de6ae6 --- /dev/null +++ b/tests/docs/0.1.0/components/channel-bindings.yml @@ -0,0 +1,9 @@ +smartylightingMeasurement: + nats: + is: pubsub + queue: + name: smartylightingMeasurement + bindingVersion: '0.1.0' + + + diff --git a/tests/docs/0.1.0/components/messages.yml b/tests/docs/0.1.0/components/messages.yml new file mode 100644 index 000000000..d144416f8 --- /dev/null +++ b/tests/docs/0.1.0/components/messages.yml @@ -0,0 +1,31 @@ +lightMeasured: + name: lightMeasured + title: Light measured + summary: Inform about environmental lighting conditions of a particular streetlight. + contentType: application/json + payload: + $ref: "./schemas.yml#/lightMeasuredPayload" +turnOnOff: + name: turnOnOff + title: Turn on/off + summary: Command a particular streetlight to turn the lights on or off. + payload: + $ref: "./schemas.yml#/turnOnOffPayload" +turnOnOffResponse: + name: turnOnOffResponse + title: turn on/off light response when processed. + payload: + $ref: "./schemas.yml#/response" +dimLight: + name: dimLight + title: Dim light + summary: Command a particular streetlight to dim the lights. + payload: + anyOf: + - $ref: "./schemas.yml#/dimLightPayloadserere" + - $ref: "./schemas.yml#/response" +dimLightResponse: + name: dimLightResponse + title: Dim light response when processed. + payload: + $ref: "./schemas.yml#/response" diff --git a/tests/docs/0.1.0/components/parameters.yml b/tests/docs/0.1.0/components/parameters.yml new file mode 100644 index 000000000..b8ef4fce5 --- /dev/null +++ b/tests/docs/0.1.0/components/parameters.yml @@ -0,0 +1,4 @@ +streetlightId: + description: The ID of the streetlight. + schema: + type: string diff --git a/tests/docs/0.1.0/components/schemas.yml b/tests/docs/0.1.0/components/schemas.yml new file mode 100644 index 000000000..800b42cb8 --- /dev/null +++ b/tests/docs/0.1.0/components/schemas.yml @@ -0,0 +1,57 @@ +lightMeasuredPayload: + type: object + $id: lightMeasuredPayload + x-parser-schema-id: lightMeasuredPayload + properties: + lumens: + type: integer + minimum: 0 + description: Light intensity measured in lumens. + x-pi: false + sentAt: + $ref: "#/sentAt" +turnOnOffPayload: + type: object + $id: turnOnOffPayload + x-parser-schema-id: turnOnOffPayload + properties: + command: + type: string + enum: + - on + - off + description: Whether to turn on or off the light. + x-pi: false + sentAt: + $ref: "#/sentAt" +dimLightPayloadserere: + type: object + $id: dimLightPayloadserere + x-parser-schema-id: dimLightPayloadserere + properties: + percentage: + type: integer + description: Percentage to which the light should be dimmed to. + minimum: 0 + maximum: 100 + sentAt: + $ref: "#/sentAt" +sentAt: + type: string + format: date-time + description: Date and time when the message was sent. +response: + type: object + $id: response + x-parser-schema-id: response + properties: + status: + type: integer + description: Like http codes + statusMessage: + type: string + enum: + - OK + - ERROR + sentAt: + $ref: "#/sentAt" diff --git a/tests/docs/0.1.0/frontend.yml b/tests/docs/0.1.0/frontend.yml new file mode 100644 index 000000000..25d903dcb --- /dev/null +++ b/tests/docs/0.1.0/frontend.yml @@ -0,0 +1,127 @@ +asyncapi: '2.0.0' +info: + title: Streetlights Nats API for the frontend + version: '1.0.0' + description: | + The Smartylighting Streetlights API allows you to remotely manage the city lights. + + This is for the frontend where the lights can be controlled, which assumed are multiple instances to ensure availability. + + ### Check out its awesome features: + + * Turn a specific streetlight on/off 🌃 + * Dim a specific streetlight 😎 + * Receive real-time information about environmental lighting conditions 📈 + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0 + +servers: + production: + url: test.nats.org:{port} + protocol: nats + description: Test broker + variables: + port: + default: '4444' + security: + - apiKey: [] + +defaultContentType: json + +channels: + smartylighting/streetlights/1/0/event/*: + description: Topic for which one can subscribe to all measurements regardless of id. + subscribe: + operationId: receiveAllLightMeasurements + message: + $ref: './components/messages.yml#/lightMeasured' + bindings: + $ref: './components/channel-bindings.yml#/smartylightingMeasurement' + + smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured: + description: Topic for which one can subscribe to measurements on a specific streetlightId. + parameters: + streetlightId: + $ref: './components/parameters.yml#/streetlightId' + subscribe: + operationId: receiveLightMeasurements + message: + $ref: './components/messages.yml#/lightMeasured' + bindings: + $ref: './components/channel-bindings.yml#/smartylightingMeasurement' + + smartylighting/streetlights/1/0/action/{streetlightId}/turn/on: + parameters: + streetlightId: + $ref: './components/parameters.yml#/streetlightId' + publish: + operationId: turnOn + description: The turn on request send to the light controller. + message: + $ref: './components/messages.yml#/turnOnOff' + subscribe: + operationId: turnOnResponse + description: The response returned by the light controller. + message: + $ref: './components/messages.yml#/turnOnOffResponse' + bindings: + nats: + is: requestReply + requestReply: + is: requester + queue: + name: smartylightingTurnOn + bindingVersion: '0.1.0' + smartylighting/streetlights/1/0/action/{streetlightId}/turn/off: + parameters: + streetlightId: + $ref: './components/parameters.yml#/streetlightId' + subscribe: + operationId: turnOffResponse + description: The response returned by the light controller. + message: + $ref: './components/messages.yml#/turnOnOffResponse' + publish: + operationId: turnOff + description: The turn off request send to the light controller. + message: + $ref: './components/messages.yml#/turnOnOff' + bindings: + nats: + is: requestReply + requestReply: + is: requester + queue: + name: smartylightingTurnOff + bindingVersion: '0.1.0' + + smartylighting/streetlights/1/0/action/{streetlightId}/dim: + parameters: + streetlightId: + $ref: './components/parameters.yml#/streetlightId' + subscribe: + operationId: dimLightResponse + description: The response returned by the light controller. + message: + $ref: './components/messages.yml#/dimLightResponse' + publish: + operationId: dimLight + description: The dim light request send to the light controller. + message: + $ref: './components/messages.yml#/dimLight' + bindings: + nats: + is: requestReply + requestReply: + is: requester + queue: + name: smartylightingDim + bindingVersion: '0.1.0' + +components: + securitySchemes: + apiKey: + type: apiKey + in: user + description: Provide your API key as the user and leave the password empty. diff --git a/tests/docs/0.1.0/light-controller.yml b/tests/docs/0.1.0/light-controller.yml new file mode 100644 index 000000000..ead10b58d --- /dev/null +++ b/tests/docs/0.1.0/light-controller.yml @@ -0,0 +1,121 @@ +asyncapi: '2.0.0' +info: + title: Streetlights Nats API for lightning controllers + version: '1.0.0' + description: | + The Smartylighting Streetlights API allows you to remotely manage the city lights. + + This is for the lighting controllers, which assumed are multiple instances to ensure availability. + + ### Check out its awesome features: + + * Turn a specific streetlight on/off 🌃 + * Dim a specific streetlight 😎 + * Receive real-time information about environmental lighting conditions 📈 + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0 + +servers: + production: + url: test.nats.org:{port} + protocol: nats + description: Test broker + variables: + port: + default: '4444' + security: + - apiKey: [] + +defaultContentType: json +channels: + smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured: + description: Any measured values will be published through this method. + parameters: + streetlightId: + $ref: './components/parameters.yml#/streetlightId' + publish: + operationId: publishLightMeasurement + message: + $ref: './components/messages.yml#/lightMeasured' + bindings: + $ref: './components/channel-bindings.yml#/smartylightingMeasurement' + + smartylighting/streetlights/1/0/action/{streetlightId}/turn/on: + description: Get notified when a streetlight should be turned on. This should only be handled by 1 subscriber but ensured by request reply. + parameters: + streetlightId: + $ref: './components/parameters.yml#/streetlightId' + publish: + operationId: turnOnResponse + description: The response returned by us to the frontend. + message: + $ref: './components/messages.yml#/turnOnOffResponse' + subscribe: + operationId: turnOn + description: The turn on request received from the frontend. + message: + $ref: './components/messages.yml#/turnOnOff' + bindings: + nats: + is: requestReply + requestReply: + is: replier + queue: + name: smartylightingTurnOn + bindingVersion: '0.1.0' + + smartylighting/streetlights/1/0/action/{streetlightId}/turn/off: + description: Get notified when a streetlight should be turned off. This should only be handled by 1 subscriber but ensured by request reply. + parameters: + streetlightId: + $ref: './components/parameters.yml#/streetlightId' + publish: + operationId: turnOffResponse + description: The response returned by us to the frontend. + message: + $ref: './components/messages.yml#/turnOnOffResponse' + subscribe: + operationId: turnOff + description: The turn off request received from the frontend. + message: + $ref: './components/messages.yml#/turnOnOff' + bindings: + nats: + is: requestReply + requestReply: + is: replier + queue: + name: smartylightingTurnOff + bindingVersion: '0.1.0' + + smartylighting/streetlights/1/0/action/{streetlightId}/dim: + description: Get notified when a streetlight should be dimmed. This should only be handled by 1 subscriber but ensured by request reply. + parameters: + streetlightId: + $ref: './components/parameters.yml#/streetlightId' + publish: + operationId: dimLightResponse + description: The response returned by us. + message: + $ref: './components/messages.yml#/dimLightResponse' + subscribe: + operationId: dimLight + description: The dim light request received from the frontend. + message: + $ref: './components/messages.yml#/dimLight' + bindings: + nats: + is: requestReply + requestReply: + is: replier + queue: + name: smartylightingDim + bindingVersion: '0.1.0' + +components: + securitySchemes: + apiKey: + type: apiKey + in: user + description: Provide your API key as the user and leave the password empty. From 8323434425d86d05e80f1e58ea224e682d4f459c Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sun, 5 Apr 2020 03:52:44 +0200 Subject: [PATCH 016/110] Fix: template partial paths --- template/src/channels/$$channel$$.ts.njk | 8 ++++---- template/src/index.ts.njk | 8 ++++---- .../testclient/testchannels/$$channel$$.ts.njk | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) rename template/src/{test => tests}/testclient/testchannels/$$channel$$.ts.njk (82%) diff --git a/template/src/channels/$$channel$$.ts.njk b/template/src/channels/$$channel$$.ts.njk index d187b840a..c8fafea95 100644 --- a/template/src/channels/$$channel$$.ts.njk +++ b/template/src/channels/$$channel$$.ts.njk @@ -1,8 +1,8 @@ -{%- from "../../.partials/channel/publish.njk" import publish %} -{%- from "../../.partials/channel/reply.njk" import reply %} -{%- from "../../.partials/channel/request.njk" import request %} -{%- from "../../.partials/channel/subscribe.njk" import subscribe %} +{%- from "../../../partials/channel/publish.njk" import publish %} +{%- from "../../../partials/channel/reply.njk" import reply %} +{%- from "../../../partials/channel/request.njk" import request %} +{%- from "../../../partials/channel/subscribe.njk" import subscribe %} {%- if channel.hasPublish() %} import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '../messages/{{ channel.publish().message(0).uid() | pascalCase}}' {%- endif %} diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index fb884c4a5..bc56b48b6 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -1,8 +1,8 @@ -{%- from "../.partials/index/publish.njk" import publish %} -{%- from "../.partials/index/reply.njk" import reply %} -{%- from "../.partials/index/request.njk" import request %} -{%- from "../.partials/index/subscribe.njk" import subscribe %} +{%- from "../../partials/index/publish.njk" import publish %} +{%- from "../../partials/index/reply.njk" import reply %} +{%- from "../../partials/index/request.njk" import request %} +{%- from "../../partials/index/subscribe.njk" import subscribe %} import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; diff --git a/template/src/test/testclient/testchannels/$$channel$$.ts.njk b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk similarity index 82% rename from template/src/test/testclient/testchannels/$$channel$$.ts.njk rename to template/src/tests/testclient/testchannels/$$channel$$.ts.njk index 327196486..179abf81f 100644 --- a/template/src/test/testclient/testchannels/$$channel$$.ts.njk +++ b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk @@ -1,8 +1,8 @@ -{%- from "../../../../.partials/channel/publish.njk" import publish %} -{%- from "../../../../.partials/channel/reply.njk" import reply %} -{%- from "../../../../.partials/channel/request.njk" import request %} -{%- from "../../../../.partials/channel/subscribe.njk" import subscribe %} +{%- from "../../../../../partials/channel/publish.njk" import publish %} +{%- from "../../../../../partials/channel/reply.njk" import reply %} +{%- from "../../../../../partials/channel/request.njk" import request %} +{%- from "../../../../../partials/channel/subscribe.njk" import subscribe %} {%- if channel.hasPublish() %} import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '../../../messages/{{ channel.publish().message(0).uid() | pascalCase}}' {%- endif %} From 074376f3e8777ae5b596fa4915095382505da609 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sun, 5 Apr 2020 03:53:08 +0200 Subject: [PATCH 017/110] Fix: missing check for bindings in filters --- filters/all.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/filters/all.js b/filters/all.js index 2b08f9ff8..f66b2e93d 100644 --- a/filters/all.js +++ b/filters/all.js @@ -226,23 +226,21 @@ module.exports = ({ Nunjucks }) => { }); Nunjucks.addFilter('isPubsub', channel => { - let tempChannel = channel._json; - if (tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'pubsub') { + const tempChannel = channel._json; + if (tempChannel.bindings && tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'pubsub') { return true; } return false; }); Nunjucks.addFilter('hasNatsBindings', obj => { - if (obj.bindings.nats) { - return true; - } - return false; + return obj.bindings && obj.bindings.nats; }); Nunjucks.addFilter('isRequestReply', channel => { let tempChannel = channel._json; if ( + tempChannel.bindings && tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'requestReply' ) { @@ -254,6 +252,7 @@ module.exports = ({ Nunjucks }) => { Nunjucks.addFilter('isRequester', channel => { let tempChannel = channel._json; if ( + tempChannel.bindings && tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'requestReply' && tempChannel.bindings.nats.requestReply && @@ -267,6 +266,7 @@ module.exports = ({ Nunjucks }) => { Nunjucks.addFilter('isReplier', channel => { let tempChannel = channel._json; if ( + tempChannel.bindings && tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'requestReply' && tempChannel.bindings.nats.requestReply && From 1afafe14ce61290b6fcd2a6da6dc207a3fa1f348 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sun, 5 Apr 2020 03:54:16 +0200 Subject: [PATCH 018/110] Test: added template and generated tests --- .gitignore | 3 +- README.md | 15 +- package-lock.json | 1016 +++++++++++++++++ package.json | 9 + scripts/generate_new_actual_comparators.sh | 33 + scripts/generate_new_expected_comparators.sh | 33 + template/src/channels/$$channel$$.ts.njk | 8 +- template/src/index.ts.njk | 8 +- template/src/test/testclient/index.ts.njk | 70 -- template/src/tests/$$channel$$.ts | 0 template/src/tests/schemas/$$schema$$.spec.ts | 9 + template/src/tests/testclient/index.ts.njk | 27 + .../testchannels/$$channel$$.ts.njk | 8 +- .../latest/frontend/README.md | 17 + .../latest/frontend/package.json | 45 + ...etlights-1-0-action-{streetlightId}-dim.ts | 46 + ...hts-1-0-action-{streetlightId}-turn-off.ts | 46 + ...ghts-1-0-action-{streetlightId}-turn-on.ts | 46 + ...event-{streetlightId}-lighting-measured.ts | 44 + .../smartylighting-streetlights-1-0-event.ts | 40 + .../latest/frontend/src/channels/utils.ts | 11 + .../latest/frontend/src/hooks.ts | 63 + .../latest/frontend/src/index.ts | 101 ++ .../latest/frontend/src/messages/dimLight.ts | 45 + .../frontend/src/messages/dimLightResponse.ts | 30 + .../frontend/src/messages/lightMeasured.ts | 30 + .../latest/frontend/src/messages/turnOnOff.ts | 30 + .../src/messages/turnOnOffResponse.ts | 30 + .../frontend/src/schema/anonymous-schema-4.ts | 11 + .../frontend/src/schema/anonymous-schema-5.ts | 22 + .../src/schema/lightMeasuredPayload.ts | 13 + .../latest/frontend/src/schema/response.ts | 14 + .../frontend/src/schema/turnOnOffPayload.ts | 13 + ...etlights-1-0-action-{streetlightId}-dim.ts | 0 ...hts-1-0-action-{streetlightId}-turn-off.ts | 0 ...ghts-1-0-action-{streetlightId}-turn-on.ts | 0 ...event-{streetlightId}-lighting-measured.ts | 0 .../smartylighting-streetlights-1-0-event.ts | 0 .../frontend/src/tests/testclient/index.ts | 54 + ...etlights-1-0-action-{streetlightId}-dim.ts | 66 ++ ...hts-1-0-action-{streetlightId}-turn-off.ts | 66 ++ ...ghts-1-0-action-{streetlightId}-turn-on.ts | 66 ++ ...event-{streetlightId}-lighting-measured.ts | 37 + .../smartylighting-streetlights-1-0-event.ts | 33 + .../latest/frontend/tsconfig.json | 22 + .../latest/light-controller/README.md | 17 + .../latest/light-controller/package.json | 45 + ...etlights-1-0-action-{streetlightId}-dim.ts | 66 ++ ...hts-1-0-action-{streetlightId}-turn-off.ts | 66 ++ ...ghts-1-0-action-{streetlightId}-turn-on.ts | 66 ++ ...event-{streetlightId}-lighting-measured.ts | 37 + .../light-controller/src/channels/utils.ts | 11 + .../latest/light-controller/src/hooks.ts | 63 + .../latest/light-controller/src/index.ts | 93 ++ .../light-controller/src/messages/dimLight.ts | 45 + .../src/messages/dimLightResponse.ts | 30 + .../src/messages/lightMeasured.ts | 30 + .../src/messages/turnOnOff.ts | 30 + .../src/messages/turnOnOffResponse.ts | 30 + .../src/schema/anonymous-schema-4.ts | 11 + .../src/schema/anonymous-schema-5.ts | 22 + .../src/schema/lightMeasuredPayload.ts | 13 + .../light-controller/src/schema/response.ts | 14 + .../src/schema/turnOnOffPayload.ts | 13 + ...etlights-1-0-action-{streetlightId}-dim.ts | 0 ...hts-1-0-action-{streetlightId}-turn-off.ts | 0 ...ghts-1-0-action-{streetlightId}-turn-on.ts | 0 ...event-{streetlightId}-lighting-measured.ts | 0 .../src/tests/testclient/index.ts | 41 + ...etlights-1-0-action-{streetlightId}-dim.ts | 46 + ...hts-1-0-action-{streetlightId}-turn-off.ts | 46 + ...ghts-1-0-action-{streetlightId}-turn-on.ts | 46 + ...event-{streetlightId}-lighting-measured.ts | 44 + .../latest/light-controller/tsconfig.json | 22 + .../0.1.0/components/channel-bindings.yml | 0 .../docs/0.1.0/components/messages.yml | 0 .../docs/0.1.0/components/parameters.yml | 0 .../docs/0.1.0/components/schemas.yml | 0 {tests => test}/docs/0.1.0/frontend.yml | 0 .../docs/0.1.0/light-controller.yml | 0 .../latest/frontend/README.md | 17 + .../latest/frontend/package.json | 45 + ...etlights-1-0-action-{streetlightId}-dim.ts | 46 + ...hts-1-0-action-{streetlightId}-turn-off.ts | 46 + ...ghts-1-0-action-{streetlightId}-turn-on.ts | 46 + ...event-{streetlightId}-lighting-measured.ts | 44 + .../smartylighting-streetlights-1-0-event.ts | 40 + .../latest/frontend/src/channels/utils.ts | 11 + .../latest/frontend/src/hooks.ts | 63 + .../latest/frontend/src/index.ts | 101 ++ .../latest/frontend/src/messages/dimLight.ts | 45 + .../frontend/src/messages/dimLightResponse.ts | 30 + .../frontend/src/messages/lightMeasured.ts | 30 + .../latest/frontend/src/messages/turnOnOff.ts | 30 + .../src/messages/turnOnOffResponse.ts | 30 + .../frontend/src/schema/anonymous-schema-4.ts | 11 + .../frontend/src/schema/anonymous-schema-5.ts | 22 + .../src/schema/lightMeasuredPayload.ts | 13 + .../latest/frontend/src/schema/response.ts | 14 + .../frontend/src/schema/turnOnOffPayload.ts | 13 + ...etlights-1-0-action-{streetlightId}-dim.ts | 0 ...hts-1-0-action-{streetlightId}-turn-off.ts | 0 ...ghts-1-0-action-{streetlightId}-turn-on.ts | 0 ...event-{streetlightId}-lighting-measured.ts | 0 .../smartylighting-streetlights-1-0-event.ts | 0 .../frontend/src/tests/testclient/index.ts | 54 + ...etlights-1-0-action-{streetlightId}-dim.ts | 66 ++ ...hts-1-0-action-{streetlightId}-turn-off.ts | 66 ++ ...ghts-1-0-action-{streetlightId}-turn-on.ts | 66 ++ ...event-{streetlightId}-lighting-measured.ts | 37 + .../smartylighting-streetlights-1-0-event.ts | 33 + .../latest/frontend/tsconfig.json | 22 + .../latest/light-controller/README.md | 17 + .../latest/light-controller/package.json | 45 + ...etlights-1-0-action-{streetlightId}-dim.ts | 66 ++ ...hts-1-0-action-{streetlightId}-turn-off.ts | 66 ++ ...ghts-1-0-action-{streetlightId}-turn-on.ts | 66 ++ ...event-{streetlightId}-lighting-measured.ts | 37 + .../light-controller/src/channels/utils.ts | 11 + .../latest/light-controller/src/hooks.ts | 63 + .../latest/light-controller/src/index.ts | 93 ++ .../light-controller/src/messages/dimLight.ts | 45 + .../src/messages/dimLightResponse.ts | 30 + .../src/messages/lightMeasured.ts | 30 + .../src/messages/turnOnOff.ts | 30 + .../src/messages/turnOnOffResponse.ts | 30 + .../src/schema/anonymous-schema-4.ts | 11 + .../src/schema/anonymous-schema-5.ts | 22 + .../src/schema/lightMeasuredPayload.ts | 13 + .../light-controller/src/schema/response.ts | 14 + .../src/schema/turnOnOffPayload.ts | 13 + ...etlights-1-0-action-{streetlightId}-dim.ts | 0 ...hts-1-0-action-{streetlightId}-turn-off.ts | 0 ...ghts-1-0-action-{streetlightId}-turn-on.ts | 0 ...event-{streetlightId}-lighting-measured.ts | 0 .../src/tests/testclient/index.ts | 41 + ...etlights-1-0-action-{streetlightId}-dim.ts | 46 + ...hts-1-0-action-{streetlightId}-turn-off.ts | 46 + ...ghts-1-0-action-{streetlightId}-turn-on.ts | 46 + ...event-{streetlightId}-lighting-measured.ts | 44 + .../latest/light-controller/tsconfig.json | 22 + test/template.js | 26 + 142 files changed, 5155 insertions(+), 86 deletions(-) create mode 100644 scripts/generate_new_actual_comparators.sh create mode 100644 scripts/generate_new_expected_comparators.sh delete mode 100644 template/src/test/testclient/index.ts.njk create mode 100644 template/src/tests/$$channel$$.ts create mode 100644 template/src/tests/schemas/$$schema$$.spec.ts create mode 100644 template/src/tests/testclient/index.ts.njk create mode 100644 test/actual_comparators/latest/frontend/README.md create mode 100644 test/actual_comparators/latest/frontend/package.json create mode 100644 test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts create mode 100644 test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts create mode 100644 test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts create mode 100644 test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts create mode 100644 test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event.ts create mode 100644 test/actual_comparators/latest/frontend/src/channels/utils.ts create mode 100644 test/actual_comparators/latest/frontend/src/hooks.ts create mode 100644 test/actual_comparators/latest/frontend/src/index.ts create mode 100644 test/actual_comparators/latest/frontend/src/messages/dimLight.ts create mode 100644 test/actual_comparators/latest/frontend/src/messages/dimLightResponse.ts create mode 100644 test/actual_comparators/latest/frontend/src/messages/lightMeasured.ts create mode 100644 test/actual_comparators/latest/frontend/src/messages/turnOnOff.ts create mode 100644 test/actual_comparators/latest/frontend/src/messages/turnOnOffResponse.ts create mode 100644 test/actual_comparators/latest/frontend/src/schema/anonymous-schema-4.ts create mode 100644 test/actual_comparators/latest/frontend/src/schema/anonymous-schema-5.ts create mode 100644 test/actual_comparators/latest/frontend/src/schema/lightMeasuredPayload.ts create mode 100644 test/actual_comparators/latest/frontend/src/schema/response.ts create mode 100644 test/actual_comparators/latest/frontend/src/schema/turnOnOffPayload.ts create mode 100644 test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts create mode 100644 test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts create mode 100644 test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts create mode 100644 test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts create mode 100644 test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event.ts create mode 100644 test/actual_comparators/latest/frontend/src/tests/testclient/index.ts create mode 100644 test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts create mode 100644 test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts create mode 100644 test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts create mode 100644 test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts create mode 100644 test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event.ts create mode 100644 test/actual_comparators/latest/frontend/tsconfig.json create mode 100644 test/actual_comparators/latest/light-controller/README.md create mode 100644 test/actual_comparators/latest/light-controller/package.json create mode 100644 test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts create mode 100644 test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts create mode 100644 test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts create mode 100644 test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts create mode 100644 test/actual_comparators/latest/light-controller/src/channels/utils.ts create mode 100644 test/actual_comparators/latest/light-controller/src/hooks.ts create mode 100644 test/actual_comparators/latest/light-controller/src/index.ts create mode 100644 test/actual_comparators/latest/light-controller/src/messages/dimLight.ts create mode 100644 test/actual_comparators/latest/light-controller/src/messages/dimLightResponse.ts create mode 100644 test/actual_comparators/latest/light-controller/src/messages/lightMeasured.ts create mode 100644 test/actual_comparators/latest/light-controller/src/messages/turnOnOff.ts create mode 100644 test/actual_comparators/latest/light-controller/src/messages/turnOnOffResponse.ts create mode 100644 test/actual_comparators/latest/light-controller/src/schema/anonymous-schema-4.ts create mode 100644 test/actual_comparators/latest/light-controller/src/schema/anonymous-schema-5.ts create mode 100644 test/actual_comparators/latest/light-controller/src/schema/lightMeasuredPayload.ts create mode 100644 test/actual_comparators/latest/light-controller/src/schema/response.ts create mode 100644 test/actual_comparators/latest/light-controller/src/schema/turnOnOffPayload.ts create mode 100644 test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts create mode 100644 test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts create mode 100644 test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts create mode 100644 test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts create mode 100644 test/actual_comparators/latest/light-controller/src/tests/testclient/index.ts create mode 100644 test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts create mode 100644 test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts create mode 100644 test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts create mode 100644 test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts create mode 100644 test/actual_comparators/latest/light-controller/tsconfig.json rename {tests => test}/docs/0.1.0/components/channel-bindings.yml (100%) rename {tests => test}/docs/0.1.0/components/messages.yml (100%) rename {tests => test}/docs/0.1.0/components/parameters.yml (100%) rename {tests => test}/docs/0.1.0/components/schemas.yml (100%) rename {tests => test}/docs/0.1.0/frontend.yml (100%) rename {tests => test}/docs/0.1.0/light-controller.yml (100%) create mode 100644 test/expected_comparators/latest/frontend/README.md create mode 100644 test/expected_comparators/latest/frontend/package.json create mode 100644 test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts create mode 100644 test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts create mode 100644 test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts create mode 100644 test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts create mode 100644 test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event.ts create mode 100644 test/expected_comparators/latest/frontend/src/channels/utils.ts create mode 100644 test/expected_comparators/latest/frontend/src/hooks.ts create mode 100644 test/expected_comparators/latest/frontend/src/index.ts create mode 100644 test/expected_comparators/latest/frontend/src/messages/dimLight.ts create mode 100644 test/expected_comparators/latest/frontend/src/messages/dimLightResponse.ts create mode 100644 test/expected_comparators/latest/frontend/src/messages/lightMeasured.ts create mode 100644 test/expected_comparators/latest/frontend/src/messages/turnOnOff.ts create mode 100644 test/expected_comparators/latest/frontend/src/messages/turnOnOffResponse.ts create mode 100644 test/expected_comparators/latest/frontend/src/schema/anonymous-schema-4.ts create mode 100644 test/expected_comparators/latest/frontend/src/schema/anonymous-schema-5.ts create mode 100644 test/expected_comparators/latest/frontend/src/schema/lightMeasuredPayload.ts create mode 100644 test/expected_comparators/latest/frontend/src/schema/response.ts create mode 100644 test/expected_comparators/latest/frontend/src/schema/turnOnOffPayload.ts create mode 100644 test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts create mode 100644 test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts create mode 100644 test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts create mode 100644 test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts create mode 100644 test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event.ts create mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/index.ts create mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts create mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts create mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts create mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts create mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event.ts create mode 100644 test/expected_comparators/latest/frontend/tsconfig.json create mode 100644 test/expected_comparators/latest/light-controller/README.md create mode 100644 test/expected_comparators/latest/light-controller/package.json create mode 100644 test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts create mode 100644 test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts create mode 100644 test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts create mode 100644 test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts create mode 100644 test/expected_comparators/latest/light-controller/src/channels/utils.ts create mode 100644 test/expected_comparators/latest/light-controller/src/hooks.ts create mode 100644 test/expected_comparators/latest/light-controller/src/index.ts create mode 100644 test/expected_comparators/latest/light-controller/src/messages/dimLight.ts create mode 100644 test/expected_comparators/latest/light-controller/src/messages/dimLightResponse.ts create mode 100644 test/expected_comparators/latest/light-controller/src/messages/lightMeasured.ts create mode 100644 test/expected_comparators/latest/light-controller/src/messages/turnOnOff.ts create mode 100644 test/expected_comparators/latest/light-controller/src/messages/turnOnOffResponse.ts create mode 100644 test/expected_comparators/latest/light-controller/src/schema/anonymous-schema-4.ts create mode 100644 test/expected_comparators/latest/light-controller/src/schema/anonymous-schema-5.ts create mode 100644 test/expected_comparators/latest/light-controller/src/schema/lightMeasuredPayload.ts create mode 100644 test/expected_comparators/latest/light-controller/src/schema/response.ts create mode 100644 test/expected_comparators/latest/light-controller/src/schema/turnOnOffPayload.ts create mode 100644 test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts create mode 100644 test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts create mode 100644 test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts create mode 100644 test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts create mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/index.ts create mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts create mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts create mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts create mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts create mode 100644 test/expected_comparators/latest/light-controller/tsconfig.json create mode 100644 test/template.js diff --git a/.gitignore b/.gitignore index b512c09d4..b72af8276 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -node_modules \ No newline at end of file +node_modules +tests/actual_comparators \ No newline at end of file diff --git a/README.md b/README.md index d76ab49f3..465bc8beb 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,21 @@ -# Template usage +# Typescript NATS template -## content types +## Template development +* Why use `.sh` files instead of just javascript files for generating the testing scenarios? + +Because of circular dependencies it is not possible to install the generator and then use this template directly. + + + +## Template usage + +### content types For binary payloads use: `binary` content type For json payloads use: `json` content type For string payloads use: `string` content type -## Hooks +### Hooks Use the hooks to control the flow of information outside the generated code. diff --git a/package-lock.json b/package-lock.json index e26efdc60..7a7016f30 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,11 +4,343 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "buffer-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chokidar": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "dir-compare": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-2.2.0.tgz", + "integrity": "sha512-cmOgS23lSolrsdrDSwWdu/USalfXEwQ/4r3MyIur2U/td2pIp8TnO71ME4M8siaE49xg43tIVX3XzriDOgfdow==", + "dev": true, + "requires": { + "buffer-equal": "1.0.0", + "colors": "1.0.3", + "commander": "2.9.0", + "minimatch": "3.0.2" + }, + "dependencies": { + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "requires": { + "graceful-readlink": ">= 1.0.0" + } + }, + "minimatch": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz", + "integrity": "sha1-DzmKcwDqRB6cNIyD2Yq4ydv5xAo=", + "dev": true, + "requires": { + "brace-expansion": "^1.0.0" + } + } + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, "filename-reserved-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", @@ -24,11 +356,529 @@ "trim-repeated": "^1.0.0" } }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", + "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mocha": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.1.tgz", + "integrity": "sha512-3qQsu3ijNS3GkWcccT5Zw0hf/rWvu1fTN9sPvEd81hlwsr30GX2GcDSSoBxo24IR8FelmrAydGC6/1J5QQP4WA==", + "dev": true, + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "chokidar": "3.3.0", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "3.0.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.3", + "ms": "2.1.1", + "node-environment-flags": "1.0.6", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "readdirp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "dev": true, + "requires": { + "picomatch": "^2.0.4" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.0.tgz", + "integrity": "sha512-EEJnGqa/xNfIg05SxiPSqRS7S9qwDhYts1TSLR1BQfYUfPe1stofgGKvwERK9+9yf+PpfBMlpBaCHucXGPQfUA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimleft": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", + "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimstart": "^1.0.0" + } + }, + "string.prototype.trimright": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", + "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimend": "^1.0.0" + } + }, + "string.prototype.trimstart": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.0.tgz", + "integrity": "sha512-iCP8g01NFYiiBOnwG1Xc3WZLyoo+RuBymwIlWncShXDDJYWN6DbnM3odslBJdgCdRlq94B5s63NWAZlcn2CS4w==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, "strip-outer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", @@ -37,6 +887,24 @@ "escape-string-regexp": "^1.0.2" } }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "trim-repeated": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", @@ -44,6 +912,154 @@ "requires": { "escape-string-regexp": "^1.0.2" } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + } } } } diff --git a/package.json b/package.json index 1ee8fb7fd..d0a8b7e83 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,19 @@ "nats", "template" ], + "scripts": { + "test": "mocha", + "gen": "node ./generatorComparators" + }, "author": "Jonas Lagoni (jonas-lt@live.dk)", "license": "Apache-2.0", "dependencies": { "filenamify": "^4.1.0", "lodash": "^4.17.15" + }, + "devDependencies": { + "chai": "^4.2.0", + "dir-compare": "^2.2.0", + "mocha": "^7.1.1" } } diff --git a/scripts/generate_new_actual_comparators.sh b/scripts/generate_new_actual_comparators.sh new file mode 100644 index 000000000..82733baa7 --- /dev/null +++ b/scripts/generate_new_actual_comparators.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -x +unameOut="$(uname -s)" +case "${unameOut}" in + Linux*) machine="Linux";; + Darwin*) machine="Mac";; + CYGWIN*) machine="Cygwin";; + MINGW*) machine="MinGw";; + *) machine="UNKNOWN:${unameOut}" +esac +currentDir=${PWD} +echo ${machine} +if [ $machine == "MinGw" ]; then + # Convert /c/ to C:/ + currentDir="${currentDir:1:1}:" + currentDir="${currentDir^}" + currentDir="${currentDir}${PWD:2}" +fi + +docker run --rm -it \ + -v ${currentDir}/tests/docs/0.1.0/frontend.yml:/app/asyncapi.yml \ + -v ${currentDir}/tests/docs/0.1.0/components:/app/components \ + -v ${currentDir}/tests/actual_comparators/latest/frontend:/app/output \ + -v ${currentDir}:/app/template \ + asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --force-write --install + +docker run --rm -it \ + -v ${currentDir}/tests/docs/0.1.0/light-controller.yml:/app/asyncapi.yml \ + -v ${currentDir}/tests/docs/0.1.0/components:/app/components \ + -v ${currentDir}/tests/actual_comparators/latest/light-controller:/app/output \ + -v ${currentDir}:/app/template \ + asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --force-write --install + diff --git a/scripts/generate_new_expected_comparators.sh b/scripts/generate_new_expected_comparators.sh new file mode 100644 index 000000000..3b6adc9b0 --- /dev/null +++ b/scripts/generate_new_expected_comparators.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -x +unameOut="$(uname -s)" +case "${unameOut}" in + Linux*) machine="Linux";; + Darwin*) machine="Mac";; + CYGWIN*) machine="Cygwin";; + MINGW*) machine="MinGw";; + *) machine="UNKNOWN:${unameOut}" +esac +currentDir=${PWD} +echo ${machine} +if [ $machine == "MinGw" ]; then + # Convert /c/ to C:/ + currentDir="${currentDir:1:1}:" + currentDir="${currentDir^}" + currentDir="${currentDir}${PWD:2}" +fi + +docker run --rm -it \ + -v ${currentDir}/tests/docs/0.1.0/frontend.yml:/app/asyncapi.yml \ + -v ${currentDir}/tests/docs/0.1.0/components:/app/components \ + -v ${currentDir}/tests/expected_comparators/latest/frontend:/app/output \ + -v ${currentDir}:/app/template \ + asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --force-write --install + +docker run --rm -it \ + -v ${currentDir}/tests/docs/0.1.0/light-controller.yml:/app/asyncapi.yml \ + -v ${currentDir}/tests/docs/0.1.0/components:/app/components \ + -v ${currentDir}/tests/expected_comparators/latest/light-controller:/app/output \ + -v ${currentDir}:/app/template \ + asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --force-write --install + diff --git a/template/src/channels/$$channel$$.ts.njk b/template/src/channels/$$channel$$.ts.njk index c8fafea95..c2de8b52b 100644 --- a/template/src/channels/$$channel$$.ts.njk +++ b/template/src/channels/$$channel$$.ts.njk @@ -1,8 +1,8 @@ -{%- from "../../../partials/channel/publish.njk" import publish %} -{%- from "../../../partials/channel/reply.njk" import reply %} -{%- from "../../../partials/channel/request.njk" import request %} -{%- from "../../../partials/channel/subscribe.njk" import subscribe %} +{%- from "../../../partials/channel/Publish.njk" import publish %} +{%- from "../../../partials/channel/Reply.njk" import reply %} +{%- from "../../../partials/channel/Request.njk" import request %} +{%- from "../../../partials/channel/Subscribe.njk" import subscribe %} {%- if channel.hasPublish() %} import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '../messages/{{ channel.publish().message(0).uid() | pascalCase}}' {%- endif %} diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index bc56b48b6..29dc89030 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -1,8 +1,8 @@ -{%- from "../../partials/index/publish.njk" import publish %} -{%- from "../../partials/index/reply.njk" import reply %} -{%- from "../../partials/index/request.njk" import request %} -{%- from "../../partials/index/subscribe.njk" import subscribe %} +{%- from "../../partials/index/Publish.njk" import publish %} +{%- from "../../partials/index/Reply.njk" import reply %} +{%- from "../../partials/index/Request.njk" import request %} +{%- from "../../partials/index/Subscribe.njk" import subscribe %} import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; diff --git a/template/src/test/testclient/index.ts.njk b/template/src/test/testclient/index.ts.njk deleted file mode 100644 index f8b0545a4..000000000 --- a/template/src/test/testclient/index.ts.njk +++ /dev/null @@ -1,70 +0,0 @@ - -{%- from "../../../.partials/index/publish.njk" import publish %} -{%- from "../../../.partials/index/reply.njk" import reply %} -{%- from "../../../.partials/index/request.njk" import request %} -{%- from "../../../.partials/index/subscribe.njk" import subscribe %} - -import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; - -{%- for channelName, channel in asyncapi.channels() %} -import * as {{ channelName | camelCase }}Channel from "./testchannels/{{ channelName | firstUpperCase }}"; -{%- endfor %} - -{%- for messageName, message in asyncapi.allMessages() %} -import {default as {{ messageName | pascalCase }}Message} from "../../messages/{{ messageName | pascalCase }}"; -{%- endfor %} - -export default class NatsAsyncApiClient { - public nc?: Client; - public options: NatsConnectionOptions; - constructor(options : NatsConnectionOptions) { - options = this.setDefaultOptions(options); - this.options = options; - this.connect(options); - } - - /** - * Try to connect to the NATS server. - * @param options The connection options for NATS - */ - private async connect(options : NatsConnectionOptions){ - try{ - this.nc = await connect(options); - }catch(e){ - console.error("Could not connect to NATS: " + e) - } - } - - /** - * Set the default options from the AsyncAPI file. - * @param options The options to set - */ - private setDefaultOptions(options: NatsConnectionOptions){ - //If server binding options sat set the options - options.encoding = 'utf8'; - options.payload = Payload.BINARY; - return options; - } - - {%- for channelName, channel in asyncapi.channels() %} - - {%- if channel | isRequestReply %} - {%- if channel | isRequester %} - {{reply(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel)}} - {%- endif %} - {%- if channel | isReplier %} - {{request(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel)}} - {%- endif %} - {%- endif %} - - {%- if channel | isPubsub %} - {%- if channel.hasSubscribe() %} - {{publish(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel)}} - {%- endif %} - {%- if channel.hasPublish() %} - {{subscribe(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel)}} - {%- endif %} - {%- endif %} - - {%- endfor %} -} diff --git a/template/src/tests/$$channel$$.ts b/template/src/tests/$$channel$$.ts new file mode 100644 index 000000000..e69de29bb diff --git a/template/src/tests/schemas/$$schema$$.spec.ts b/template/src/tests/schemas/$$schema$$.spec.ts new file mode 100644 index 000000000..b529dce2a --- /dev/null +++ b/template/src/tests/schemas/$$schema$$.spec.ts @@ -0,0 +1,9 @@ +import { expect } from 'chai'; +import 'mocha'; + +describe('First test', () => { + it('should return true', () => { + const result = helloTest(); + expect(result).to.equal(true); + }); +}); \ No newline at end of file diff --git a/template/src/tests/testclient/index.ts.njk b/template/src/tests/testclient/index.ts.njk new file mode 100644 index 000000000..b63286917 --- /dev/null +++ b/template/src/tests/testclient/index.ts.njk @@ -0,0 +1,27 @@ + +{%- from "../../../../partials/index/Publish.njk" import publish %} +{%- from "../../../../partials/index/Reply.njk" import reply %} +{%- from "../../../../partials/index/Request.njk" import request %} +{%- from "../../../../partials/index/Subscribe.njk" import subscribe %} + + {%- for channelName, channel in asyncapi.channels() %} + + {%- if channel | isRequestReply %} + {%- if channel | isRequester %} + {{reply(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel)}} + {%- endif %} + {%- if channel | isReplier %} + {{request(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel)}} + {%- endif %} + {%- endif %} + + {%- if channel | isPubsub %} + {%- if channel.hasSubscribe() %} + {{publish(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel)}} + {%- endif %} + {%- if channel.hasPublish() %} + {{subscribe(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel)}} + {%- endif %} + {%- endif %} + + {%- endfor %} diff --git a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk index 179abf81f..866b107a3 100644 --- a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk +++ b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk @@ -1,8 +1,8 @@ -{%- from "../../../../../partials/channel/publish.njk" import publish %} -{%- from "../../../../../partials/channel/reply.njk" import reply %} -{%- from "../../../../../partials/channel/request.njk" import request %} -{%- from "../../../../../partials/channel/subscribe.njk" import subscribe %} +{%- from "../../../../../partials/channel/Publish.njk" import publish %} +{%- from "../../../../../partials/channel/Reply.njk" import reply %} +{%- from "../../../../../partials/channel/Request.njk" import request %} +{%- from "../../../../../partials/channel/Subscribe.njk" import subscribe %} {%- if channel.hasPublish() %} import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '../../../messages/{{ channel.publish().message(0).uid() | pascalCase}}' {%- endif %} diff --git a/test/actual_comparators/latest/frontend/README.md b/test/actual_comparators/latest/frontend/README.md new file mode 100644 index 000000000..fb373e91a --- /dev/null +++ b/test/actual_comparators/latest/frontend/README.md @@ -0,0 +1,17 @@ +# Streetlights Nats API for the frontend + +The Smartylighting Streetlights API allows you to remotely manage the city lights. + +This is for the frontend where the lights can be controlled, which assumed are multiple instances to ensure availability. + +### Check out its awesome features: + +* Turn a specific streetlight on/off 🌃 +* Dim a specific streetlight 😎 +* Receive real-time information about environmental lighting conditions 📈 + + + + +Available nats encodings: +https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings diff --git a/test/actual_comparators/latest/frontend/package.json b/test/actual_comparators/latest/frontend/package.json new file mode 100644 index 000000000..dfe709a71 --- /dev/null +++ b/test/actual_comparators/latest/frontend/package.json @@ -0,0 +1,45 @@ +{ + + + + "name": "streetlights-nats-api-for-the-frontend", + "description": "The Smartylighting Streetlights API allows you to remotely manage the city lights. This is for the frontend where the lights can be controlled, which assumed are multiple instances to ensure availability. ### Check out its awesome features: * Turn a specific streetlight on/off 🌃 * Dim a specific streetlight 😎 * Receive real-time information about environmental lighting conditions 📈 ", + "version": "1.0.0", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "watch": "tsc --watch", + "build": "tsc", + "start": "node src/api/index.js", + "postinstall": "link-module-alias", + "test": "mocha -r ts-node/register tests/\*\*/\*.spec.ts" + }, + "_moduleAliasIgnoreWarning": true, + "_moduleAliases": { + "#messages": "./src/messages", + "#schemas": "./src/schema", + "#channels": "./src/channels", + "#hooks": "./src/hooks" + }, + "dependencies": { + "@types/klaw-sync": "^6.0.0", + "@types/uuid": "3.4.5", + "@types/node": "13.9.5", + "klaw-sync": "6.0.0", + "link-module-alias": "^1.2.0", + "msgpack-lite": "^0.1.26", + "ts-nats": "1.2.4", + "node-yaml-config": "0.0.5", + "typescript": "3.4.3", + "uuid": "3.3.3", + "winston": "3.2.1", + "winston-daily-rotate-file": "3.10.0" + }, + "devDependencies": { + "@types/chai": "^4.2.11", + "@types/mocha": "^7.0.2", + "chai": "^4.2.0", + "mocha": "^7.1.1", + "ts-node": "^8.8.1" + } +} diff --git a/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts new file mode 100644 index 000000000..1361c0da6 --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts @@ -0,0 +1,46 @@ + +import {default as DimLightMessage} from '../messages/DimLight' +import {default as DimLightResponseMessage} from '../messages/DimLightResponse' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + +export function request( + requestMessage: DimLightMessage, + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + resolve(DimLightResponseMessage.toMessage(processedData)); + } + }, { max: 1 }); + let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var requestData; + for(let hook in publishDataHooks){ + requestData = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/dim', { + + "streetlightId": streetlightId + + }), requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts new file mode 100644 index 000000000..4f3a2dd9d --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts @@ -0,0 +1,46 @@ + +import {default as TurnOnOffMessage} from '../messages/TurnOnOff' +import {default as TurnOnOffResponseMessage} from '../messages/TurnOnOffResponse' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + +export function request( + requestMessage: TurnOnOffMessage, + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + resolve(TurnOnOffResponseMessage.toMessage(processedData)); + } + }, { max: 1 }); + let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var requestData; + for(let hook in publishDataHooks){ + requestData = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/off', { + + "streetlightId": streetlightId + + }), requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts new file mode 100644 index 000000000..4ca6a3341 --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts @@ -0,0 +1,46 @@ + +import {default as TurnOnOffMessage} from '../messages/TurnOnOff' +import {default as TurnOnOffResponseMessage} from '../messages/TurnOnOffResponse' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + +export function request( + requestMessage: TurnOnOffMessage, + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + resolve(TurnOnOffResponseMessage.toMessage(processedData)); + } + }, { max: 1 }); + let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var requestData; + for(let hook in publishDataHooks){ + requestData = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/on', { + + "streetlightId": streetlightId + + }), requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts new file mode 100644 index 000000000..81100c80c --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts @@ -0,0 +1,44 @@ + +import {default as LightMeasuredMessage} from '../messages/LightMeasured' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + + +import {getHooks, AvailableHooks} from '#hooks'; +export function subscribe( + onDataCallback : (err?: NatsError, msg?: lightMeasured) => void, + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured', { + + "streetlightId": streetlightId + + }), (err, msg) => { + if(err){ + onDataCallback(err); + }else{ + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let publishedData = new lightMeasured(); + publishedData.copyFrom(processedData); + onDataCallback(undefined, publishedData); + } + }, subscribeOptions); + resolve(subscription); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event.ts b/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event.ts new file mode 100644 index 000000000..89313c1f9 --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event.ts @@ -0,0 +1,40 @@ + +import {default as LightMeasuredMessage} from '../messages/LightMeasured' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + + +import {getHooks, AvailableHooks} from '#hooks'; +export function subscribe( + onDataCallback : (err?: NatsError, msg?: lightMeasured) => void, + + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/event/*', { + + }), (err, msg) => { + if(err){ + onDataCallback(err); + }else{ + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let publishedData = new lightMeasured(); + publishedData.copyFrom(processedData); + onDataCallback(undefined, publishedData); + } + }, subscribeOptions); + resolve(subscription); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/actual_comparators/latest/frontend/src/channels/utils.ts b/test/actual_comparators/latest/frontend/src/channels/utils.ts new file mode 100644 index 000000000..8810b700d --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/channels/utils.ts @@ -0,0 +1,11 @@ +export function realizeChannelName(channelName: string, parameters: any) { + let returnString = channelName; + returnString = returnString.replace('/', '.'); + for (let parameterName in parameters) { + returnString = returnString.replace( + `{${parameterName}}`, + parameters[parameterName] + ); + } + return returnString; +} diff --git a/test/actual_comparators/latest/frontend/src/hooks.ts b/test/actual_comparators/latest/frontend/src/hooks.ts new file mode 100644 index 000000000..7dfcbfbd9 --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/hooks.ts @@ -0,0 +1,63 @@ +const HOOKS_DIRNAME = './hooks'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as walkSync from 'klaw-sync'; +export enum AvailableHooks { + RecievedData = 'RecievedData', + BeforeSendingData = 'BeforeSendingData' +} +export type RecievedDataHook = () => void; +export type BeforeSendingDataHook = (messageToSend: any) => void; +export var hooks: { + BeforeSendingData: BeforeSendingDataHook[]; + RecievedData: RecievedDataHook[]; +}; + +/** + * Loads the custom hooks. + */ +try { + const hooksPath = path.resolve(HOOKS_DIRNAME); + if (fs.existsSync(hooksPath)) { + const files = walkSync(hooksPath, { nodir: true }); + files.forEach((file: any) => { + require(file.path)((when: AvailableHooks, hook: any) => { + hooks[when].push(hook); + }); + }); + } +} catch (e) { + e.message = `There was a problem registering the hooks: ${e.message}`; + throw e; +} + +/** + * Register a hook for BeforeSendingData + * @param hook + */ +export async function registerBeforeSendingData(hook: BeforeSendingDataHook) { + hooks[AvailableHooks.BeforeSendingData] + ? hooks[AvailableHooks.BeforeSendingData].push(hook) + : [hook]; +} + +/** + * Register a hook for BeforeSendingData + * @param hook + */ +export async function registerRecievedData(hook: RecievedDataHook) { + hooks[AvailableHooks.RecievedData] + ? hooks[AvailableHooks.RecievedData].push(hook) + : [hook]; +} + +/** + * Get all the hooks registered at a given hook point/name. + * @param hook to find hooks for + * @returns all hooks + */ +export function getHooks(hook: AvailableHooks): Function[] { + if (!Array.isArray(hooks[hook])) return []; + // Return valid hooks + return hooks[hook]; +} diff --git a/test/actual_comparators/latest/frontend/src/index.ts b/test/actual_comparators/latest/frontend/src/index.ts new file mode 100644 index 000000000..8573d5b42 --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/index.ts @@ -0,0 +1,101 @@ + + +import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; +import * as smartylightingStreetlights10EventChannel from "./channels/Smartylighting/streetlights/1/0/event/*"; +import * as smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel from "./channels/Smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured"; +import * as smartylightingStreetlights10ActionStreetlightIdTurnOnChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/turn/on"; +import * as smartylightingStreetlights10ActionStreetlightIdTurnOffChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/turn/off"; +import * as smartylightingStreetlights10ActionStreetlightIdDimChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/dim"; +import {default as LightMeasuredMessage} from "./messages/LightMeasured"; +import {default as TurnOnOffMessage} from "./messages/TurnOnOff"; +import {default as TurnOnOffResponseMessage} from "./messages/TurnOnOffResponse"; +import {default as DimLightMessage} from "./messages/DimLight"; +import {default as DimLightResponseMessage} from "./messages/DimLightResponse"; + +export default class NatsAsyncApiClient { + public jsonClient?: Client; + public stringClient?: Client; + public binaryClient?: Client; + public options: NatsConnectionOptions; + + /** + * + * @param options options to use, payload is omitted if sat in the AsyncAPI document. + */ + constructor(options : NatsConnectionOptions) { + this.options = this.setDefaultOptions(options); + this.connect(); + } + + /** + * Try to connect to the NATS server with the different payloads. + */ + private async connect(){ + try{ + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + }catch(e){ + console.error("Could not connect to NATS: " + e) + } + } + + /** + * Set the default options based on the AsyncAPI file. + * @param options to set + */ + private setDefaultOptions(options: NatsConnectionOptions){ + //If server binding options sat set the options + options.encoding = 'utf8'; + return options; + } + + /** + * Topic for which one can subscribe to all measurements regardless of id. + * @param onDataCallback Called when message recieved. + */ + public subscribeToSmartylightingStreetlights10Event(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10EventChannel.subscribe(onDataCallback, nc); + } + + + /** + * Topic for which one can subscribe to measurements on a specific streetlightId. + * @param onDataCallback Called when message recieved. + */ + public subscribeToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.subscribe(onDataCallback, nc); + } + + + /** + * + * @param requestMessage The request message to send. + */ + public requestSmartylightingStreetlights10ActionStreetlightIdTurnOn(requestMessage: TurnOnOffMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.request(requestMessage, nc); + } + + + /** + * + * @param requestMessage The request message to send. + */ + public requestSmartylightingStreetlights10ActionStreetlightIdTurnOff(requestMessage: TurnOnOffMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.request(requestMessage, nc); + } + + + /** + * + * @param requestMessage The request message to send. + */ + public requestSmartylightingStreetlights10ActionStreetlightIdDim(requestMessage: DimLightMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdDimChannel.request(requestMessage, nc); + } + +} diff --git a/test/actual_comparators/latest/frontend/src/messages/dimLight.ts b/test/actual_comparators/latest/frontend/src/messages/dimLight.ts new file mode 100644 index 000000000..7a8281027 --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/messages/dimLight.ts @@ -0,0 +1,45 @@ + + + + +import { default as DimLightPayloadserereSchema } from '../schema/DimLightPayloadserere'; + + + +import { default as ResponseSchema } from '../schema/Response'; + + +export default class DimLight { + + + + dimLightPayloadserere:DimLightPayloadserereSchema; + + + + response:ResponseSchema; + + + constructor( + dimLightPayloadserere: DimLightPayloadserereSchema,response: ResponseSchema + ){ + + + + this.dimLightPayloadserere = dimLightPayloadserere; + + + + this.response = response; + + } + + /** + * Parses a JSON string to an object of DimLight message class. + * @param json string to be parsed as DimLight. + */ + public static toMessage(json: string): DimLight { + return JSON.parse(json); + } + +} diff --git a/test/actual_comparators/latest/frontend/src/messages/dimLightResponse.ts b/test/actual_comparators/latest/frontend/src/messages/dimLightResponse.ts new file mode 100644 index 000000000..2e0d9da0e --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/messages/dimLightResponse.ts @@ -0,0 +1,30 @@ + + + +import { default as ResponseSchema } from '../schema/Response'; + + +export default class DimLightResponse { + + + response:ResponseSchema; + + + constructor( + response: ResponseSchema + ){ + + + this.response = response; + + } + + /** + * Parses a JSON string to an object of DimLightResponse message class. + * @param json string to be parsed as DimLightResponse. + */ + public static toMessage(json: string): DimLightResponse { + return JSON.parse(json); + } + +} diff --git a/test/actual_comparators/latest/frontend/src/messages/lightMeasured.ts b/test/actual_comparators/latest/frontend/src/messages/lightMeasured.ts new file mode 100644 index 000000000..9e2010e22 --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/messages/lightMeasured.ts @@ -0,0 +1,30 @@ + + + +import { default as LightMeasuredPayloadSchema } from '../schema/LightMeasuredPayload'; + + +export default class LightMeasured { + + + lightMeasuredPayload:LightMeasuredPayloadSchema; + + + constructor( + lightMeasuredPayload: LightMeasuredPayloadSchema + ){ + + + this.lightMeasuredPayload = lightMeasuredPayload; + + } + + /** + * Parses a JSON string to an object of LightMeasured message class. + * @param json string to be parsed as LightMeasured. + */ + public static toMessage(json: string): LightMeasured { + return JSON.parse(json); + } + +} diff --git a/test/actual_comparators/latest/frontend/src/messages/turnOnOff.ts b/test/actual_comparators/latest/frontend/src/messages/turnOnOff.ts new file mode 100644 index 000000000..483922274 --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/messages/turnOnOff.ts @@ -0,0 +1,30 @@ + + + +import { default as TurnOnOffPayloadSchema } from '../schema/TurnOnOffPayload'; + + +export default class TurnOnOff { + + + turnOnOffPayload:TurnOnOffPayloadSchema; + + + constructor( + turnOnOffPayload: TurnOnOffPayloadSchema + ){ + + + this.turnOnOffPayload = turnOnOffPayload; + + } + + /** + * Parses a JSON string to an object of TurnOnOff message class. + * @param json string to be parsed as TurnOnOff. + */ + public static toMessage(json: string): TurnOnOff { + return JSON.parse(json); + } + +} diff --git a/test/actual_comparators/latest/frontend/src/messages/turnOnOffResponse.ts b/test/actual_comparators/latest/frontend/src/messages/turnOnOffResponse.ts new file mode 100644 index 000000000..c25f1a5c5 --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/messages/turnOnOffResponse.ts @@ -0,0 +1,30 @@ + + + +import { default as ResponseSchema } from '../schema/Response'; + + +export default class TurnOnOffResponse { + + + response:ResponseSchema; + + + constructor( + response: ResponseSchema + ){ + + + this.response = response; + + } + + /** + * Parses a JSON string to an object of TurnOnOffResponse message class. + * @param json string to be parsed as TurnOnOffResponse. + */ + public static toMessage(json: string): TurnOnOffResponse { + return JSON.parse(json); + } + +} diff --git a/test/actual_comparators/latest/frontend/src/schema/anonymous-schema-4.ts b/test/actual_comparators/latest/frontend/src/schema/anonymous-schema-4.ts new file mode 100644 index 000000000..ef2cd616f --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/schema/anonymous-schema-4.ts @@ -0,0 +1,11 @@ + + + + +export default class anonymousSchema4 { + + + + + +} diff --git a/test/actual_comparators/latest/frontend/src/schema/anonymous-schema-5.ts b/test/actual_comparators/latest/frontend/src/schema/anonymous-schema-5.ts new file mode 100644 index 000000000..e11ccc78d --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/schema/anonymous-schema-5.ts @@ -0,0 +1,22 @@ + + + + +export default class anonymousSchema5 { + + + + percentage?: Number + sentAt?: string + + + + status?: Number + statusMessage?: string + sentAt?: string + + + + + +} diff --git a/test/actual_comparators/latest/frontend/src/schema/lightMeasuredPayload.ts b/test/actual_comparators/latest/frontend/src/schema/lightMeasuredPayload.ts new file mode 100644 index 000000000..a783f2728 --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/schema/lightMeasuredPayload.ts @@ -0,0 +1,13 @@ + + + + +export default class lightMeasuredPayload { + + + lumens?: Number + sentAt?: string + + + +} diff --git a/test/actual_comparators/latest/frontend/src/schema/response.ts b/test/actual_comparators/latest/frontend/src/schema/response.ts new file mode 100644 index 000000000..0c80740f4 --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/schema/response.ts @@ -0,0 +1,14 @@ + + + + +export default class response { + + + status?: Number + statusMessage?: string + sentAt?: string + + + +} diff --git a/test/actual_comparators/latest/frontend/src/schema/turnOnOffPayload.ts b/test/actual_comparators/latest/frontend/src/schema/turnOnOffPayload.ts new file mode 100644 index 000000000..c9ea846aa --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/schema/turnOnOffPayload.ts @@ -0,0 +1,13 @@ + + + + +export default class turnOnOffPayload { + + + command?: string + sentAt?: string + + + +} diff --git a/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event.ts b/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/actual_comparators/latest/frontend/src/tests/testclient/index.ts b/test/actual_comparators/latest/frontend/src/tests/testclient/index.ts new file mode 100644 index 000000000..ecde61413 --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/tests/testclient/index.ts @@ -0,0 +1,54 @@ + + + /** + * [object Object] + * @param requestMessage The message to publish. + */ + public publishToSmartylightingStreetlights10Event(requestMessage: LightMeasuredMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10EventChannel.publish(requestMessage, nc); + } + + + /** + * [object Object] + * @param requestMessage The message to publish. + */ + public publishToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(requestMessage: LightMeasuredMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.publish(requestMessage, nc); + } + + + /** + * [object Object] + * @param onRequest Called when request recieved. + * @param onReplyError Called when it was not possible to send the reply. + */ + public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOn(onRequest : (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, onReplyError : (err: NatsError) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.reply(onRequest, onReplyError, nc); + } + + + /** + * [object Object] + * @param onRequest Called when request recieved. + * @param onReplyError Called when it was not possible to send the reply. + */ + public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOff(onRequest : (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, onReplyError : (err: NatsError) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.reply(onRequest, onReplyError, nc); + } + + + /** + * [object Object] + * @param onRequest Called when request recieved. + * @param onReplyError Called when it was not possible to send the reply. + */ + public replyToSmartylightingStreetlights10ActionStreetlightIdDim(onRequest : (err?: NatsError, msg?: DimLightMessage) => DimLightResponseMessage, onReplyError : (err: NatsError) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdDimChannel.reply(onRequest, onReplyError, nc); + } + diff --git a/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts new file mode 100644 index 000000000..f0c9801c9 --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts @@ -0,0 +1,66 @@ + +import {default as DimLightMessage} from '../../../messages/DimLight' +import {default as DimLightResponseMessage} from '../../../messages/DimLightResponse' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + +export function reply( + onRequest: (err?: NatsError, msg?: DimLightMessage) => DimLightResponseMessage, + onReplyError: (err: NatsError) => void, + , + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/dim', { + + "streetlightId": streetlightId + + }), (err, msg) => { + if (err) { + onRequest(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let requestData = new DimLightMessage(); + requestData.copyFrom(processedData); + + let responseObject = onRequest(undefined, requestData); + if (msg.reply) { + try { + let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); + nc.publish(msg.reply, requestData); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + console.error(error) + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts new file mode 100644 index 000000000..4393e85e3 --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts @@ -0,0 +1,66 @@ + +import {default as TurnOnOffMessage} from '../../../messages/TurnOnOff' +import {default as TurnOnOffResponseMessage} from '../../../messages/TurnOnOffResponse' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + +export function reply( + onRequest: (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, + onReplyError: (err: NatsError) => void, + , + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/off', { + + "streetlightId": streetlightId + + }), (err, msg) => { + if (err) { + onRequest(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let requestData = new TurnOnOffMessage(); + requestData.copyFrom(processedData); + + let responseObject = onRequest(undefined, requestData); + if (msg.reply) { + try { + let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); + nc.publish(msg.reply, requestData); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + console.error(error) + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts new file mode 100644 index 000000000..366873ed1 --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts @@ -0,0 +1,66 @@ + +import {default as TurnOnOffMessage} from '../../../messages/TurnOnOff' +import {default as TurnOnOffResponseMessage} from '../../../messages/TurnOnOffResponse' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + +export function reply( + onRequest: (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, + onReplyError: (err: NatsError) => void, + , + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/on', { + + "streetlightId": streetlightId + + }), (err, msg) => { + if (err) { + onRequest(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let requestData = new TurnOnOffMessage(); + requestData.copyFrom(processedData); + + let responseObject = onRequest(undefined, requestData); + if (msg.reply) { + try { + let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); + nc.publish(msg.reply, requestData); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + console.error(error) + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts new file mode 100644 index 000000000..dba07ac3e --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts @@ -0,0 +1,37 @@ + +import {default as LightMeasuredMessage} from '../../../messages/LightMeasured' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + + +export function publish( + requestMessage: LightMeasuredMessage, + + streetlightId:string + , + nc?: Client + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var dataToPublish; + for(let hook in publishDataHooks){ + dataToPublish = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured', { + + "streetlightId": streetlightId + + }), dataToPublish); + resolve(); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }); +}; + diff --git a/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event.ts b/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event.ts new file mode 100644 index 000000000..937d72bdb --- /dev/null +++ b/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event.ts @@ -0,0 +1,33 @@ + +import {default as LightMeasuredMessage} from '../../../messages/LightMeasured' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + + +export function publish( + requestMessage: LightMeasuredMessage, + + nc?: Client + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var dataToPublish; + for(let hook in publishDataHooks){ + dataToPublish = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/event/*', { + + }), dataToPublish); + resolve(); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }); +}; + diff --git a/test/actual_comparators/latest/frontend/tsconfig.json b/test/actual_comparators/latest/frontend/tsconfig.json new file mode 100644 index 000000000..9fb047824 --- /dev/null +++ b/test/actual_comparators/latest/frontend/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "declaration": true, + "strict": true, + "noImplicitAny": true, + "removeComments": true, + "preserveConstEnums": true, + "sourceMap": true, + "outDir": "dist/", + "baseUrl": "./src" /* Base directory to resolve non-absolute module names. */, + "paths": { + "#messages": ["messages"], + "#schemas": ["schema"], + "#channels": ["channels"], + "#hooks": ["hooks"] + } + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "**/*.spec.ts"] +} diff --git a/test/actual_comparators/latest/light-controller/README.md b/test/actual_comparators/latest/light-controller/README.md new file mode 100644 index 000000000..7d8ed191e --- /dev/null +++ b/test/actual_comparators/latest/light-controller/README.md @@ -0,0 +1,17 @@ +# Streetlights Nats API for lightning controllers + +The Smartylighting Streetlights API allows you to remotely manage the city lights. + +This is for the lighting controllers, which assumed are multiple instances to ensure availability. + +### Check out its awesome features: + +* Turn a specific streetlight on/off 🌃 +* Dim a specific streetlight 😎 +* Receive real-time information about environmental lighting conditions 📈 + + + + +Available nats encodings: +https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings diff --git a/test/actual_comparators/latest/light-controller/package.json b/test/actual_comparators/latest/light-controller/package.json new file mode 100644 index 000000000..7f9bc65a6 --- /dev/null +++ b/test/actual_comparators/latest/light-controller/package.json @@ -0,0 +1,45 @@ +{ + + + + "name": "streetlights-nats-api-for-lightning-controllers", + "description": "The Smartylighting Streetlights API allows you to remotely manage the city lights. This is for the lighting controllers, which assumed are multiple instances to ensure availability. ### Check out its awesome features: * Turn a specific streetlight on/off 🌃 * Dim a specific streetlight 😎 * Receive real-time information about environmental lighting conditions 📈 ", + "version": "1.0.0", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "watch": "tsc --watch", + "build": "tsc", + "start": "node src/api/index.js", + "postinstall": "link-module-alias", + "test": "mocha -r ts-node/register tests/\*\*/\*.spec.ts" + }, + "_moduleAliasIgnoreWarning": true, + "_moduleAliases": { + "#messages": "./src/messages", + "#schemas": "./src/schema", + "#channels": "./src/channels", + "#hooks": "./src/hooks" + }, + "dependencies": { + "@types/klaw-sync": "^6.0.0", + "@types/uuid": "3.4.5", + "@types/node": "13.9.5", + "klaw-sync": "6.0.0", + "link-module-alias": "^1.2.0", + "msgpack-lite": "^0.1.26", + "ts-nats": "1.2.4", + "node-yaml-config": "0.0.5", + "typescript": "3.4.3", + "uuid": "3.3.3", + "winston": "3.2.1", + "winston-daily-rotate-file": "3.10.0" + }, + "devDependencies": { + "@types/chai": "^4.2.11", + "@types/mocha": "^7.0.2", + "chai": "^4.2.0", + "mocha": "^7.1.1", + "ts-node": "^8.8.1" + } +} diff --git a/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts new file mode 100644 index 000000000..324a21f47 --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts @@ -0,0 +1,66 @@ + +import {default as DimLightResponseMessage} from '../messages/DimLightResponse' +import {default as DimLightMessage} from '../messages/DimLight' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + +export function reply( + onRequest: (err?: NatsError, msg?: DimLightMessage) => DimLightResponseMessage, + onReplyError: (err: NatsError) => void, + , + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/dim', { + + "streetlightId": streetlightId + + }), (err, msg) => { + if (err) { + onRequest(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let requestData = new DimLightMessage(); + requestData.copyFrom(processedData); + + let responseObject = onRequest(undefined, requestData); + if (msg.reply) { + try { + let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); + nc.publish(msg.reply, requestData); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + console.error(error) + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts new file mode 100644 index 000000000..e66e7d710 --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts @@ -0,0 +1,66 @@ + +import {default as TurnOnOffResponseMessage} from '../messages/TurnOnOffResponse' +import {default as TurnOnOffMessage} from '../messages/TurnOnOff' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + +export function reply( + onRequest: (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, + onReplyError: (err: NatsError) => void, + , + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/off', { + + "streetlightId": streetlightId + + }), (err, msg) => { + if (err) { + onRequest(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let requestData = new TurnOnOffMessage(); + requestData.copyFrom(processedData); + + let responseObject = onRequest(undefined, requestData); + if (msg.reply) { + try { + let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); + nc.publish(msg.reply, requestData); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + console.error(error) + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts new file mode 100644 index 000000000..431746c1d --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts @@ -0,0 +1,66 @@ + +import {default as TurnOnOffResponseMessage} from '../messages/TurnOnOffResponse' +import {default as TurnOnOffMessage} from '../messages/TurnOnOff' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + +export function reply( + onRequest: (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, + onReplyError: (err: NatsError) => void, + , + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/on', { + + "streetlightId": streetlightId + + }), (err, msg) => { + if (err) { + onRequest(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let requestData = new TurnOnOffMessage(); + requestData.copyFrom(processedData); + + let responseObject = onRequest(undefined, requestData); + if (msg.reply) { + try { + let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); + nc.publish(msg.reply, requestData); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + console.error(error) + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts new file mode 100644 index 000000000..d106cccbe --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts @@ -0,0 +1,37 @@ + +import {default as LightMeasuredMessage} from '../messages/LightMeasured' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + + +export function publish( + requestMessage: LightMeasuredMessage, + + streetlightId:string + , + nc?: Client + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var dataToPublish; + for(let hook in publishDataHooks){ + dataToPublish = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured', { + + "streetlightId": streetlightId + + }), dataToPublish); + resolve(); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }); +}; + diff --git a/test/actual_comparators/latest/light-controller/src/channels/utils.ts b/test/actual_comparators/latest/light-controller/src/channels/utils.ts new file mode 100644 index 000000000..8810b700d --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/channels/utils.ts @@ -0,0 +1,11 @@ +export function realizeChannelName(channelName: string, parameters: any) { + let returnString = channelName; + returnString = returnString.replace('/', '.'); + for (let parameterName in parameters) { + returnString = returnString.replace( + `{${parameterName}}`, + parameters[parameterName] + ); + } + return returnString; +} diff --git a/test/actual_comparators/latest/light-controller/src/hooks.ts b/test/actual_comparators/latest/light-controller/src/hooks.ts new file mode 100644 index 000000000..7dfcbfbd9 --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/hooks.ts @@ -0,0 +1,63 @@ +const HOOKS_DIRNAME = './hooks'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as walkSync from 'klaw-sync'; +export enum AvailableHooks { + RecievedData = 'RecievedData', + BeforeSendingData = 'BeforeSendingData' +} +export type RecievedDataHook = () => void; +export type BeforeSendingDataHook = (messageToSend: any) => void; +export var hooks: { + BeforeSendingData: BeforeSendingDataHook[]; + RecievedData: RecievedDataHook[]; +}; + +/** + * Loads the custom hooks. + */ +try { + const hooksPath = path.resolve(HOOKS_DIRNAME); + if (fs.existsSync(hooksPath)) { + const files = walkSync(hooksPath, { nodir: true }); + files.forEach((file: any) => { + require(file.path)((when: AvailableHooks, hook: any) => { + hooks[when].push(hook); + }); + }); + } +} catch (e) { + e.message = `There was a problem registering the hooks: ${e.message}`; + throw e; +} + +/** + * Register a hook for BeforeSendingData + * @param hook + */ +export async function registerBeforeSendingData(hook: BeforeSendingDataHook) { + hooks[AvailableHooks.BeforeSendingData] + ? hooks[AvailableHooks.BeforeSendingData].push(hook) + : [hook]; +} + +/** + * Register a hook for BeforeSendingData + * @param hook + */ +export async function registerRecievedData(hook: RecievedDataHook) { + hooks[AvailableHooks.RecievedData] + ? hooks[AvailableHooks.RecievedData].push(hook) + : [hook]; +} + +/** + * Get all the hooks registered at a given hook point/name. + * @param hook to find hooks for + * @returns all hooks + */ +export function getHooks(hook: AvailableHooks): Function[] { + if (!Array.isArray(hooks[hook])) return []; + // Return valid hooks + return hooks[hook]; +} diff --git a/test/actual_comparators/latest/light-controller/src/index.ts b/test/actual_comparators/latest/light-controller/src/index.ts new file mode 100644 index 000000000..380fa3473 --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/index.ts @@ -0,0 +1,93 @@ + + +import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; +import * as smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel from "./channels/Smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured"; +import * as smartylightingStreetlights10ActionStreetlightIdTurnOnChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/turn/on"; +import * as smartylightingStreetlights10ActionStreetlightIdTurnOffChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/turn/off"; +import * as smartylightingStreetlights10ActionStreetlightIdDimChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/dim"; +import {default as LightMeasuredMessage} from "./messages/LightMeasured"; +import {default as TurnOnOffResponseMessage} from "./messages/TurnOnOffResponse"; +import {default as TurnOnOffMessage} from "./messages/TurnOnOff"; +import {default as DimLightResponseMessage} from "./messages/DimLightResponse"; +import {default as DimLightMessage} from "./messages/DimLight"; + +export default class NatsAsyncApiClient { + public jsonClient?: Client; + public stringClient?: Client; + public binaryClient?: Client; + public options: NatsConnectionOptions; + + /** + * + * @param options options to use, payload is omitted if sat in the AsyncAPI document. + */ + constructor(options : NatsConnectionOptions) { + this.options = this.setDefaultOptions(options); + this.connect(); + } + + /** + * Try to connect to the NATS server with the different payloads. + */ + private async connect(){ + try{ + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + }catch(e){ + console.error("Could not connect to NATS: " + e) + } + } + + /** + * Set the default options based on the AsyncAPI file. + * @param options to set + */ + private setDefaultOptions(options: NatsConnectionOptions){ + //If server binding options sat set the options + options.encoding = 'utf8'; + return options; + } + + /** + * Any measured values will be published through this method. + * @param requestMessage The message to publish. + */ + public publishToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(requestMessage: LightMeasuredMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.publish(requestMessage, nc); + } + + + /** + * Get notified when a streetlight should be turned on. This should only be handled by 1 subscriber but ensured by request reply. + * @param onRequest Called when request recieved. + * @param onReplyError Called when it was not possible to send the reply. + */ + public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOn(onRequest : (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, onReplyError : (err: NatsError) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.reply(onRequest, onReplyError, nc); + } + + + /** + * Get notified when a streetlight should be turned off. This should only be handled by 1 subscriber but ensured by request reply. + * @param onRequest Called when request recieved. + * @param onReplyError Called when it was not possible to send the reply. + */ + public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOff(onRequest : (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, onReplyError : (err: NatsError) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.reply(onRequest, onReplyError, nc); + } + + + /** + * Get notified when a streetlight should be dimmed. This should only be handled by 1 subscriber but ensured by request reply. + * @param onRequest Called when request recieved. + * @param onReplyError Called when it was not possible to send the reply. + */ + public replyToSmartylightingStreetlights10ActionStreetlightIdDim(onRequest : (err?: NatsError, msg?: DimLightMessage) => DimLightResponseMessage, onReplyError : (err: NatsError) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdDimChannel.reply(onRequest, onReplyError, nc); + } + +} diff --git a/test/actual_comparators/latest/light-controller/src/messages/dimLight.ts b/test/actual_comparators/latest/light-controller/src/messages/dimLight.ts new file mode 100644 index 000000000..7a8281027 --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/messages/dimLight.ts @@ -0,0 +1,45 @@ + + + + +import { default as DimLightPayloadserereSchema } from '../schema/DimLightPayloadserere'; + + + +import { default as ResponseSchema } from '../schema/Response'; + + +export default class DimLight { + + + + dimLightPayloadserere:DimLightPayloadserereSchema; + + + + response:ResponseSchema; + + + constructor( + dimLightPayloadserere: DimLightPayloadserereSchema,response: ResponseSchema + ){ + + + + this.dimLightPayloadserere = dimLightPayloadserere; + + + + this.response = response; + + } + + /** + * Parses a JSON string to an object of DimLight message class. + * @param json string to be parsed as DimLight. + */ + public static toMessage(json: string): DimLight { + return JSON.parse(json); + } + +} diff --git a/test/actual_comparators/latest/light-controller/src/messages/dimLightResponse.ts b/test/actual_comparators/latest/light-controller/src/messages/dimLightResponse.ts new file mode 100644 index 000000000..2e0d9da0e --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/messages/dimLightResponse.ts @@ -0,0 +1,30 @@ + + + +import { default as ResponseSchema } from '../schema/Response'; + + +export default class DimLightResponse { + + + response:ResponseSchema; + + + constructor( + response: ResponseSchema + ){ + + + this.response = response; + + } + + /** + * Parses a JSON string to an object of DimLightResponse message class. + * @param json string to be parsed as DimLightResponse. + */ + public static toMessage(json: string): DimLightResponse { + return JSON.parse(json); + } + +} diff --git a/test/actual_comparators/latest/light-controller/src/messages/lightMeasured.ts b/test/actual_comparators/latest/light-controller/src/messages/lightMeasured.ts new file mode 100644 index 000000000..9e2010e22 --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/messages/lightMeasured.ts @@ -0,0 +1,30 @@ + + + +import { default as LightMeasuredPayloadSchema } from '../schema/LightMeasuredPayload'; + + +export default class LightMeasured { + + + lightMeasuredPayload:LightMeasuredPayloadSchema; + + + constructor( + lightMeasuredPayload: LightMeasuredPayloadSchema + ){ + + + this.lightMeasuredPayload = lightMeasuredPayload; + + } + + /** + * Parses a JSON string to an object of LightMeasured message class. + * @param json string to be parsed as LightMeasured. + */ + public static toMessage(json: string): LightMeasured { + return JSON.parse(json); + } + +} diff --git a/test/actual_comparators/latest/light-controller/src/messages/turnOnOff.ts b/test/actual_comparators/latest/light-controller/src/messages/turnOnOff.ts new file mode 100644 index 000000000..483922274 --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/messages/turnOnOff.ts @@ -0,0 +1,30 @@ + + + +import { default as TurnOnOffPayloadSchema } from '../schema/TurnOnOffPayload'; + + +export default class TurnOnOff { + + + turnOnOffPayload:TurnOnOffPayloadSchema; + + + constructor( + turnOnOffPayload: TurnOnOffPayloadSchema + ){ + + + this.turnOnOffPayload = turnOnOffPayload; + + } + + /** + * Parses a JSON string to an object of TurnOnOff message class. + * @param json string to be parsed as TurnOnOff. + */ + public static toMessage(json: string): TurnOnOff { + return JSON.parse(json); + } + +} diff --git a/test/actual_comparators/latest/light-controller/src/messages/turnOnOffResponse.ts b/test/actual_comparators/latest/light-controller/src/messages/turnOnOffResponse.ts new file mode 100644 index 000000000..c25f1a5c5 --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/messages/turnOnOffResponse.ts @@ -0,0 +1,30 @@ + + + +import { default as ResponseSchema } from '../schema/Response'; + + +export default class TurnOnOffResponse { + + + response:ResponseSchema; + + + constructor( + response: ResponseSchema + ){ + + + this.response = response; + + } + + /** + * Parses a JSON string to an object of TurnOnOffResponse message class. + * @param json string to be parsed as TurnOnOffResponse. + */ + public static toMessage(json: string): TurnOnOffResponse { + return JSON.parse(json); + } + +} diff --git a/test/actual_comparators/latest/light-controller/src/schema/anonymous-schema-4.ts b/test/actual_comparators/latest/light-controller/src/schema/anonymous-schema-4.ts new file mode 100644 index 000000000..ef2cd616f --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/schema/anonymous-schema-4.ts @@ -0,0 +1,11 @@ + + + + +export default class anonymousSchema4 { + + + + + +} diff --git a/test/actual_comparators/latest/light-controller/src/schema/anonymous-schema-5.ts b/test/actual_comparators/latest/light-controller/src/schema/anonymous-schema-5.ts new file mode 100644 index 000000000..e11ccc78d --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/schema/anonymous-schema-5.ts @@ -0,0 +1,22 @@ + + + + +export default class anonymousSchema5 { + + + + percentage?: Number + sentAt?: string + + + + status?: Number + statusMessage?: string + sentAt?: string + + + + + +} diff --git a/test/actual_comparators/latest/light-controller/src/schema/lightMeasuredPayload.ts b/test/actual_comparators/latest/light-controller/src/schema/lightMeasuredPayload.ts new file mode 100644 index 000000000..a783f2728 --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/schema/lightMeasuredPayload.ts @@ -0,0 +1,13 @@ + + + + +export default class lightMeasuredPayload { + + + lumens?: Number + sentAt?: string + + + +} diff --git a/test/actual_comparators/latest/light-controller/src/schema/response.ts b/test/actual_comparators/latest/light-controller/src/schema/response.ts new file mode 100644 index 000000000..0c80740f4 --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/schema/response.ts @@ -0,0 +1,14 @@ + + + + +export default class response { + + + status?: Number + statusMessage?: string + sentAt?: string + + + +} diff --git a/test/actual_comparators/latest/light-controller/src/schema/turnOnOffPayload.ts b/test/actual_comparators/latest/light-controller/src/schema/turnOnOffPayload.ts new file mode 100644 index 000000000..c9ea846aa --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/schema/turnOnOffPayload.ts @@ -0,0 +1,13 @@ + + + + +export default class turnOnOffPayload { + + + command?: string + sentAt?: string + + + +} diff --git a/test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/actual_comparators/latest/light-controller/src/tests/testclient/index.ts b/test/actual_comparators/latest/light-controller/src/tests/testclient/index.ts new file mode 100644 index 000000000..c7cd13ee6 --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/tests/testclient/index.ts @@ -0,0 +1,41 @@ + + + /** + * [object Object] + * @param onDataCallback Called when message recieved. + */ + public subscribeToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.subscribe(onDataCallback, nc); + } + + + /** + * [object Object] + * @param requestMessage The request message to send. + */ + public requestSmartylightingStreetlights10ActionStreetlightIdTurnOn(requestMessage: TurnOnOffMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.request(requestMessage, nc); + } + + + /** + * [object Object] + * @param requestMessage The request message to send. + */ + public requestSmartylightingStreetlights10ActionStreetlightIdTurnOff(requestMessage: TurnOnOffMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.request(requestMessage, nc); + } + + + /** + * [object Object] + * @param requestMessage The request message to send. + */ + public requestSmartylightingStreetlights10ActionStreetlightIdDim(requestMessage: DimLightMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdDimChannel.request(requestMessage, nc); + } + diff --git a/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts new file mode 100644 index 000000000..008f5e2b9 --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts @@ -0,0 +1,46 @@ + +import {default as DimLightResponseMessage} from '../../../messages/DimLightResponse' +import {default as DimLightMessage} from '../../../messages/DimLight' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + +export function request( + requestMessage: DimLightMessage, + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + resolve(DimLightResponseMessage.toMessage(processedData)); + } + }, { max: 1 }); + let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var requestData; + for(let hook in publishDataHooks){ + requestData = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/dim', { + + "streetlightId": streetlightId + + }), requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts new file mode 100644 index 000000000..91a2eb86a --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts @@ -0,0 +1,46 @@ + +import {default as TurnOnOffResponseMessage} from '../../../messages/TurnOnOffResponse' +import {default as TurnOnOffMessage} from '../../../messages/TurnOnOff' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + +export function request( + requestMessage: TurnOnOffMessage, + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + resolve(TurnOnOffResponseMessage.toMessage(processedData)); + } + }, { max: 1 }); + let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var requestData; + for(let hook in publishDataHooks){ + requestData = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/off', { + + "streetlightId": streetlightId + + }), requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts new file mode 100644 index 000000000..e69df5569 --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts @@ -0,0 +1,46 @@ + +import {default as TurnOnOffResponseMessage} from '../../../messages/TurnOnOffResponse' +import {default as TurnOnOffMessage} from '../../../messages/TurnOnOff' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + +export function request( + requestMessage: TurnOnOffMessage, + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + resolve(TurnOnOffResponseMessage.toMessage(processedData)); + } + }, { max: 1 }); + let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var requestData; + for(let hook in publishDataHooks){ + requestData = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/on', { + + "streetlightId": streetlightId + + }), requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts new file mode 100644 index 000000000..e36a33357 --- /dev/null +++ b/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts @@ -0,0 +1,44 @@ + +import {default as LightMeasuredMessage} from '../../../messages/LightMeasured' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + + +import {getHooks, AvailableHooks} from '#hooks'; +export function subscribe( + onDataCallback : (err?: NatsError, msg?: lightMeasured) => void, + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured', { + + "streetlightId": streetlightId + + }), (err, msg) => { + if(err){ + onDataCallback(err); + }else{ + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let publishedData = new lightMeasured(); + publishedData.copyFrom(processedData); + onDataCallback(undefined, publishedData); + } + }, subscribeOptions); + resolve(subscription); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/actual_comparators/latest/light-controller/tsconfig.json b/test/actual_comparators/latest/light-controller/tsconfig.json new file mode 100644 index 000000000..9fb047824 --- /dev/null +++ b/test/actual_comparators/latest/light-controller/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "declaration": true, + "strict": true, + "noImplicitAny": true, + "removeComments": true, + "preserveConstEnums": true, + "sourceMap": true, + "outDir": "dist/", + "baseUrl": "./src" /* Base directory to resolve non-absolute module names. */, + "paths": { + "#messages": ["messages"], + "#schemas": ["schema"], + "#channels": ["channels"], + "#hooks": ["hooks"] + } + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "**/*.spec.ts"] +} diff --git a/tests/docs/0.1.0/components/channel-bindings.yml b/test/docs/0.1.0/components/channel-bindings.yml similarity index 100% rename from tests/docs/0.1.0/components/channel-bindings.yml rename to test/docs/0.1.0/components/channel-bindings.yml diff --git a/tests/docs/0.1.0/components/messages.yml b/test/docs/0.1.0/components/messages.yml similarity index 100% rename from tests/docs/0.1.0/components/messages.yml rename to test/docs/0.1.0/components/messages.yml diff --git a/tests/docs/0.1.0/components/parameters.yml b/test/docs/0.1.0/components/parameters.yml similarity index 100% rename from tests/docs/0.1.0/components/parameters.yml rename to test/docs/0.1.0/components/parameters.yml diff --git a/tests/docs/0.1.0/components/schemas.yml b/test/docs/0.1.0/components/schemas.yml similarity index 100% rename from tests/docs/0.1.0/components/schemas.yml rename to test/docs/0.1.0/components/schemas.yml diff --git a/tests/docs/0.1.0/frontend.yml b/test/docs/0.1.0/frontend.yml similarity index 100% rename from tests/docs/0.1.0/frontend.yml rename to test/docs/0.1.0/frontend.yml diff --git a/tests/docs/0.1.0/light-controller.yml b/test/docs/0.1.0/light-controller.yml similarity index 100% rename from tests/docs/0.1.0/light-controller.yml rename to test/docs/0.1.0/light-controller.yml diff --git a/test/expected_comparators/latest/frontend/README.md b/test/expected_comparators/latest/frontend/README.md new file mode 100644 index 000000000..fb373e91a --- /dev/null +++ b/test/expected_comparators/latest/frontend/README.md @@ -0,0 +1,17 @@ +# Streetlights Nats API for the frontend + +The Smartylighting Streetlights API allows you to remotely manage the city lights. + +This is for the frontend where the lights can be controlled, which assumed are multiple instances to ensure availability. + +### Check out its awesome features: + +* Turn a specific streetlight on/off 🌃 +* Dim a specific streetlight 😎 +* Receive real-time information about environmental lighting conditions 📈 + + + + +Available nats encodings: +https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings diff --git a/test/expected_comparators/latest/frontend/package.json b/test/expected_comparators/latest/frontend/package.json new file mode 100644 index 000000000..dfe709a71 --- /dev/null +++ b/test/expected_comparators/latest/frontend/package.json @@ -0,0 +1,45 @@ +{ + + + + "name": "streetlights-nats-api-for-the-frontend", + "description": "The Smartylighting Streetlights API allows you to remotely manage the city lights. This is for the frontend where the lights can be controlled, which assumed are multiple instances to ensure availability. ### Check out its awesome features: * Turn a specific streetlight on/off 🌃 * Dim a specific streetlight 😎 * Receive real-time information about environmental lighting conditions 📈 ", + "version": "1.0.0", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "watch": "tsc --watch", + "build": "tsc", + "start": "node src/api/index.js", + "postinstall": "link-module-alias", + "test": "mocha -r ts-node/register tests/\*\*/\*.spec.ts" + }, + "_moduleAliasIgnoreWarning": true, + "_moduleAliases": { + "#messages": "./src/messages", + "#schemas": "./src/schema", + "#channels": "./src/channels", + "#hooks": "./src/hooks" + }, + "dependencies": { + "@types/klaw-sync": "^6.0.0", + "@types/uuid": "3.4.5", + "@types/node": "13.9.5", + "klaw-sync": "6.0.0", + "link-module-alias": "^1.2.0", + "msgpack-lite": "^0.1.26", + "ts-nats": "1.2.4", + "node-yaml-config": "0.0.5", + "typescript": "3.4.3", + "uuid": "3.3.3", + "winston": "3.2.1", + "winston-daily-rotate-file": "3.10.0" + }, + "devDependencies": { + "@types/chai": "^4.2.11", + "@types/mocha": "^7.0.2", + "chai": "^4.2.0", + "mocha": "^7.1.1", + "ts-node": "^8.8.1" + } +} diff --git a/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts new file mode 100644 index 000000000..1361c0da6 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts @@ -0,0 +1,46 @@ + +import {default as DimLightMessage} from '../messages/DimLight' +import {default as DimLightResponseMessage} from '../messages/DimLightResponse' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + +export function request( + requestMessage: DimLightMessage, + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + resolve(DimLightResponseMessage.toMessage(processedData)); + } + }, { max: 1 }); + let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var requestData; + for(let hook in publishDataHooks){ + requestData = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/dim', { + + "streetlightId": streetlightId + + }), requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts new file mode 100644 index 000000000..4f3a2dd9d --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts @@ -0,0 +1,46 @@ + +import {default as TurnOnOffMessage} from '../messages/TurnOnOff' +import {default as TurnOnOffResponseMessage} from '../messages/TurnOnOffResponse' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + +export function request( + requestMessage: TurnOnOffMessage, + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + resolve(TurnOnOffResponseMessage.toMessage(processedData)); + } + }, { max: 1 }); + let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var requestData; + for(let hook in publishDataHooks){ + requestData = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/off', { + + "streetlightId": streetlightId + + }), requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts new file mode 100644 index 000000000..4ca6a3341 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts @@ -0,0 +1,46 @@ + +import {default as TurnOnOffMessage} from '../messages/TurnOnOff' +import {default as TurnOnOffResponseMessage} from '../messages/TurnOnOffResponse' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + +export function request( + requestMessage: TurnOnOffMessage, + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + resolve(TurnOnOffResponseMessage.toMessage(processedData)); + } + }, { max: 1 }); + let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var requestData; + for(let hook in publishDataHooks){ + requestData = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/on', { + + "streetlightId": streetlightId + + }), requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts new file mode 100644 index 000000000..81100c80c --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts @@ -0,0 +1,44 @@ + +import {default as LightMeasuredMessage} from '../messages/LightMeasured' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + + +import {getHooks, AvailableHooks} from '#hooks'; +export function subscribe( + onDataCallback : (err?: NatsError, msg?: lightMeasured) => void, + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured', { + + "streetlightId": streetlightId + + }), (err, msg) => { + if(err){ + onDataCallback(err); + }else{ + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let publishedData = new lightMeasured(); + publishedData.copyFrom(processedData); + onDataCallback(undefined, publishedData); + } + }, subscribeOptions); + resolve(subscription); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event.ts b/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event.ts new file mode 100644 index 000000000..89313c1f9 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event.ts @@ -0,0 +1,40 @@ + +import {default as LightMeasuredMessage} from '../messages/LightMeasured' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + + +import {getHooks, AvailableHooks} from '#hooks'; +export function subscribe( + onDataCallback : (err?: NatsError, msg?: lightMeasured) => void, + + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/event/*', { + + }), (err, msg) => { + if(err){ + onDataCallback(err); + }else{ + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let publishedData = new lightMeasured(); + publishedData.copyFrom(processedData); + onDataCallback(undefined, publishedData); + } + }, subscribeOptions); + resolve(subscription); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/frontend/src/channels/utils.ts b/test/expected_comparators/latest/frontend/src/channels/utils.ts new file mode 100644 index 000000000..8810b700d --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/channels/utils.ts @@ -0,0 +1,11 @@ +export function realizeChannelName(channelName: string, parameters: any) { + let returnString = channelName; + returnString = returnString.replace('/', '.'); + for (let parameterName in parameters) { + returnString = returnString.replace( + `{${parameterName}}`, + parameters[parameterName] + ); + } + return returnString; +} diff --git a/test/expected_comparators/latest/frontend/src/hooks.ts b/test/expected_comparators/latest/frontend/src/hooks.ts new file mode 100644 index 000000000..7dfcbfbd9 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/hooks.ts @@ -0,0 +1,63 @@ +const HOOKS_DIRNAME = './hooks'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as walkSync from 'klaw-sync'; +export enum AvailableHooks { + RecievedData = 'RecievedData', + BeforeSendingData = 'BeforeSendingData' +} +export type RecievedDataHook = () => void; +export type BeforeSendingDataHook = (messageToSend: any) => void; +export var hooks: { + BeforeSendingData: BeforeSendingDataHook[]; + RecievedData: RecievedDataHook[]; +}; + +/** + * Loads the custom hooks. + */ +try { + const hooksPath = path.resolve(HOOKS_DIRNAME); + if (fs.existsSync(hooksPath)) { + const files = walkSync(hooksPath, { nodir: true }); + files.forEach((file: any) => { + require(file.path)((when: AvailableHooks, hook: any) => { + hooks[when].push(hook); + }); + }); + } +} catch (e) { + e.message = `There was a problem registering the hooks: ${e.message}`; + throw e; +} + +/** + * Register a hook for BeforeSendingData + * @param hook + */ +export async function registerBeforeSendingData(hook: BeforeSendingDataHook) { + hooks[AvailableHooks.BeforeSendingData] + ? hooks[AvailableHooks.BeforeSendingData].push(hook) + : [hook]; +} + +/** + * Register a hook for BeforeSendingData + * @param hook + */ +export async function registerRecievedData(hook: RecievedDataHook) { + hooks[AvailableHooks.RecievedData] + ? hooks[AvailableHooks.RecievedData].push(hook) + : [hook]; +} + +/** + * Get all the hooks registered at a given hook point/name. + * @param hook to find hooks for + * @returns all hooks + */ +export function getHooks(hook: AvailableHooks): Function[] { + if (!Array.isArray(hooks[hook])) return []; + // Return valid hooks + return hooks[hook]; +} diff --git a/test/expected_comparators/latest/frontend/src/index.ts b/test/expected_comparators/latest/frontend/src/index.ts new file mode 100644 index 000000000..8573d5b42 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/index.ts @@ -0,0 +1,101 @@ + + +import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; +import * as smartylightingStreetlights10EventChannel from "./channels/Smartylighting/streetlights/1/0/event/*"; +import * as smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel from "./channels/Smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured"; +import * as smartylightingStreetlights10ActionStreetlightIdTurnOnChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/turn/on"; +import * as smartylightingStreetlights10ActionStreetlightIdTurnOffChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/turn/off"; +import * as smartylightingStreetlights10ActionStreetlightIdDimChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/dim"; +import {default as LightMeasuredMessage} from "./messages/LightMeasured"; +import {default as TurnOnOffMessage} from "./messages/TurnOnOff"; +import {default as TurnOnOffResponseMessage} from "./messages/TurnOnOffResponse"; +import {default as DimLightMessage} from "./messages/DimLight"; +import {default as DimLightResponseMessage} from "./messages/DimLightResponse"; + +export default class NatsAsyncApiClient { + public jsonClient?: Client; + public stringClient?: Client; + public binaryClient?: Client; + public options: NatsConnectionOptions; + + /** + * + * @param options options to use, payload is omitted if sat in the AsyncAPI document. + */ + constructor(options : NatsConnectionOptions) { + this.options = this.setDefaultOptions(options); + this.connect(); + } + + /** + * Try to connect to the NATS server with the different payloads. + */ + private async connect(){ + try{ + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + }catch(e){ + console.error("Could not connect to NATS: " + e) + } + } + + /** + * Set the default options based on the AsyncAPI file. + * @param options to set + */ + private setDefaultOptions(options: NatsConnectionOptions){ + //If server binding options sat set the options + options.encoding = 'utf8'; + return options; + } + + /** + * Topic for which one can subscribe to all measurements regardless of id. + * @param onDataCallback Called when message recieved. + */ + public subscribeToSmartylightingStreetlights10Event(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10EventChannel.subscribe(onDataCallback, nc); + } + + + /** + * Topic for which one can subscribe to measurements on a specific streetlightId. + * @param onDataCallback Called when message recieved. + */ + public subscribeToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.subscribe(onDataCallback, nc); + } + + + /** + * + * @param requestMessage The request message to send. + */ + public requestSmartylightingStreetlights10ActionStreetlightIdTurnOn(requestMessage: TurnOnOffMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.request(requestMessage, nc); + } + + + /** + * + * @param requestMessage The request message to send. + */ + public requestSmartylightingStreetlights10ActionStreetlightIdTurnOff(requestMessage: TurnOnOffMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.request(requestMessage, nc); + } + + + /** + * + * @param requestMessage The request message to send. + */ + public requestSmartylightingStreetlights10ActionStreetlightIdDim(requestMessage: DimLightMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdDimChannel.request(requestMessage, nc); + } + +} diff --git a/test/expected_comparators/latest/frontend/src/messages/dimLight.ts b/test/expected_comparators/latest/frontend/src/messages/dimLight.ts new file mode 100644 index 000000000..7a8281027 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/messages/dimLight.ts @@ -0,0 +1,45 @@ + + + + +import { default as DimLightPayloadserereSchema } from '../schema/DimLightPayloadserere'; + + + +import { default as ResponseSchema } from '../schema/Response'; + + +export default class DimLight { + + + + dimLightPayloadserere:DimLightPayloadserereSchema; + + + + response:ResponseSchema; + + + constructor( + dimLightPayloadserere: DimLightPayloadserereSchema,response: ResponseSchema + ){ + + + + this.dimLightPayloadserere = dimLightPayloadserere; + + + + this.response = response; + + } + + /** + * Parses a JSON string to an object of DimLight message class. + * @param json string to be parsed as DimLight. + */ + public static toMessage(json: string): DimLight { + return JSON.parse(json); + } + +} diff --git a/test/expected_comparators/latest/frontend/src/messages/dimLightResponse.ts b/test/expected_comparators/latest/frontend/src/messages/dimLightResponse.ts new file mode 100644 index 000000000..2e0d9da0e --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/messages/dimLightResponse.ts @@ -0,0 +1,30 @@ + + + +import { default as ResponseSchema } from '../schema/Response'; + + +export default class DimLightResponse { + + + response:ResponseSchema; + + + constructor( + response: ResponseSchema + ){ + + + this.response = response; + + } + + /** + * Parses a JSON string to an object of DimLightResponse message class. + * @param json string to be parsed as DimLightResponse. + */ + public static toMessage(json: string): DimLightResponse { + return JSON.parse(json); + } + +} diff --git a/test/expected_comparators/latest/frontend/src/messages/lightMeasured.ts b/test/expected_comparators/latest/frontend/src/messages/lightMeasured.ts new file mode 100644 index 000000000..9e2010e22 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/messages/lightMeasured.ts @@ -0,0 +1,30 @@ + + + +import { default as LightMeasuredPayloadSchema } from '../schema/LightMeasuredPayload'; + + +export default class LightMeasured { + + + lightMeasuredPayload:LightMeasuredPayloadSchema; + + + constructor( + lightMeasuredPayload: LightMeasuredPayloadSchema + ){ + + + this.lightMeasuredPayload = lightMeasuredPayload; + + } + + /** + * Parses a JSON string to an object of LightMeasured message class. + * @param json string to be parsed as LightMeasured. + */ + public static toMessage(json: string): LightMeasured { + return JSON.parse(json); + } + +} diff --git a/test/expected_comparators/latest/frontend/src/messages/turnOnOff.ts b/test/expected_comparators/latest/frontend/src/messages/turnOnOff.ts new file mode 100644 index 000000000..483922274 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/messages/turnOnOff.ts @@ -0,0 +1,30 @@ + + + +import { default as TurnOnOffPayloadSchema } from '../schema/TurnOnOffPayload'; + + +export default class TurnOnOff { + + + turnOnOffPayload:TurnOnOffPayloadSchema; + + + constructor( + turnOnOffPayload: TurnOnOffPayloadSchema + ){ + + + this.turnOnOffPayload = turnOnOffPayload; + + } + + /** + * Parses a JSON string to an object of TurnOnOff message class. + * @param json string to be parsed as TurnOnOff. + */ + public static toMessage(json: string): TurnOnOff { + return JSON.parse(json); + } + +} diff --git a/test/expected_comparators/latest/frontend/src/messages/turnOnOffResponse.ts b/test/expected_comparators/latest/frontend/src/messages/turnOnOffResponse.ts new file mode 100644 index 000000000..c25f1a5c5 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/messages/turnOnOffResponse.ts @@ -0,0 +1,30 @@ + + + +import { default as ResponseSchema } from '../schema/Response'; + + +export default class TurnOnOffResponse { + + + response:ResponseSchema; + + + constructor( + response: ResponseSchema + ){ + + + this.response = response; + + } + + /** + * Parses a JSON string to an object of TurnOnOffResponse message class. + * @param json string to be parsed as TurnOnOffResponse. + */ + public static toMessage(json: string): TurnOnOffResponse { + return JSON.parse(json); + } + +} diff --git a/test/expected_comparators/latest/frontend/src/schema/anonymous-schema-4.ts b/test/expected_comparators/latest/frontend/src/schema/anonymous-schema-4.ts new file mode 100644 index 000000000..ef2cd616f --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/schema/anonymous-schema-4.ts @@ -0,0 +1,11 @@ + + + + +export default class anonymousSchema4 { + + + + + +} diff --git a/test/expected_comparators/latest/frontend/src/schema/anonymous-schema-5.ts b/test/expected_comparators/latest/frontend/src/schema/anonymous-schema-5.ts new file mode 100644 index 000000000..e11ccc78d --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/schema/anonymous-schema-5.ts @@ -0,0 +1,22 @@ + + + + +export default class anonymousSchema5 { + + + + percentage?: Number + sentAt?: string + + + + status?: Number + statusMessage?: string + sentAt?: string + + + + + +} diff --git a/test/expected_comparators/latest/frontend/src/schema/lightMeasuredPayload.ts b/test/expected_comparators/latest/frontend/src/schema/lightMeasuredPayload.ts new file mode 100644 index 000000000..a783f2728 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/schema/lightMeasuredPayload.ts @@ -0,0 +1,13 @@ + + + + +export default class lightMeasuredPayload { + + + lumens?: Number + sentAt?: string + + + +} diff --git a/test/expected_comparators/latest/frontend/src/schema/response.ts b/test/expected_comparators/latest/frontend/src/schema/response.ts new file mode 100644 index 000000000..0c80740f4 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/schema/response.ts @@ -0,0 +1,14 @@ + + + + +export default class response { + + + status?: Number + statusMessage?: string + sentAt?: string + + + +} diff --git a/test/expected_comparators/latest/frontend/src/schema/turnOnOffPayload.ts b/test/expected_comparators/latest/frontend/src/schema/turnOnOffPayload.ts new file mode 100644 index 000000000..c9ea846aa --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/schema/turnOnOffPayload.ts @@ -0,0 +1,13 @@ + + + + +export default class turnOnOffPayload { + + + command?: string + sentAt?: string + + + +} diff --git a/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event.ts b/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/index.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/index.ts new file mode 100644 index 000000000..ecde61413 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/tests/testclient/index.ts @@ -0,0 +1,54 @@ + + + /** + * [object Object] + * @param requestMessage The message to publish. + */ + public publishToSmartylightingStreetlights10Event(requestMessage: LightMeasuredMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10EventChannel.publish(requestMessage, nc); + } + + + /** + * [object Object] + * @param requestMessage The message to publish. + */ + public publishToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(requestMessage: LightMeasuredMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.publish(requestMessage, nc); + } + + + /** + * [object Object] + * @param onRequest Called when request recieved. + * @param onReplyError Called when it was not possible to send the reply. + */ + public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOn(onRequest : (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, onReplyError : (err: NatsError) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.reply(onRequest, onReplyError, nc); + } + + + /** + * [object Object] + * @param onRequest Called when request recieved. + * @param onReplyError Called when it was not possible to send the reply. + */ + public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOff(onRequest : (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, onReplyError : (err: NatsError) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.reply(onRequest, onReplyError, nc); + } + + + /** + * [object Object] + * @param onRequest Called when request recieved. + * @param onReplyError Called when it was not possible to send the reply. + */ + public replyToSmartylightingStreetlights10ActionStreetlightIdDim(onRequest : (err?: NatsError, msg?: DimLightMessage) => DimLightResponseMessage, onReplyError : (err: NatsError) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdDimChannel.reply(onRequest, onReplyError, nc); + } + diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts new file mode 100644 index 000000000..f0c9801c9 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts @@ -0,0 +1,66 @@ + +import {default as DimLightMessage} from '../../../messages/DimLight' +import {default as DimLightResponseMessage} from '../../../messages/DimLightResponse' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + +export function reply( + onRequest: (err?: NatsError, msg?: DimLightMessage) => DimLightResponseMessage, + onReplyError: (err: NatsError) => void, + , + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/dim', { + + "streetlightId": streetlightId + + }), (err, msg) => { + if (err) { + onRequest(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let requestData = new DimLightMessage(); + requestData.copyFrom(processedData); + + let responseObject = onRequest(undefined, requestData); + if (msg.reply) { + try { + let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); + nc.publish(msg.reply, requestData); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + console.error(error) + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts new file mode 100644 index 000000000..4393e85e3 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts @@ -0,0 +1,66 @@ + +import {default as TurnOnOffMessage} from '../../../messages/TurnOnOff' +import {default as TurnOnOffResponseMessage} from '../../../messages/TurnOnOffResponse' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + +export function reply( + onRequest: (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, + onReplyError: (err: NatsError) => void, + , + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/off', { + + "streetlightId": streetlightId + + }), (err, msg) => { + if (err) { + onRequest(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let requestData = new TurnOnOffMessage(); + requestData.copyFrom(processedData); + + let responseObject = onRequest(undefined, requestData); + if (msg.reply) { + try { + let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); + nc.publish(msg.reply, requestData); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + console.error(error) + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts new file mode 100644 index 000000000..366873ed1 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts @@ -0,0 +1,66 @@ + +import {default as TurnOnOffMessage} from '../../../messages/TurnOnOff' +import {default as TurnOnOffResponseMessage} from '../../../messages/TurnOnOffResponse' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + +export function reply( + onRequest: (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, + onReplyError: (err: NatsError) => void, + , + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/on', { + + "streetlightId": streetlightId + + }), (err, msg) => { + if (err) { + onRequest(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let requestData = new TurnOnOffMessage(); + requestData.copyFrom(processedData); + + let responseObject = onRequest(undefined, requestData); + if (msg.reply) { + try { + let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); + nc.publish(msg.reply, requestData); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + console.error(error) + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts new file mode 100644 index 000000000..dba07ac3e --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts @@ -0,0 +1,37 @@ + +import {default as LightMeasuredMessage} from '../../../messages/LightMeasured' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + + +export function publish( + requestMessage: LightMeasuredMessage, + + streetlightId:string + , + nc?: Client + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var dataToPublish; + for(let hook in publishDataHooks){ + dataToPublish = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured', { + + "streetlightId": streetlightId + + }), dataToPublish); + resolve(); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }); +}; + diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event.ts new file mode 100644 index 000000000..937d72bdb --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event.ts @@ -0,0 +1,33 @@ + +import {default as LightMeasuredMessage} from '../../../messages/LightMeasured' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + + +export function publish( + requestMessage: LightMeasuredMessage, + + nc?: Client + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var dataToPublish; + for(let hook in publishDataHooks){ + dataToPublish = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/event/*', { + + }), dataToPublish); + resolve(); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }); +}; + diff --git a/test/expected_comparators/latest/frontend/tsconfig.json b/test/expected_comparators/latest/frontend/tsconfig.json new file mode 100644 index 000000000..9fb047824 --- /dev/null +++ b/test/expected_comparators/latest/frontend/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "declaration": true, + "strict": true, + "noImplicitAny": true, + "removeComments": true, + "preserveConstEnums": true, + "sourceMap": true, + "outDir": "dist/", + "baseUrl": "./src" /* Base directory to resolve non-absolute module names. */, + "paths": { + "#messages": ["messages"], + "#schemas": ["schema"], + "#channels": ["channels"], + "#hooks": ["hooks"] + } + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "**/*.spec.ts"] +} diff --git a/test/expected_comparators/latest/light-controller/README.md b/test/expected_comparators/latest/light-controller/README.md new file mode 100644 index 000000000..7d8ed191e --- /dev/null +++ b/test/expected_comparators/latest/light-controller/README.md @@ -0,0 +1,17 @@ +# Streetlights Nats API for lightning controllers + +The Smartylighting Streetlights API allows you to remotely manage the city lights. + +This is for the lighting controllers, which assumed are multiple instances to ensure availability. + +### Check out its awesome features: + +* Turn a specific streetlight on/off 🌃 +* Dim a specific streetlight 😎 +* Receive real-time information about environmental lighting conditions 📈 + + + + +Available nats encodings: +https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings diff --git a/test/expected_comparators/latest/light-controller/package.json b/test/expected_comparators/latest/light-controller/package.json new file mode 100644 index 000000000..7f9bc65a6 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/package.json @@ -0,0 +1,45 @@ +{ + + + + "name": "streetlights-nats-api-for-lightning-controllers", + "description": "The Smartylighting Streetlights API allows you to remotely manage the city lights. This is for the lighting controllers, which assumed are multiple instances to ensure availability. ### Check out its awesome features: * Turn a specific streetlight on/off 🌃 * Dim a specific streetlight 😎 * Receive real-time information about environmental lighting conditions 📈 ", + "version": "1.0.0", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "watch": "tsc --watch", + "build": "tsc", + "start": "node src/api/index.js", + "postinstall": "link-module-alias", + "test": "mocha -r ts-node/register tests/\*\*/\*.spec.ts" + }, + "_moduleAliasIgnoreWarning": true, + "_moduleAliases": { + "#messages": "./src/messages", + "#schemas": "./src/schema", + "#channels": "./src/channels", + "#hooks": "./src/hooks" + }, + "dependencies": { + "@types/klaw-sync": "^6.0.0", + "@types/uuid": "3.4.5", + "@types/node": "13.9.5", + "klaw-sync": "6.0.0", + "link-module-alias": "^1.2.0", + "msgpack-lite": "^0.1.26", + "ts-nats": "1.2.4", + "node-yaml-config": "0.0.5", + "typescript": "3.4.3", + "uuid": "3.3.3", + "winston": "3.2.1", + "winston-daily-rotate-file": "3.10.0" + }, + "devDependencies": { + "@types/chai": "^4.2.11", + "@types/mocha": "^7.0.2", + "chai": "^4.2.0", + "mocha": "^7.1.1", + "ts-node": "^8.8.1" + } +} diff --git a/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts new file mode 100644 index 000000000..324a21f47 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts @@ -0,0 +1,66 @@ + +import {default as DimLightResponseMessage} from '../messages/DimLightResponse' +import {default as DimLightMessage} from '../messages/DimLight' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + +export function reply( + onRequest: (err?: NatsError, msg?: DimLightMessage) => DimLightResponseMessage, + onReplyError: (err: NatsError) => void, + , + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/dim', { + + "streetlightId": streetlightId + + }), (err, msg) => { + if (err) { + onRequest(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let requestData = new DimLightMessage(); + requestData.copyFrom(processedData); + + let responseObject = onRequest(undefined, requestData); + if (msg.reply) { + try { + let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); + nc.publish(msg.reply, requestData); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + console.error(error) + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts new file mode 100644 index 000000000..e66e7d710 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts @@ -0,0 +1,66 @@ + +import {default as TurnOnOffResponseMessage} from '../messages/TurnOnOffResponse' +import {default as TurnOnOffMessage} from '../messages/TurnOnOff' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + +export function reply( + onRequest: (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, + onReplyError: (err: NatsError) => void, + , + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/off', { + + "streetlightId": streetlightId + + }), (err, msg) => { + if (err) { + onRequest(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let requestData = new TurnOnOffMessage(); + requestData.copyFrom(processedData); + + let responseObject = onRequest(undefined, requestData); + if (msg.reply) { + try { + let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); + nc.publish(msg.reply, requestData); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + console.error(error) + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts new file mode 100644 index 000000000..431746c1d --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts @@ -0,0 +1,66 @@ + +import {default as TurnOnOffResponseMessage} from '../messages/TurnOnOffResponse' +import {default as TurnOnOffMessage} from '../messages/TurnOnOff' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + +export function reply( + onRequest: (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, + onReplyError: (err: NatsError) => void, + , + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/on', { + + "streetlightId": streetlightId + + }), (err, msg) => { + if (err) { + onRequest(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let requestData = new TurnOnOffMessage(); + requestData.copyFrom(processedData); + + let responseObject = onRequest(undefined, requestData); + if (msg.reply) { + try { + let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); + nc.publish(msg.reply, requestData); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + console.error(error) + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts new file mode 100644 index 000000000..d106cccbe --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts @@ -0,0 +1,37 @@ + +import {default as LightMeasuredMessage} from '../messages/LightMeasured' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {realizeChannelName} from './utils'; +import * as hooks from '#hooks'; + + +export function publish( + requestMessage: LightMeasuredMessage, + + streetlightId:string + , + nc?: Client + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var dataToPublish; + for(let hook in publishDataHooks){ + dataToPublish = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured', { + + "streetlightId": streetlightId + + }), dataToPublish); + resolve(); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }); +}; + diff --git a/test/expected_comparators/latest/light-controller/src/channels/utils.ts b/test/expected_comparators/latest/light-controller/src/channels/utils.ts new file mode 100644 index 000000000..8810b700d --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/channels/utils.ts @@ -0,0 +1,11 @@ +export function realizeChannelName(channelName: string, parameters: any) { + let returnString = channelName; + returnString = returnString.replace('/', '.'); + for (let parameterName in parameters) { + returnString = returnString.replace( + `{${parameterName}}`, + parameters[parameterName] + ); + } + return returnString; +} diff --git a/test/expected_comparators/latest/light-controller/src/hooks.ts b/test/expected_comparators/latest/light-controller/src/hooks.ts new file mode 100644 index 000000000..7dfcbfbd9 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/hooks.ts @@ -0,0 +1,63 @@ +const HOOKS_DIRNAME = './hooks'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as walkSync from 'klaw-sync'; +export enum AvailableHooks { + RecievedData = 'RecievedData', + BeforeSendingData = 'BeforeSendingData' +} +export type RecievedDataHook = () => void; +export type BeforeSendingDataHook = (messageToSend: any) => void; +export var hooks: { + BeforeSendingData: BeforeSendingDataHook[]; + RecievedData: RecievedDataHook[]; +}; + +/** + * Loads the custom hooks. + */ +try { + const hooksPath = path.resolve(HOOKS_DIRNAME); + if (fs.existsSync(hooksPath)) { + const files = walkSync(hooksPath, { nodir: true }); + files.forEach((file: any) => { + require(file.path)((when: AvailableHooks, hook: any) => { + hooks[when].push(hook); + }); + }); + } +} catch (e) { + e.message = `There was a problem registering the hooks: ${e.message}`; + throw e; +} + +/** + * Register a hook for BeforeSendingData + * @param hook + */ +export async function registerBeforeSendingData(hook: BeforeSendingDataHook) { + hooks[AvailableHooks.BeforeSendingData] + ? hooks[AvailableHooks.BeforeSendingData].push(hook) + : [hook]; +} + +/** + * Register a hook for BeforeSendingData + * @param hook + */ +export async function registerRecievedData(hook: RecievedDataHook) { + hooks[AvailableHooks.RecievedData] + ? hooks[AvailableHooks.RecievedData].push(hook) + : [hook]; +} + +/** + * Get all the hooks registered at a given hook point/name. + * @param hook to find hooks for + * @returns all hooks + */ +export function getHooks(hook: AvailableHooks): Function[] { + if (!Array.isArray(hooks[hook])) return []; + // Return valid hooks + return hooks[hook]; +} diff --git a/test/expected_comparators/latest/light-controller/src/index.ts b/test/expected_comparators/latest/light-controller/src/index.ts new file mode 100644 index 000000000..380fa3473 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/index.ts @@ -0,0 +1,93 @@ + + +import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; +import * as smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel from "./channels/Smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured"; +import * as smartylightingStreetlights10ActionStreetlightIdTurnOnChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/turn/on"; +import * as smartylightingStreetlights10ActionStreetlightIdTurnOffChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/turn/off"; +import * as smartylightingStreetlights10ActionStreetlightIdDimChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/dim"; +import {default as LightMeasuredMessage} from "./messages/LightMeasured"; +import {default as TurnOnOffResponseMessage} from "./messages/TurnOnOffResponse"; +import {default as TurnOnOffMessage} from "./messages/TurnOnOff"; +import {default as DimLightResponseMessage} from "./messages/DimLightResponse"; +import {default as DimLightMessage} from "./messages/DimLight"; + +export default class NatsAsyncApiClient { + public jsonClient?: Client; + public stringClient?: Client; + public binaryClient?: Client; + public options: NatsConnectionOptions; + + /** + * + * @param options options to use, payload is omitted if sat in the AsyncAPI document. + */ + constructor(options : NatsConnectionOptions) { + this.options = this.setDefaultOptions(options); + this.connect(); + } + + /** + * Try to connect to the NATS server with the different payloads. + */ + private async connect(){ + try{ + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + }catch(e){ + console.error("Could not connect to NATS: " + e) + } + } + + /** + * Set the default options based on the AsyncAPI file. + * @param options to set + */ + private setDefaultOptions(options: NatsConnectionOptions){ + //If server binding options sat set the options + options.encoding = 'utf8'; + return options; + } + + /** + * Any measured values will be published through this method. + * @param requestMessage The message to publish. + */ + public publishToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(requestMessage: LightMeasuredMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.publish(requestMessage, nc); + } + + + /** + * Get notified when a streetlight should be turned on. This should only be handled by 1 subscriber but ensured by request reply. + * @param onRequest Called when request recieved. + * @param onReplyError Called when it was not possible to send the reply. + */ + public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOn(onRequest : (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, onReplyError : (err: NatsError) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.reply(onRequest, onReplyError, nc); + } + + + /** + * Get notified when a streetlight should be turned off. This should only be handled by 1 subscriber but ensured by request reply. + * @param onRequest Called when request recieved. + * @param onReplyError Called when it was not possible to send the reply. + */ + public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOff(onRequest : (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, onReplyError : (err: NatsError) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.reply(onRequest, onReplyError, nc); + } + + + /** + * Get notified when a streetlight should be dimmed. This should only be handled by 1 subscriber but ensured by request reply. + * @param onRequest Called when request recieved. + * @param onReplyError Called when it was not possible to send the reply. + */ + public replyToSmartylightingStreetlights10ActionStreetlightIdDim(onRequest : (err?: NatsError, msg?: DimLightMessage) => DimLightResponseMessage, onReplyError : (err: NatsError) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdDimChannel.reply(onRequest, onReplyError, nc); + } + +} diff --git a/test/expected_comparators/latest/light-controller/src/messages/dimLight.ts b/test/expected_comparators/latest/light-controller/src/messages/dimLight.ts new file mode 100644 index 000000000..7a8281027 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/messages/dimLight.ts @@ -0,0 +1,45 @@ + + + + +import { default as DimLightPayloadserereSchema } from '../schema/DimLightPayloadserere'; + + + +import { default as ResponseSchema } from '../schema/Response'; + + +export default class DimLight { + + + + dimLightPayloadserere:DimLightPayloadserereSchema; + + + + response:ResponseSchema; + + + constructor( + dimLightPayloadserere: DimLightPayloadserereSchema,response: ResponseSchema + ){ + + + + this.dimLightPayloadserere = dimLightPayloadserere; + + + + this.response = response; + + } + + /** + * Parses a JSON string to an object of DimLight message class. + * @param json string to be parsed as DimLight. + */ + public static toMessage(json: string): DimLight { + return JSON.parse(json); + } + +} diff --git a/test/expected_comparators/latest/light-controller/src/messages/dimLightResponse.ts b/test/expected_comparators/latest/light-controller/src/messages/dimLightResponse.ts new file mode 100644 index 000000000..2e0d9da0e --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/messages/dimLightResponse.ts @@ -0,0 +1,30 @@ + + + +import { default as ResponseSchema } from '../schema/Response'; + + +export default class DimLightResponse { + + + response:ResponseSchema; + + + constructor( + response: ResponseSchema + ){ + + + this.response = response; + + } + + /** + * Parses a JSON string to an object of DimLightResponse message class. + * @param json string to be parsed as DimLightResponse. + */ + public static toMessage(json: string): DimLightResponse { + return JSON.parse(json); + } + +} diff --git a/test/expected_comparators/latest/light-controller/src/messages/lightMeasured.ts b/test/expected_comparators/latest/light-controller/src/messages/lightMeasured.ts new file mode 100644 index 000000000..9e2010e22 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/messages/lightMeasured.ts @@ -0,0 +1,30 @@ + + + +import { default as LightMeasuredPayloadSchema } from '../schema/LightMeasuredPayload'; + + +export default class LightMeasured { + + + lightMeasuredPayload:LightMeasuredPayloadSchema; + + + constructor( + lightMeasuredPayload: LightMeasuredPayloadSchema + ){ + + + this.lightMeasuredPayload = lightMeasuredPayload; + + } + + /** + * Parses a JSON string to an object of LightMeasured message class. + * @param json string to be parsed as LightMeasured. + */ + public static toMessage(json: string): LightMeasured { + return JSON.parse(json); + } + +} diff --git a/test/expected_comparators/latest/light-controller/src/messages/turnOnOff.ts b/test/expected_comparators/latest/light-controller/src/messages/turnOnOff.ts new file mode 100644 index 000000000..483922274 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/messages/turnOnOff.ts @@ -0,0 +1,30 @@ + + + +import { default as TurnOnOffPayloadSchema } from '../schema/TurnOnOffPayload'; + + +export default class TurnOnOff { + + + turnOnOffPayload:TurnOnOffPayloadSchema; + + + constructor( + turnOnOffPayload: TurnOnOffPayloadSchema + ){ + + + this.turnOnOffPayload = turnOnOffPayload; + + } + + /** + * Parses a JSON string to an object of TurnOnOff message class. + * @param json string to be parsed as TurnOnOff. + */ + public static toMessage(json: string): TurnOnOff { + return JSON.parse(json); + } + +} diff --git a/test/expected_comparators/latest/light-controller/src/messages/turnOnOffResponse.ts b/test/expected_comparators/latest/light-controller/src/messages/turnOnOffResponse.ts new file mode 100644 index 000000000..c25f1a5c5 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/messages/turnOnOffResponse.ts @@ -0,0 +1,30 @@ + + + +import { default as ResponseSchema } from '../schema/Response'; + + +export default class TurnOnOffResponse { + + + response:ResponseSchema; + + + constructor( + response: ResponseSchema + ){ + + + this.response = response; + + } + + /** + * Parses a JSON string to an object of TurnOnOffResponse message class. + * @param json string to be parsed as TurnOnOffResponse. + */ + public static toMessage(json: string): TurnOnOffResponse { + return JSON.parse(json); + } + +} diff --git a/test/expected_comparators/latest/light-controller/src/schema/anonymous-schema-4.ts b/test/expected_comparators/latest/light-controller/src/schema/anonymous-schema-4.ts new file mode 100644 index 000000000..ef2cd616f --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/schema/anonymous-schema-4.ts @@ -0,0 +1,11 @@ + + + + +export default class anonymousSchema4 { + + + + + +} diff --git a/test/expected_comparators/latest/light-controller/src/schema/anonymous-schema-5.ts b/test/expected_comparators/latest/light-controller/src/schema/anonymous-schema-5.ts new file mode 100644 index 000000000..e11ccc78d --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/schema/anonymous-schema-5.ts @@ -0,0 +1,22 @@ + + + + +export default class anonymousSchema5 { + + + + percentage?: Number + sentAt?: string + + + + status?: Number + statusMessage?: string + sentAt?: string + + + + + +} diff --git a/test/expected_comparators/latest/light-controller/src/schema/lightMeasuredPayload.ts b/test/expected_comparators/latest/light-controller/src/schema/lightMeasuredPayload.ts new file mode 100644 index 000000000..a783f2728 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/schema/lightMeasuredPayload.ts @@ -0,0 +1,13 @@ + + + + +export default class lightMeasuredPayload { + + + lumens?: Number + sentAt?: string + + + +} diff --git a/test/expected_comparators/latest/light-controller/src/schema/response.ts b/test/expected_comparators/latest/light-controller/src/schema/response.ts new file mode 100644 index 000000000..0c80740f4 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/schema/response.ts @@ -0,0 +1,14 @@ + + + + +export default class response { + + + status?: Number + statusMessage?: string + sentAt?: string + + + +} diff --git a/test/expected_comparators/latest/light-controller/src/schema/turnOnOffPayload.ts b/test/expected_comparators/latest/light-controller/src/schema/turnOnOffPayload.ts new file mode 100644 index 000000000..c9ea846aa --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/schema/turnOnOffPayload.ts @@ -0,0 +1,13 @@ + + + + +export default class turnOnOffPayload { + + + command?: string + sentAt?: string + + + +} diff --git a/test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/index.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/index.ts new file mode 100644 index 000000000..c7cd13ee6 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/tests/testclient/index.ts @@ -0,0 +1,41 @@ + + + /** + * [object Object] + * @param onDataCallback Called when message recieved. + */ + public subscribeToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage) => void): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.subscribe(onDataCallback, nc); + } + + + /** + * [object Object] + * @param requestMessage The request message to send. + */ + public requestSmartylightingStreetlights10ActionStreetlightIdTurnOn(requestMessage: TurnOnOffMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.request(requestMessage, nc); + } + + + /** + * [object Object] + * @param requestMessage The request message to send. + */ + public requestSmartylightingStreetlights10ActionStreetlightIdTurnOff(requestMessage: TurnOnOffMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.request(requestMessage, nc); + } + + + /** + * [object Object] + * @param requestMessage The request message to send. + */ + public requestSmartylightingStreetlights10ActionStreetlightIdDim(requestMessage: DimLightMessage): Promise { + const nc: Client = this.jsonClient!; + return smartylightingStreetlights10ActionStreetlightIdDimChannel.request(requestMessage, nc); + } + diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts new file mode 100644 index 000000000..008f5e2b9 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts @@ -0,0 +1,46 @@ + +import {default as DimLightResponseMessage} from '../../../messages/DimLightResponse' +import {default as DimLightMessage} from '../../../messages/DimLight' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + +export function request( + requestMessage: DimLightMessage, + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + resolve(DimLightResponseMessage.toMessage(processedData)); + } + }, { max: 1 }); + let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var requestData; + for(let hook in publishDataHooks){ + requestData = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/dim', { + + "streetlightId": streetlightId + + }), requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts new file mode 100644 index 000000000..91a2eb86a --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts @@ -0,0 +1,46 @@ + +import {default as TurnOnOffResponseMessage} from '../../../messages/TurnOnOffResponse' +import {default as TurnOnOffMessage} from '../../../messages/TurnOnOff' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + +export function request( + requestMessage: TurnOnOffMessage, + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + resolve(TurnOnOffResponseMessage.toMessage(processedData)); + } + }, { max: 1 }); + let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var requestData; + for(let hook in publishDataHooks){ + requestData = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/off', { + + "streetlightId": streetlightId + + }), requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts new file mode 100644 index 000000000..e69df5569 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts @@ -0,0 +1,46 @@ + +import {default as TurnOnOffResponseMessage} from '../../../messages/TurnOnOffResponse' +import {default as TurnOnOffMessage} from '../../../messages/TurnOnOff' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + +export function request( + requestMessage: TurnOnOffMessage, + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + resolve(TurnOnOffResponseMessage.toMessage(processedData)); + } + }, { max: 1 }); + let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); + let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + var requestData; + for(let hook in publishDataHooks){ + requestData = hook(requestMessage); + } + nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/on', { + + "streetlightId": streetlightId + + }), requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts new file mode 100644 index 000000000..e36a33357 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts @@ -0,0 +1,44 @@ + +import {default as LightMeasuredMessage} from '../../../messages/LightMeasured' + +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import * as utils from '../utils'; + + +import {getHooks, AvailableHooks} from '#hooks'; +export function subscribe( + onDataCallback : (err?: NatsError, msg?: lightMeasured) => void, + + streetlightId:string + , + nc?: Client): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured', { + + "streetlightId": streetlightId + + }), (err, msg) => { + if(err){ + onDataCallback(err); + }else{ + let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); + let publishedData = new lightMeasured(); + publishedData.copyFrom(processedData); + onDataCallback(undefined, publishedData); + } + }, subscribeOptions); + resolve(subscription); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/light-controller/tsconfig.json b/test/expected_comparators/latest/light-controller/tsconfig.json new file mode 100644 index 000000000..9fb047824 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "declaration": true, + "strict": true, + "noImplicitAny": true, + "removeComments": true, + "preserveConstEnums": true, + "sourceMap": true, + "outDir": "dist/", + "baseUrl": "./src" /* Base directory to resolve non-absolute module names. */, + "paths": { + "#messages": ["messages"], + "#schemas": ["schema"], + "#channels": ["channels"], + "#hooks": ["hooks"] + } + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "**/*.spec.ts"] +} diff --git a/test/template.js b/test/template.js new file mode 100644 index 000000000..668925374 --- /dev/null +++ b/test/template.js @@ -0,0 +1,26 @@ +const dircompare = require('dir-compare'); +const path = require('path'); +const expect = require('chai').expect; +describe('template', () => { + describe('should be usable with latest generator', () => { + describe('and should support 0.1.0 bindings', () => { + it('for frontend', () => { + const path1 = path.resolve('./test/actual_comparators/latest/frontend'); + const path2 = path.resolve('./test/expected_comparators/latest/frontend'); + const res = compareDir(path1, path2); + expect(res.same).to.be.true; + }); + it('for light-controller', () => { + const path1 = path.resolve('./test/actual_comparators/latest/light-controller'); + const path2 = path.resolve('./test/expected_comparators/latest/light-controller'); + const res = compareDir(path1, path2); + expect(res.same).to.be.true; + }); + }); + }); +}); + +function compareDir(path1, path2){ + const options = { compareSize: true }; + return dircompare.compareSync(path1, path2, options); +} \ No newline at end of file From 168b447356f4a201b760e616312a89abc7e1be81 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 6 Apr 2020 00:51:04 +0200 Subject: [PATCH 019/110] Fix: Removed actual comparators for testing. Should be generated each for each test. --- .gitignore | 2 +- scripts/generate_new_actual_comparators.sh | 15 +-- scripts/generate_new_expected_comparators.sh | 12 +-- .../latest/frontend/README.md | 17 --- .../latest/frontend/package.json | 45 -------- ...etlights-1-0-action-{streetlightId}-dim.ts | 46 -------- ...hts-1-0-action-{streetlightId}-turn-off.ts | 46 -------- ...ghts-1-0-action-{streetlightId}-turn-on.ts | 46 -------- ...event-{streetlightId}-lighting-measured.ts | 44 -------- .../smartylighting-streetlights-1-0-event.ts | 40 ------- .../latest/frontend/src/channels/utils.ts | 11 -- .../latest/frontend/src/hooks.ts | 63 ----------- .../latest/frontend/src/index.ts | 101 ------------------ .../latest/frontend/src/messages/dimLight.ts | 45 -------- .../frontend/src/messages/dimLightResponse.ts | 30 ------ .../frontend/src/messages/lightMeasured.ts | 30 ------ .../latest/frontend/src/messages/turnOnOff.ts | 30 ------ .../src/messages/turnOnOffResponse.ts | 30 ------ .../frontend/src/schema/anonymous-schema-4.ts | 11 -- .../frontend/src/schema/anonymous-schema-5.ts | 22 ---- .../src/schema/lightMeasuredPayload.ts | 13 --- .../latest/frontend/src/schema/response.ts | 14 --- .../frontend/src/schema/turnOnOffPayload.ts | 13 --- ...etlights-1-0-action-{streetlightId}-dim.ts | 0 ...hts-1-0-action-{streetlightId}-turn-off.ts | 0 ...ghts-1-0-action-{streetlightId}-turn-on.ts | 0 ...event-{streetlightId}-lighting-measured.ts | 0 .../smartylighting-streetlights-1-0-event.ts | 0 .../frontend/src/tests/testclient/index.ts | 54 ---------- ...etlights-1-0-action-{streetlightId}-dim.ts | 66 ------------ ...hts-1-0-action-{streetlightId}-turn-off.ts | 66 ------------ ...ghts-1-0-action-{streetlightId}-turn-on.ts | 66 ------------ ...event-{streetlightId}-lighting-measured.ts | 37 ------- .../smartylighting-streetlights-1-0-event.ts | 33 ------ .../latest/frontend/tsconfig.json | 22 ---- .../latest/light-controller/README.md | 17 --- .../latest/light-controller/package.json | 45 -------- ...etlights-1-0-action-{streetlightId}-dim.ts | 66 ------------ ...hts-1-0-action-{streetlightId}-turn-off.ts | 66 ------------ ...ghts-1-0-action-{streetlightId}-turn-on.ts | 66 ------------ ...event-{streetlightId}-lighting-measured.ts | 37 ------- .../light-controller/src/channels/utils.ts | 11 -- .../latest/light-controller/src/hooks.ts | 63 ----------- .../latest/light-controller/src/index.ts | 93 ---------------- .../light-controller/src/messages/dimLight.ts | 45 -------- .../src/messages/dimLightResponse.ts | 30 ------ .../src/messages/lightMeasured.ts | 30 ------ .../src/messages/turnOnOff.ts | 30 ------ .../src/messages/turnOnOffResponse.ts | 30 ------ .../src/schema/anonymous-schema-4.ts | 11 -- .../src/schema/anonymous-schema-5.ts | 22 ---- .../src/schema/lightMeasuredPayload.ts | 13 --- .../light-controller/src/schema/response.ts | 14 --- .../src/schema/turnOnOffPayload.ts | 13 --- ...etlights-1-0-action-{streetlightId}-dim.ts | 0 ...hts-1-0-action-{streetlightId}-turn-off.ts | 0 ...ghts-1-0-action-{streetlightId}-turn-on.ts | 0 ...event-{streetlightId}-lighting-measured.ts | 0 .../src/tests/testclient/index.ts | 41 ------- ...etlights-1-0-action-{streetlightId}-dim.ts | 46 -------- ...hts-1-0-action-{streetlightId}-turn-off.ts | 46 -------- ...ghts-1-0-action-{streetlightId}-turn-on.ts | 46 -------- ...event-{streetlightId}-lighting-measured.ts | 44 -------- .../latest/light-controller/tsconfig.json | 22 ---- 64 files changed, 16 insertions(+), 2001 deletions(-) delete mode 100644 test/actual_comparators/latest/frontend/README.md delete mode 100644 test/actual_comparators/latest/frontend/package.json delete mode 100644 test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts delete mode 100644 test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts delete mode 100644 test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts delete mode 100644 test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts delete mode 100644 test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event.ts delete mode 100644 test/actual_comparators/latest/frontend/src/channels/utils.ts delete mode 100644 test/actual_comparators/latest/frontend/src/hooks.ts delete mode 100644 test/actual_comparators/latest/frontend/src/index.ts delete mode 100644 test/actual_comparators/latest/frontend/src/messages/dimLight.ts delete mode 100644 test/actual_comparators/latest/frontend/src/messages/dimLightResponse.ts delete mode 100644 test/actual_comparators/latest/frontend/src/messages/lightMeasured.ts delete mode 100644 test/actual_comparators/latest/frontend/src/messages/turnOnOff.ts delete mode 100644 test/actual_comparators/latest/frontend/src/messages/turnOnOffResponse.ts delete mode 100644 test/actual_comparators/latest/frontend/src/schema/anonymous-schema-4.ts delete mode 100644 test/actual_comparators/latest/frontend/src/schema/anonymous-schema-5.ts delete mode 100644 test/actual_comparators/latest/frontend/src/schema/lightMeasuredPayload.ts delete mode 100644 test/actual_comparators/latest/frontend/src/schema/response.ts delete mode 100644 test/actual_comparators/latest/frontend/src/schema/turnOnOffPayload.ts delete mode 100644 test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts delete mode 100644 test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts delete mode 100644 test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts delete mode 100644 test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts delete mode 100644 test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event.ts delete mode 100644 test/actual_comparators/latest/frontend/src/tests/testclient/index.ts delete mode 100644 test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts delete mode 100644 test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts delete mode 100644 test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts delete mode 100644 test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts delete mode 100644 test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event.ts delete mode 100644 test/actual_comparators/latest/frontend/tsconfig.json delete mode 100644 test/actual_comparators/latest/light-controller/README.md delete mode 100644 test/actual_comparators/latest/light-controller/package.json delete mode 100644 test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/channels/utils.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/hooks.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/index.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/messages/dimLight.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/messages/dimLightResponse.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/messages/lightMeasured.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/messages/turnOnOff.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/messages/turnOnOffResponse.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/schema/anonymous-schema-4.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/schema/anonymous-schema-5.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/schema/lightMeasuredPayload.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/schema/response.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/schema/turnOnOffPayload.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/tests/testclient/index.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts delete mode 100644 test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts delete mode 100644 test/actual_comparators/latest/light-controller/tsconfig.json diff --git a/.gitignore b/.gitignore index b72af8276..0453c489e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ node_modules -tests/actual_comparators \ No newline at end of file +test/actual_comparators/* \ No newline at end of file diff --git a/scripts/generate_new_actual_comparators.sh b/scripts/generate_new_actual_comparators.sh index 82733baa7..9af3a673e 100644 --- a/scripts/generate_new_actual_comparators.sh +++ b/scripts/generate_new_actual_comparators.sh @@ -16,18 +16,21 @@ if [ $machine == "MinGw" ]; then currentDir="${currentDir^}" currentDir="${currentDir}${PWD:2}" fi +mkdir ${currentDir}/test/actual_comparators/latest/frontend +mkdir ${currentDir}/test/actual_comparators/latest/light-controller + docker run --rm -it \ - -v ${currentDir}/tests/docs/0.1.0/frontend.yml:/app/asyncapi.yml \ - -v ${currentDir}/tests/docs/0.1.0/components:/app/components \ - -v ${currentDir}/tests/actual_comparators/latest/frontend:/app/output \ + -v ${currentDir}/test/docs/0.1.0/frontend.yml:/app/asyncapi.yml \ + -v ${currentDir}/test/docs/0.1.0/components:/app/components \ + -v ${currentDir}/test/actual_comparators/latest/frontend:/app/output \ -v ${currentDir}:/app/template \ asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --force-write --install docker run --rm -it \ - -v ${currentDir}/tests/docs/0.1.0/light-controller.yml:/app/asyncapi.yml \ - -v ${currentDir}/tests/docs/0.1.0/components:/app/components \ - -v ${currentDir}/tests/actual_comparators/latest/light-controller:/app/output \ + -v ${currentDir}/test/docs/0.1.0/light-controller.yml:/app/asyncapi.yml \ + -v ${currentDir}/test/docs/0.1.0/components:/app/components \ + -v ${currentDir}/test/actual_comparators/latest/light-controller:/app/output \ -v ${currentDir}:/app/template \ asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --force-write --install diff --git a/scripts/generate_new_expected_comparators.sh b/scripts/generate_new_expected_comparators.sh index 3b6adc9b0..423b7ed4f 100644 --- a/scripts/generate_new_expected_comparators.sh +++ b/scripts/generate_new_expected_comparators.sh @@ -18,16 +18,16 @@ if [ $machine == "MinGw" ]; then fi docker run --rm -it \ - -v ${currentDir}/tests/docs/0.1.0/frontend.yml:/app/asyncapi.yml \ - -v ${currentDir}/tests/docs/0.1.0/components:/app/components \ - -v ${currentDir}/tests/expected_comparators/latest/frontend:/app/output \ + -v ${currentDir}/test/docs/0.1.0/frontend.yml:/app/asyncapi.yml \ + -v ${currentDir}/test/docs/0.1.0/components:/app/components \ + -v ${currentDir}/test/expected_comparators/latest/frontend:/app/output \ -v ${currentDir}:/app/template \ asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --force-write --install docker run --rm -it \ - -v ${currentDir}/tests/docs/0.1.0/light-controller.yml:/app/asyncapi.yml \ - -v ${currentDir}/tests/docs/0.1.0/components:/app/components \ - -v ${currentDir}/tests/expected_comparators/latest/light-controller:/app/output \ + -v ${currentDir}/test/docs/0.1.0/light-controller.yml:/app/asyncapi.yml \ + -v ${currentDir}/test/docs/0.1.0/components:/app/components \ + -v ${currentDir}/test/expected_comparators/latest/light-controller:/app/output \ -v ${currentDir}:/app/template \ asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --force-write --install diff --git a/test/actual_comparators/latest/frontend/README.md b/test/actual_comparators/latest/frontend/README.md deleted file mode 100644 index fb373e91a..000000000 --- a/test/actual_comparators/latest/frontend/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Streetlights Nats API for the frontend - -The Smartylighting Streetlights API allows you to remotely manage the city lights. - -This is for the frontend where the lights can be controlled, which assumed are multiple instances to ensure availability. - -### Check out its awesome features: - -* Turn a specific streetlight on/off 🌃 -* Dim a specific streetlight 😎 -* Receive real-time information about environmental lighting conditions 📈 - - - - -Available nats encodings: -https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings diff --git a/test/actual_comparators/latest/frontend/package.json b/test/actual_comparators/latest/frontend/package.json deleted file mode 100644 index dfe709a71..000000000 --- a/test/actual_comparators/latest/frontend/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - - - - "name": "streetlights-nats-api-for-the-frontend", - "description": "The Smartylighting Streetlights API allows you to remotely manage the city lights. This is for the frontend where the lights can be controlled, which assumed are multiple instances to ensure availability. ### Check out its awesome features: * Turn a specific streetlight on/off 🌃 * Dim a specific streetlight 😎 * Receive real-time information about environmental lighting conditions 📈 ", - "version": "1.0.0", - "main": "dist/index.js", - "types": "dist/index.d.ts", - "scripts": { - "watch": "tsc --watch", - "build": "tsc", - "start": "node src/api/index.js", - "postinstall": "link-module-alias", - "test": "mocha -r ts-node/register tests/\*\*/\*.spec.ts" - }, - "_moduleAliasIgnoreWarning": true, - "_moduleAliases": { - "#messages": "./src/messages", - "#schemas": "./src/schema", - "#channels": "./src/channels", - "#hooks": "./src/hooks" - }, - "dependencies": { - "@types/klaw-sync": "^6.0.0", - "@types/uuid": "3.4.5", - "@types/node": "13.9.5", - "klaw-sync": "6.0.0", - "link-module-alias": "^1.2.0", - "msgpack-lite": "^0.1.26", - "ts-nats": "1.2.4", - "node-yaml-config": "0.0.5", - "typescript": "3.4.3", - "uuid": "3.3.3", - "winston": "3.2.1", - "winston-daily-rotate-file": "3.10.0" - }, - "devDependencies": { - "@types/chai": "^4.2.11", - "@types/mocha": "^7.0.2", - "chai": "^4.2.0", - "mocha": "^7.1.1", - "ts-node": "^8.8.1" - } -} diff --git a/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts deleted file mode 100644 index 1361c0da6..000000000 --- a/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts +++ /dev/null @@ -1,46 +0,0 @@ - -import {default as DimLightMessage} from '../messages/DimLight' -import {default as DimLightResponseMessage} from '../messages/DimLightResponse' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - -export function request( - requestMessage: DimLightMessage, - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - resolve(DimLightResponseMessage.toMessage(processedData)); - } - }, { max: 1 }); - let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var requestData; - for(let hook in publishDataHooks){ - requestData = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/dim', { - - "streetlightId": streetlightId - - }), requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts deleted file mode 100644 index 4f3a2dd9d..000000000 --- a/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts +++ /dev/null @@ -1,46 +0,0 @@ - -import {default as TurnOnOffMessage} from '../messages/TurnOnOff' -import {default as TurnOnOffResponseMessage} from '../messages/TurnOnOffResponse' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - -export function request( - requestMessage: TurnOnOffMessage, - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - resolve(TurnOnOffResponseMessage.toMessage(processedData)); - } - }, { max: 1 }); - let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var requestData; - for(let hook in publishDataHooks){ - requestData = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/off', { - - "streetlightId": streetlightId - - }), requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts deleted file mode 100644 index 4ca6a3341..000000000 --- a/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts +++ /dev/null @@ -1,46 +0,0 @@ - -import {default as TurnOnOffMessage} from '../messages/TurnOnOff' -import {default as TurnOnOffResponseMessage} from '../messages/TurnOnOffResponse' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - -export function request( - requestMessage: TurnOnOffMessage, - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - resolve(TurnOnOffResponseMessage.toMessage(processedData)); - } - }, { max: 1 }); - let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var requestData; - for(let hook in publishDataHooks){ - requestData = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/on', { - - "streetlightId": streetlightId - - }), requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts deleted file mode 100644 index 81100c80c..000000000 --- a/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts +++ /dev/null @@ -1,44 +0,0 @@ - -import {default as LightMeasuredMessage} from '../messages/LightMeasured' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - - -import {getHooks, AvailableHooks} from '#hooks'; -export function subscribe( - onDataCallback : (err?: NatsError, msg?: lightMeasured) => void, - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured', { - - "streetlightId": streetlightId - - }), (err, msg) => { - if(err){ - onDataCallback(err); - }else{ - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let publishedData = new lightMeasured(); - publishedData.copyFrom(processedData); - onDataCallback(undefined, publishedData); - } - }, subscribeOptions); - resolve(subscription); - }catch(e){ - reject(e); - } - }else{ - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event.ts b/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event.ts deleted file mode 100644 index 89313c1f9..000000000 --- a/test/actual_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event.ts +++ /dev/null @@ -1,40 +0,0 @@ - -import {default as LightMeasuredMessage} from '../messages/LightMeasured' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - - -import {getHooks, AvailableHooks} from '#hooks'; -export function subscribe( - onDataCallback : (err?: NatsError, msg?: lightMeasured) => void, - - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/event/*', { - - }), (err, msg) => { - if(err){ - onDataCallback(err); - }else{ - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let publishedData = new lightMeasured(); - publishedData.copyFrom(processedData); - onDataCallback(undefined, publishedData); - } - }, subscribeOptions); - resolve(subscription); - }catch(e){ - reject(e); - } - }else{ - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/actual_comparators/latest/frontend/src/channels/utils.ts b/test/actual_comparators/latest/frontend/src/channels/utils.ts deleted file mode 100644 index 8810b700d..000000000 --- a/test/actual_comparators/latest/frontend/src/channels/utils.ts +++ /dev/null @@ -1,11 +0,0 @@ -export function realizeChannelName(channelName: string, parameters: any) { - let returnString = channelName; - returnString = returnString.replace('/', '.'); - for (let parameterName in parameters) { - returnString = returnString.replace( - `{${parameterName}}`, - parameters[parameterName] - ); - } - return returnString; -} diff --git a/test/actual_comparators/latest/frontend/src/hooks.ts b/test/actual_comparators/latest/frontend/src/hooks.ts deleted file mode 100644 index 7dfcbfbd9..000000000 --- a/test/actual_comparators/latest/frontend/src/hooks.ts +++ /dev/null @@ -1,63 +0,0 @@ -const HOOKS_DIRNAME = './hooks'; -import * as fs from 'fs'; -import * as path from 'path'; -import * as walkSync from 'klaw-sync'; -export enum AvailableHooks { - RecievedData = 'RecievedData', - BeforeSendingData = 'BeforeSendingData' -} -export type RecievedDataHook = () => void; -export type BeforeSendingDataHook = (messageToSend: any) => void; -export var hooks: { - BeforeSendingData: BeforeSendingDataHook[]; - RecievedData: RecievedDataHook[]; -}; - -/** - * Loads the custom hooks. - */ -try { - const hooksPath = path.resolve(HOOKS_DIRNAME); - if (fs.existsSync(hooksPath)) { - const files = walkSync(hooksPath, { nodir: true }); - files.forEach((file: any) => { - require(file.path)((when: AvailableHooks, hook: any) => { - hooks[when].push(hook); - }); - }); - } -} catch (e) { - e.message = `There was a problem registering the hooks: ${e.message}`; - throw e; -} - -/** - * Register a hook for BeforeSendingData - * @param hook - */ -export async function registerBeforeSendingData(hook: BeforeSendingDataHook) { - hooks[AvailableHooks.BeforeSendingData] - ? hooks[AvailableHooks.BeforeSendingData].push(hook) - : [hook]; -} - -/** - * Register a hook for BeforeSendingData - * @param hook - */ -export async function registerRecievedData(hook: RecievedDataHook) { - hooks[AvailableHooks.RecievedData] - ? hooks[AvailableHooks.RecievedData].push(hook) - : [hook]; -} - -/** - * Get all the hooks registered at a given hook point/name. - * @param hook to find hooks for - * @returns all hooks - */ -export function getHooks(hook: AvailableHooks): Function[] { - if (!Array.isArray(hooks[hook])) return []; - // Return valid hooks - return hooks[hook]; -} diff --git a/test/actual_comparators/latest/frontend/src/index.ts b/test/actual_comparators/latest/frontend/src/index.ts deleted file mode 100644 index 8573d5b42..000000000 --- a/test/actual_comparators/latest/frontend/src/index.ts +++ /dev/null @@ -1,101 +0,0 @@ - - -import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; -import * as smartylightingStreetlights10EventChannel from "./channels/Smartylighting/streetlights/1/0/event/*"; -import * as smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel from "./channels/Smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured"; -import * as smartylightingStreetlights10ActionStreetlightIdTurnOnChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/turn/on"; -import * as smartylightingStreetlights10ActionStreetlightIdTurnOffChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/turn/off"; -import * as smartylightingStreetlights10ActionStreetlightIdDimChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/dim"; -import {default as LightMeasuredMessage} from "./messages/LightMeasured"; -import {default as TurnOnOffMessage} from "./messages/TurnOnOff"; -import {default as TurnOnOffResponseMessage} from "./messages/TurnOnOffResponse"; -import {default as DimLightMessage} from "./messages/DimLight"; -import {default as DimLightResponseMessage} from "./messages/DimLightResponse"; - -export default class NatsAsyncApiClient { - public jsonClient?: Client; - public stringClient?: Client; - public binaryClient?: Client; - public options: NatsConnectionOptions; - - /** - * - * @param options options to use, payload is omitted if sat in the AsyncAPI document. - */ - constructor(options : NatsConnectionOptions) { - this.options = this.setDefaultOptions(options); - this.connect(); - } - - /** - * Try to connect to the NATS server with the different payloads. - */ - private async connect(){ - try{ - this.options.payload = Payload.JSON; - this.jsonClient = await connect(this.options); - }catch(e){ - console.error("Could not connect to NATS: " + e) - } - } - - /** - * Set the default options based on the AsyncAPI file. - * @param options to set - */ - private setDefaultOptions(options: NatsConnectionOptions){ - //If server binding options sat set the options - options.encoding = 'utf8'; - return options; - } - - /** - * Topic for which one can subscribe to all measurements regardless of id. - * @param onDataCallback Called when message recieved. - */ - public subscribeToSmartylightingStreetlights10Event(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage) => void): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10EventChannel.subscribe(onDataCallback, nc); - } - - - /** - * Topic for which one can subscribe to measurements on a specific streetlightId. - * @param onDataCallback Called when message recieved. - */ - public subscribeToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage) => void): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.subscribe(onDataCallback, nc); - } - - - /** - * - * @param requestMessage The request message to send. - */ - public requestSmartylightingStreetlights10ActionStreetlightIdTurnOn(requestMessage: TurnOnOffMessage): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.request(requestMessage, nc); - } - - - /** - * - * @param requestMessage The request message to send. - */ - public requestSmartylightingStreetlights10ActionStreetlightIdTurnOff(requestMessage: TurnOnOffMessage): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.request(requestMessage, nc); - } - - - /** - * - * @param requestMessage The request message to send. - */ - public requestSmartylightingStreetlights10ActionStreetlightIdDim(requestMessage: DimLightMessage): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdDimChannel.request(requestMessage, nc); - } - -} diff --git a/test/actual_comparators/latest/frontend/src/messages/dimLight.ts b/test/actual_comparators/latest/frontend/src/messages/dimLight.ts deleted file mode 100644 index 7a8281027..000000000 --- a/test/actual_comparators/latest/frontend/src/messages/dimLight.ts +++ /dev/null @@ -1,45 +0,0 @@ - - - - -import { default as DimLightPayloadserereSchema } from '../schema/DimLightPayloadserere'; - - - -import { default as ResponseSchema } from '../schema/Response'; - - -export default class DimLight { - - - - dimLightPayloadserere:DimLightPayloadserereSchema; - - - - response:ResponseSchema; - - - constructor( - dimLightPayloadserere: DimLightPayloadserereSchema,response: ResponseSchema - ){ - - - - this.dimLightPayloadserere = dimLightPayloadserere; - - - - this.response = response; - - } - - /** - * Parses a JSON string to an object of DimLight message class. - * @param json string to be parsed as DimLight. - */ - public static toMessage(json: string): DimLight { - return JSON.parse(json); - } - -} diff --git a/test/actual_comparators/latest/frontend/src/messages/dimLightResponse.ts b/test/actual_comparators/latest/frontend/src/messages/dimLightResponse.ts deleted file mode 100644 index 2e0d9da0e..000000000 --- a/test/actual_comparators/latest/frontend/src/messages/dimLightResponse.ts +++ /dev/null @@ -1,30 +0,0 @@ - - - -import { default as ResponseSchema } from '../schema/Response'; - - -export default class DimLightResponse { - - - response:ResponseSchema; - - - constructor( - response: ResponseSchema - ){ - - - this.response = response; - - } - - /** - * Parses a JSON string to an object of DimLightResponse message class. - * @param json string to be parsed as DimLightResponse. - */ - public static toMessage(json: string): DimLightResponse { - return JSON.parse(json); - } - -} diff --git a/test/actual_comparators/latest/frontend/src/messages/lightMeasured.ts b/test/actual_comparators/latest/frontend/src/messages/lightMeasured.ts deleted file mode 100644 index 9e2010e22..000000000 --- a/test/actual_comparators/latest/frontend/src/messages/lightMeasured.ts +++ /dev/null @@ -1,30 +0,0 @@ - - - -import { default as LightMeasuredPayloadSchema } from '../schema/LightMeasuredPayload'; - - -export default class LightMeasured { - - - lightMeasuredPayload:LightMeasuredPayloadSchema; - - - constructor( - lightMeasuredPayload: LightMeasuredPayloadSchema - ){ - - - this.lightMeasuredPayload = lightMeasuredPayload; - - } - - /** - * Parses a JSON string to an object of LightMeasured message class. - * @param json string to be parsed as LightMeasured. - */ - public static toMessage(json: string): LightMeasured { - return JSON.parse(json); - } - -} diff --git a/test/actual_comparators/latest/frontend/src/messages/turnOnOff.ts b/test/actual_comparators/latest/frontend/src/messages/turnOnOff.ts deleted file mode 100644 index 483922274..000000000 --- a/test/actual_comparators/latest/frontend/src/messages/turnOnOff.ts +++ /dev/null @@ -1,30 +0,0 @@ - - - -import { default as TurnOnOffPayloadSchema } from '../schema/TurnOnOffPayload'; - - -export default class TurnOnOff { - - - turnOnOffPayload:TurnOnOffPayloadSchema; - - - constructor( - turnOnOffPayload: TurnOnOffPayloadSchema - ){ - - - this.turnOnOffPayload = turnOnOffPayload; - - } - - /** - * Parses a JSON string to an object of TurnOnOff message class. - * @param json string to be parsed as TurnOnOff. - */ - public static toMessage(json: string): TurnOnOff { - return JSON.parse(json); - } - -} diff --git a/test/actual_comparators/latest/frontend/src/messages/turnOnOffResponse.ts b/test/actual_comparators/latest/frontend/src/messages/turnOnOffResponse.ts deleted file mode 100644 index c25f1a5c5..000000000 --- a/test/actual_comparators/latest/frontend/src/messages/turnOnOffResponse.ts +++ /dev/null @@ -1,30 +0,0 @@ - - - -import { default as ResponseSchema } from '../schema/Response'; - - -export default class TurnOnOffResponse { - - - response:ResponseSchema; - - - constructor( - response: ResponseSchema - ){ - - - this.response = response; - - } - - /** - * Parses a JSON string to an object of TurnOnOffResponse message class. - * @param json string to be parsed as TurnOnOffResponse. - */ - public static toMessage(json: string): TurnOnOffResponse { - return JSON.parse(json); - } - -} diff --git a/test/actual_comparators/latest/frontend/src/schema/anonymous-schema-4.ts b/test/actual_comparators/latest/frontend/src/schema/anonymous-schema-4.ts deleted file mode 100644 index ef2cd616f..000000000 --- a/test/actual_comparators/latest/frontend/src/schema/anonymous-schema-4.ts +++ /dev/null @@ -1,11 +0,0 @@ - - - - -export default class anonymousSchema4 { - - - - - -} diff --git a/test/actual_comparators/latest/frontend/src/schema/anonymous-schema-5.ts b/test/actual_comparators/latest/frontend/src/schema/anonymous-schema-5.ts deleted file mode 100644 index e11ccc78d..000000000 --- a/test/actual_comparators/latest/frontend/src/schema/anonymous-schema-5.ts +++ /dev/null @@ -1,22 +0,0 @@ - - - - -export default class anonymousSchema5 { - - - - percentage?: Number - sentAt?: string - - - - status?: Number - statusMessage?: string - sentAt?: string - - - - - -} diff --git a/test/actual_comparators/latest/frontend/src/schema/lightMeasuredPayload.ts b/test/actual_comparators/latest/frontend/src/schema/lightMeasuredPayload.ts deleted file mode 100644 index a783f2728..000000000 --- a/test/actual_comparators/latest/frontend/src/schema/lightMeasuredPayload.ts +++ /dev/null @@ -1,13 +0,0 @@ - - - - -export default class lightMeasuredPayload { - - - lumens?: Number - sentAt?: string - - - -} diff --git a/test/actual_comparators/latest/frontend/src/schema/response.ts b/test/actual_comparators/latest/frontend/src/schema/response.ts deleted file mode 100644 index 0c80740f4..000000000 --- a/test/actual_comparators/latest/frontend/src/schema/response.ts +++ /dev/null @@ -1,14 +0,0 @@ - - - - -export default class response { - - - status?: Number - statusMessage?: string - sentAt?: string - - - -} diff --git a/test/actual_comparators/latest/frontend/src/schema/turnOnOffPayload.ts b/test/actual_comparators/latest/frontend/src/schema/turnOnOffPayload.ts deleted file mode 100644 index c9ea846aa..000000000 --- a/test/actual_comparators/latest/frontend/src/schema/turnOnOffPayload.ts +++ /dev/null @@ -1,13 +0,0 @@ - - - - -export default class turnOnOffPayload { - - - command?: string - sentAt?: string - - - -} diff --git a/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event.ts b/test/actual_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/actual_comparators/latest/frontend/src/tests/testclient/index.ts b/test/actual_comparators/latest/frontend/src/tests/testclient/index.ts deleted file mode 100644 index ecde61413..000000000 --- a/test/actual_comparators/latest/frontend/src/tests/testclient/index.ts +++ /dev/null @@ -1,54 +0,0 @@ - - - /** - * [object Object] - * @param requestMessage The message to publish. - */ - public publishToSmartylightingStreetlights10Event(requestMessage: LightMeasuredMessage): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10EventChannel.publish(requestMessage, nc); - } - - - /** - * [object Object] - * @param requestMessage The message to publish. - */ - public publishToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(requestMessage: LightMeasuredMessage): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.publish(requestMessage, nc); - } - - - /** - * [object Object] - * @param onRequest Called when request recieved. - * @param onReplyError Called when it was not possible to send the reply. - */ - public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOn(onRequest : (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, onReplyError : (err: NatsError) => void): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.reply(onRequest, onReplyError, nc); - } - - - /** - * [object Object] - * @param onRequest Called when request recieved. - * @param onReplyError Called when it was not possible to send the reply. - */ - public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOff(onRequest : (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, onReplyError : (err: NatsError) => void): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.reply(onRequest, onReplyError, nc); - } - - - /** - * [object Object] - * @param onRequest Called when request recieved. - * @param onReplyError Called when it was not possible to send the reply. - */ - public replyToSmartylightingStreetlights10ActionStreetlightIdDim(onRequest : (err?: NatsError, msg?: DimLightMessage) => DimLightResponseMessage, onReplyError : (err: NatsError) => void): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdDimChannel.reply(onRequest, onReplyError, nc); - } - diff --git a/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts deleted file mode 100644 index f0c9801c9..000000000 --- a/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts +++ /dev/null @@ -1,66 +0,0 @@ - -import {default as DimLightMessage} from '../../../messages/DimLight' -import {default as DimLightResponseMessage} from '../../../messages/DimLightResponse' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - -export function reply( - onRequest: (err?: NatsError, msg?: DimLightMessage) => DimLightResponseMessage, - onReplyError: (err: NatsError) => void, - , - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/dim', { - - "streetlightId": streetlightId - - }), (err, msg) => { - if (err) { - onRequest(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let requestData = new DimLightMessage(); - requestData.copyFrom(processedData); - - let responseObject = onRequest(undefined, requestData); - if (msg.reply) { - try { - let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); - nc.publish(msg.reply, requestData); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - console.error(error) - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts deleted file mode 100644 index 4393e85e3..000000000 --- a/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts +++ /dev/null @@ -1,66 +0,0 @@ - -import {default as TurnOnOffMessage} from '../../../messages/TurnOnOff' -import {default as TurnOnOffResponseMessage} from '../../../messages/TurnOnOffResponse' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - -export function reply( - onRequest: (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, - onReplyError: (err: NatsError) => void, - , - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/off', { - - "streetlightId": streetlightId - - }), (err, msg) => { - if (err) { - onRequest(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let requestData = new TurnOnOffMessage(); - requestData.copyFrom(processedData); - - let responseObject = onRequest(undefined, requestData); - if (msg.reply) { - try { - let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); - nc.publish(msg.reply, requestData); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - console.error(error) - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts deleted file mode 100644 index 366873ed1..000000000 --- a/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts +++ /dev/null @@ -1,66 +0,0 @@ - -import {default as TurnOnOffMessage} from '../../../messages/TurnOnOff' -import {default as TurnOnOffResponseMessage} from '../../../messages/TurnOnOffResponse' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - -export function reply( - onRequest: (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, - onReplyError: (err: NatsError) => void, - , - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/on', { - - "streetlightId": streetlightId - - }), (err, msg) => { - if (err) { - onRequest(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let requestData = new TurnOnOffMessage(); - requestData.copyFrom(processedData); - - let responseObject = onRequest(undefined, requestData); - if (msg.reply) { - try { - let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); - nc.publish(msg.reply, requestData); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - console.error(error) - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts deleted file mode 100644 index dba07ac3e..000000000 --- a/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts +++ /dev/null @@ -1,37 +0,0 @@ - -import {default as LightMeasuredMessage} from '../../../messages/LightMeasured' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - - -export function publish( - requestMessage: LightMeasuredMessage, - - streetlightId:string - , - nc?: Client - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var dataToPublish; - for(let hook in publishDataHooks){ - dataToPublish = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured', { - - "streetlightId": streetlightId - - }), dataToPublish); - resolve(); - }catch(e){ - reject(e); - } - }else{ - reject(new Error("Nats client is not connected")); - } - }); -}; - diff --git a/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event.ts b/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event.ts deleted file mode 100644 index 937d72bdb..000000000 --- a/test/actual_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event.ts +++ /dev/null @@ -1,33 +0,0 @@ - -import {default as LightMeasuredMessage} from '../../../messages/LightMeasured' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - - -export function publish( - requestMessage: LightMeasuredMessage, - - nc?: Client - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var dataToPublish; - for(let hook in publishDataHooks){ - dataToPublish = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/event/*', { - - }), dataToPublish); - resolve(); - }catch(e){ - reject(e); - } - }else{ - reject(new Error("Nats client is not connected")); - } - }); -}; - diff --git a/test/actual_comparators/latest/frontend/tsconfig.json b/test/actual_comparators/latest/frontend/tsconfig.json deleted file mode 100644 index 9fb047824..000000000 --- a/test/actual_comparators/latest/frontend/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "declaration": true, - "strict": true, - "noImplicitAny": true, - "removeComments": true, - "preserveConstEnums": true, - "sourceMap": true, - "outDir": "dist/", - "baseUrl": "./src" /* Base directory to resolve non-absolute module names. */, - "paths": { - "#messages": ["messages"], - "#schemas": ["schema"], - "#channels": ["channels"], - "#hooks": ["hooks"] - } - }, - "include": ["src/**/*"], - "exclude": ["node_modules", "**/*.spec.ts"] -} diff --git a/test/actual_comparators/latest/light-controller/README.md b/test/actual_comparators/latest/light-controller/README.md deleted file mode 100644 index 7d8ed191e..000000000 --- a/test/actual_comparators/latest/light-controller/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Streetlights Nats API for lightning controllers - -The Smartylighting Streetlights API allows you to remotely manage the city lights. - -This is for the lighting controllers, which assumed are multiple instances to ensure availability. - -### Check out its awesome features: - -* Turn a specific streetlight on/off 🌃 -* Dim a specific streetlight 😎 -* Receive real-time information about environmental lighting conditions 📈 - - - - -Available nats encodings: -https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings diff --git a/test/actual_comparators/latest/light-controller/package.json b/test/actual_comparators/latest/light-controller/package.json deleted file mode 100644 index 7f9bc65a6..000000000 --- a/test/actual_comparators/latest/light-controller/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - - - - "name": "streetlights-nats-api-for-lightning-controllers", - "description": "The Smartylighting Streetlights API allows you to remotely manage the city lights. This is for the lighting controllers, which assumed are multiple instances to ensure availability. ### Check out its awesome features: * Turn a specific streetlight on/off 🌃 * Dim a specific streetlight 😎 * Receive real-time information about environmental lighting conditions 📈 ", - "version": "1.0.0", - "main": "dist/index.js", - "types": "dist/index.d.ts", - "scripts": { - "watch": "tsc --watch", - "build": "tsc", - "start": "node src/api/index.js", - "postinstall": "link-module-alias", - "test": "mocha -r ts-node/register tests/\*\*/\*.spec.ts" - }, - "_moduleAliasIgnoreWarning": true, - "_moduleAliases": { - "#messages": "./src/messages", - "#schemas": "./src/schema", - "#channels": "./src/channels", - "#hooks": "./src/hooks" - }, - "dependencies": { - "@types/klaw-sync": "^6.0.0", - "@types/uuid": "3.4.5", - "@types/node": "13.9.5", - "klaw-sync": "6.0.0", - "link-module-alias": "^1.2.0", - "msgpack-lite": "^0.1.26", - "ts-nats": "1.2.4", - "node-yaml-config": "0.0.5", - "typescript": "3.4.3", - "uuid": "3.3.3", - "winston": "3.2.1", - "winston-daily-rotate-file": "3.10.0" - }, - "devDependencies": { - "@types/chai": "^4.2.11", - "@types/mocha": "^7.0.2", - "chai": "^4.2.0", - "mocha": "^7.1.1", - "ts-node": "^8.8.1" - } -} diff --git a/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts deleted file mode 100644 index 324a21f47..000000000 --- a/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts +++ /dev/null @@ -1,66 +0,0 @@ - -import {default as DimLightResponseMessage} from '../messages/DimLightResponse' -import {default as DimLightMessage} from '../messages/DimLight' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - -export function reply( - onRequest: (err?: NatsError, msg?: DimLightMessage) => DimLightResponseMessage, - onReplyError: (err: NatsError) => void, - , - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/dim', { - - "streetlightId": streetlightId - - }), (err, msg) => { - if (err) { - onRequest(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let requestData = new DimLightMessage(); - requestData.copyFrom(processedData); - - let responseObject = onRequest(undefined, requestData); - if (msg.reply) { - try { - let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); - nc.publish(msg.reply, requestData); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - console.error(error) - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts deleted file mode 100644 index e66e7d710..000000000 --- a/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts +++ /dev/null @@ -1,66 +0,0 @@ - -import {default as TurnOnOffResponseMessage} from '../messages/TurnOnOffResponse' -import {default as TurnOnOffMessage} from '../messages/TurnOnOff' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - -export function reply( - onRequest: (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, - onReplyError: (err: NatsError) => void, - , - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/off', { - - "streetlightId": streetlightId - - }), (err, msg) => { - if (err) { - onRequest(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let requestData = new TurnOnOffMessage(); - requestData.copyFrom(processedData); - - let responseObject = onRequest(undefined, requestData); - if (msg.reply) { - try { - let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); - nc.publish(msg.reply, requestData); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - console.error(error) - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts deleted file mode 100644 index 431746c1d..000000000 --- a/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts +++ /dev/null @@ -1,66 +0,0 @@ - -import {default as TurnOnOffResponseMessage} from '../messages/TurnOnOffResponse' -import {default as TurnOnOffMessage} from '../messages/TurnOnOff' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - -export function reply( - onRequest: (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, - onReplyError: (err: NatsError) => void, - , - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/on', { - - "streetlightId": streetlightId - - }), (err, msg) => { - if (err) { - onRequest(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let requestData = new TurnOnOffMessage(); - requestData.copyFrom(processedData); - - let responseObject = onRequest(undefined, requestData); - if (msg.reply) { - try { - let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); - nc.publish(msg.reply, requestData); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - console.error(error) - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts deleted file mode 100644 index d106cccbe..000000000 --- a/test/actual_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts +++ /dev/null @@ -1,37 +0,0 @@ - -import {default as LightMeasuredMessage} from '../messages/LightMeasured' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - - -export function publish( - requestMessage: LightMeasuredMessage, - - streetlightId:string - , - nc?: Client - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var dataToPublish; - for(let hook in publishDataHooks){ - dataToPublish = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured', { - - "streetlightId": streetlightId - - }), dataToPublish); - resolve(); - }catch(e){ - reject(e); - } - }else{ - reject(new Error("Nats client is not connected")); - } - }); -}; - diff --git a/test/actual_comparators/latest/light-controller/src/channels/utils.ts b/test/actual_comparators/latest/light-controller/src/channels/utils.ts deleted file mode 100644 index 8810b700d..000000000 --- a/test/actual_comparators/latest/light-controller/src/channels/utils.ts +++ /dev/null @@ -1,11 +0,0 @@ -export function realizeChannelName(channelName: string, parameters: any) { - let returnString = channelName; - returnString = returnString.replace('/', '.'); - for (let parameterName in parameters) { - returnString = returnString.replace( - `{${parameterName}}`, - parameters[parameterName] - ); - } - return returnString; -} diff --git a/test/actual_comparators/latest/light-controller/src/hooks.ts b/test/actual_comparators/latest/light-controller/src/hooks.ts deleted file mode 100644 index 7dfcbfbd9..000000000 --- a/test/actual_comparators/latest/light-controller/src/hooks.ts +++ /dev/null @@ -1,63 +0,0 @@ -const HOOKS_DIRNAME = './hooks'; -import * as fs from 'fs'; -import * as path from 'path'; -import * as walkSync from 'klaw-sync'; -export enum AvailableHooks { - RecievedData = 'RecievedData', - BeforeSendingData = 'BeforeSendingData' -} -export type RecievedDataHook = () => void; -export type BeforeSendingDataHook = (messageToSend: any) => void; -export var hooks: { - BeforeSendingData: BeforeSendingDataHook[]; - RecievedData: RecievedDataHook[]; -}; - -/** - * Loads the custom hooks. - */ -try { - const hooksPath = path.resolve(HOOKS_DIRNAME); - if (fs.existsSync(hooksPath)) { - const files = walkSync(hooksPath, { nodir: true }); - files.forEach((file: any) => { - require(file.path)((when: AvailableHooks, hook: any) => { - hooks[when].push(hook); - }); - }); - } -} catch (e) { - e.message = `There was a problem registering the hooks: ${e.message}`; - throw e; -} - -/** - * Register a hook for BeforeSendingData - * @param hook - */ -export async function registerBeforeSendingData(hook: BeforeSendingDataHook) { - hooks[AvailableHooks.BeforeSendingData] - ? hooks[AvailableHooks.BeforeSendingData].push(hook) - : [hook]; -} - -/** - * Register a hook for BeforeSendingData - * @param hook - */ -export async function registerRecievedData(hook: RecievedDataHook) { - hooks[AvailableHooks.RecievedData] - ? hooks[AvailableHooks.RecievedData].push(hook) - : [hook]; -} - -/** - * Get all the hooks registered at a given hook point/name. - * @param hook to find hooks for - * @returns all hooks - */ -export function getHooks(hook: AvailableHooks): Function[] { - if (!Array.isArray(hooks[hook])) return []; - // Return valid hooks - return hooks[hook]; -} diff --git a/test/actual_comparators/latest/light-controller/src/index.ts b/test/actual_comparators/latest/light-controller/src/index.ts deleted file mode 100644 index 380fa3473..000000000 --- a/test/actual_comparators/latest/light-controller/src/index.ts +++ /dev/null @@ -1,93 +0,0 @@ - - -import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; -import * as smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel from "./channels/Smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured"; -import * as smartylightingStreetlights10ActionStreetlightIdTurnOnChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/turn/on"; -import * as smartylightingStreetlights10ActionStreetlightIdTurnOffChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/turn/off"; -import * as smartylightingStreetlights10ActionStreetlightIdDimChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/dim"; -import {default as LightMeasuredMessage} from "./messages/LightMeasured"; -import {default as TurnOnOffResponseMessage} from "./messages/TurnOnOffResponse"; -import {default as TurnOnOffMessage} from "./messages/TurnOnOff"; -import {default as DimLightResponseMessage} from "./messages/DimLightResponse"; -import {default as DimLightMessage} from "./messages/DimLight"; - -export default class NatsAsyncApiClient { - public jsonClient?: Client; - public stringClient?: Client; - public binaryClient?: Client; - public options: NatsConnectionOptions; - - /** - * - * @param options options to use, payload is omitted if sat in the AsyncAPI document. - */ - constructor(options : NatsConnectionOptions) { - this.options = this.setDefaultOptions(options); - this.connect(); - } - - /** - * Try to connect to the NATS server with the different payloads. - */ - private async connect(){ - try{ - this.options.payload = Payload.JSON; - this.jsonClient = await connect(this.options); - }catch(e){ - console.error("Could not connect to NATS: " + e) - } - } - - /** - * Set the default options based on the AsyncAPI file. - * @param options to set - */ - private setDefaultOptions(options: NatsConnectionOptions){ - //If server binding options sat set the options - options.encoding = 'utf8'; - return options; - } - - /** - * Any measured values will be published through this method. - * @param requestMessage The message to publish. - */ - public publishToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(requestMessage: LightMeasuredMessage): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.publish(requestMessage, nc); - } - - - /** - * Get notified when a streetlight should be turned on. This should only be handled by 1 subscriber but ensured by request reply. - * @param onRequest Called when request recieved. - * @param onReplyError Called when it was not possible to send the reply. - */ - public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOn(onRequest : (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, onReplyError : (err: NatsError) => void): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.reply(onRequest, onReplyError, nc); - } - - - /** - * Get notified when a streetlight should be turned off. This should only be handled by 1 subscriber but ensured by request reply. - * @param onRequest Called when request recieved. - * @param onReplyError Called when it was not possible to send the reply. - */ - public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOff(onRequest : (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, onReplyError : (err: NatsError) => void): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.reply(onRequest, onReplyError, nc); - } - - - /** - * Get notified when a streetlight should be dimmed. This should only be handled by 1 subscriber but ensured by request reply. - * @param onRequest Called when request recieved. - * @param onReplyError Called when it was not possible to send the reply. - */ - public replyToSmartylightingStreetlights10ActionStreetlightIdDim(onRequest : (err?: NatsError, msg?: DimLightMessage) => DimLightResponseMessage, onReplyError : (err: NatsError) => void): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdDimChannel.reply(onRequest, onReplyError, nc); - } - -} diff --git a/test/actual_comparators/latest/light-controller/src/messages/dimLight.ts b/test/actual_comparators/latest/light-controller/src/messages/dimLight.ts deleted file mode 100644 index 7a8281027..000000000 --- a/test/actual_comparators/latest/light-controller/src/messages/dimLight.ts +++ /dev/null @@ -1,45 +0,0 @@ - - - - -import { default as DimLightPayloadserereSchema } from '../schema/DimLightPayloadserere'; - - - -import { default as ResponseSchema } from '../schema/Response'; - - -export default class DimLight { - - - - dimLightPayloadserere:DimLightPayloadserereSchema; - - - - response:ResponseSchema; - - - constructor( - dimLightPayloadserere: DimLightPayloadserereSchema,response: ResponseSchema - ){ - - - - this.dimLightPayloadserere = dimLightPayloadserere; - - - - this.response = response; - - } - - /** - * Parses a JSON string to an object of DimLight message class. - * @param json string to be parsed as DimLight. - */ - public static toMessage(json: string): DimLight { - return JSON.parse(json); - } - -} diff --git a/test/actual_comparators/latest/light-controller/src/messages/dimLightResponse.ts b/test/actual_comparators/latest/light-controller/src/messages/dimLightResponse.ts deleted file mode 100644 index 2e0d9da0e..000000000 --- a/test/actual_comparators/latest/light-controller/src/messages/dimLightResponse.ts +++ /dev/null @@ -1,30 +0,0 @@ - - - -import { default as ResponseSchema } from '../schema/Response'; - - -export default class DimLightResponse { - - - response:ResponseSchema; - - - constructor( - response: ResponseSchema - ){ - - - this.response = response; - - } - - /** - * Parses a JSON string to an object of DimLightResponse message class. - * @param json string to be parsed as DimLightResponse. - */ - public static toMessage(json: string): DimLightResponse { - return JSON.parse(json); - } - -} diff --git a/test/actual_comparators/latest/light-controller/src/messages/lightMeasured.ts b/test/actual_comparators/latest/light-controller/src/messages/lightMeasured.ts deleted file mode 100644 index 9e2010e22..000000000 --- a/test/actual_comparators/latest/light-controller/src/messages/lightMeasured.ts +++ /dev/null @@ -1,30 +0,0 @@ - - - -import { default as LightMeasuredPayloadSchema } from '../schema/LightMeasuredPayload'; - - -export default class LightMeasured { - - - lightMeasuredPayload:LightMeasuredPayloadSchema; - - - constructor( - lightMeasuredPayload: LightMeasuredPayloadSchema - ){ - - - this.lightMeasuredPayload = lightMeasuredPayload; - - } - - /** - * Parses a JSON string to an object of LightMeasured message class. - * @param json string to be parsed as LightMeasured. - */ - public static toMessage(json: string): LightMeasured { - return JSON.parse(json); - } - -} diff --git a/test/actual_comparators/latest/light-controller/src/messages/turnOnOff.ts b/test/actual_comparators/latest/light-controller/src/messages/turnOnOff.ts deleted file mode 100644 index 483922274..000000000 --- a/test/actual_comparators/latest/light-controller/src/messages/turnOnOff.ts +++ /dev/null @@ -1,30 +0,0 @@ - - - -import { default as TurnOnOffPayloadSchema } from '../schema/TurnOnOffPayload'; - - -export default class TurnOnOff { - - - turnOnOffPayload:TurnOnOffPayloadSchema; - - - constructor( - turnOnOffPayload: TurnOnOffPayloadSchema - ){ - - - this.turnOnOffPayload = turnOnOffPayload; - - } - - /** - * Parses a JSON string to an object of TurnOnOff message class. - * @param json string to be parsed as TurnOnOff. - */ - public static toMessage(json: string): TurnOnOff { - return JSON.parse(json); - } - -} diff --git a/test/actual_comparators/latest/light-controller/src/messages/turnOnOffResponse.ts b/test/actual_comparators/latest/light-controller/src/messages/turnOnOffResponse.ts deleted file mode 100644 index c25f1a5c5..000000000 --- a/test/actual_comparators/latest/light-controller/src/messages/turnOnOffResponse.ts +++ /dev/null @@ -1,30 +0,0 @@ - - - -import { default as ResponseSchema } from '../schema/Response'; - - -export default class TurnOnOffResponse { - - - response:ResponseSchema; - - - constructor( - response: ResponseSchema - ){ - - - this.response = response; - - } - - /** - * Parses a JSON string to an object of TurnOnOffResponse message class. - * @param json string to be parsed as TurnOnOffResponse. - */ - public static toMessage(json: string): TurnOnOffResponse { - return JSON.parse(json); - } - -} diff --git a/test/actual_comparators/latest/light-controller/src/schema/anonymous-schema-4.ts b/test/actual_comparators/latest/light-controller/src/schema/anonymous-schema-4.ts deleted file mode 100644 index ef2cd616f..000000000 --- a/test/actual_comparators/latest/light-controller/src/schema/anonymous-schema-4.ts +++ /dev/null @@ -1,11 +0,0 @@ - - - - -export default class anonymousSchema4 { - - - - - -} diff --git a/test/actual_comparators/latest/light-controller/src/schema/anonymous-schema-5.ts b/test/actual_comparators/latest/light-controller/src/schema/anonymous-schema-5.ts deleted file mode 100644 index e11ccc78d..000000000 --- a/test/actual_comparators/latest/light-controller/src/schema/anonymous-schema-5.ts +++ /dev/null @@ -1,22 +0,0 @@ - - - - -export default class anonymousSchema5 { - - - - percentage?: Number - sentAt?: string - - - - status?: Number - statusMessage?: string - sentAt?: string - - - - - -} diff --git a/test/actual_comparators/latest/light-controller/src/schema/lightMeasuredPayload.ts b/test/actual_comparators/latest/light-controller/src/schema/lightMeasuredPayload.ts deleted file mode 100644 index a783f2728..000000000 --- a/test/actual_comparators/latest/light-controller/src/schema/lightMeasuredPayload.ts +++ /dev/null @@ -1,13 +0,0 @@ - - - - -export default class lightMeasuredPayload { - - - lumens?: Number - sentAt?: string - - - -} diff --git a/test/actual_comparators/latest/light-controller/src/schema/response.ts b/test/actual_comparators/latest/light-controller/src/schema/response.ts deleted file mode 100644 index 0c80740f4..000000000 --- a/test/actual_comparators/latest/light-controller/src/schema/response.ts +++ /dev/null @@ -1,14 +0,0 @@ - - - - -export default class response { - - - status?: Number - statusMessage?: string - sentAt?: string - - - -} diff --git a/test/actual_comparators/latest/light-controller/src/schema/turnOnOffPayload.ts b/test/actual_comparators/latest/light-controller/src/schema/turnOnOffPayload.ts deleted file mode 100644 index c9ea846aa..000000000 --- a/test/actual_comparators/latest/light-controller/src/schema/turnOnOffPayload.ts +++ /dev/null @@ -1,13 +0,0 @@ - - - - -export default class turnOnOffPayload { - - - command?: string - sentAt?: string - - - -} diff --git a/test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/actual_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/actual_comparators/latest/light-controller/src/tests/testclient/index.ts b/test/actual_comparators/latest/light-controller/src/tests/testclient/index.ts deleted file mode 100644 index c7cd13ee6..000000000 --- a/test/actual_comparators/latest/light-controller/src/tests/testclient/index.ts +++ /dev/null @@ -1,41 +0,0 @@ - - - /** - * [object Object] - * @param onDataCallback Called when message recieved. - */ - public subscribeToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage) => void): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.subscribe(onDataCallback, nc); - } - - - /** - * [object Object] - * @param requestMessage The request message to send. - */ - public requestSmartylightingStreetlights10ActionStreetlightIdTurnOn(requestMessage: TurnOnOffMessage): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.request(requestMessage, nc); - } - - - /** - * [object Object] - * @param requestMessage The request message to send. - */ - public requestSmartylightingStreetlights10ActionStreetlightIdTurnOff(requestMessage: TurnOnOffMessage): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.request(requestMessage, nc); - } - - - /** - * [object Object] - * @param requestMessage The request message to send. - */ - public requestSmartylightingStreetlights10ActionStreetlightIdDim(requestMessage: DimLightMessage): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdDimChannel.request(requestMessage, nc); - } - diff --git a/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts deleted file mode 100644 index 008f5e2b9..000000000 --- a/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts +++ /dev/null @@ -1,46 +0,0 @@ - -import {default as DimLightResponseMessage} from '../../../messages/DimLightResponse' -import {default as DimLightMessage} from '../../../messages/DimLight' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - -export function request( - requestMessage: DimLightMessage, - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - resolve(DimLightResponseMessage.toMessage(processedData)); - } - }, { max: 1 }); - let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var requestData; - for(let hook in publishDataHooks){ - requestData = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/dim', { - - "streetlightId": streetlightId - - }), requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts deleted file mode 100644 index 91a2eb86a..000000000 --- a/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts +++ /dev/null @@ -1,46 +0,0 @@ - -import {default as TurnOnOffResponseMessage} from '../../../messages/TurnOnOffResponse' -import {default as TurnOnOffMessage} from '../../../messages/TurnOnOff' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - -export function request( - requestMessage: TurnOnOffMessage, - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - resolve(TurnOnOffResponseMessage.toMessage(processedData)); - } - }, { max: 1 }); - let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var requestData; - for(let hook in publishDataHooks){ - requestData = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/off', { - - "streetlightId": streetlightId - - }), requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts deleted file mode 100644 index e69df5569..000000000 --- a/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts +++ /dev/null @@ -1,46 +0,0 @@ - -import {default as TurnOnOffResponseMessage} from '../../../messages/TurnOnOffResponse' -import {default as TurnOnOffMessage} from '../../../messages/TurnOnOff' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - -export function request( - requestMessage: TurnOnOffMessage, - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - resolve(TurnOnOffResponseMessage.toMessage(processedData)); - } - }, { max: 1 }); - let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var requestData; - for(let hook in publishDataHooks){ - requestData = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/on', { - - "streetlightId": streetlightId - - }), requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts deleted file mode 100644 index e36a33357..000000000 --- a/test/actual_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts +++ /dev/null @@ -1,44 +0,0 @@ - -import {default as LightMeasuredMessage} from '../../../messages/LightMeasured' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - - -import {getHooks, AvailableHooks} from '#hooks'; -export function subscribe( - onDataCallback : (err?: NatsError, msg?: lightMeasured) => void, - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured', { - - "streetlightId": streetlightId - - }), (err, msg) => { - if(err){ - onDataCallback(err); - }else{ - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let publishedData = new lightMeasured(); - publishedData.copyFrom(processedData); - onDataCallback(undefined, publishedData); - } - }, subscribeOptions); - resolve(subscription); - }catch(e){ - reject(e); - } - }else{ - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/actual_comparators/latest/light-controller/tsconfig.json b/test/actual_comparators/latest/light-controller/tsconfig.json deleted file mode 100644 index 9fb047824..000000000 --- a/test/actual_comparators/latest/light-controller/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "declaration": true, - "strict": true, - "noImplicitAny": true, - "removeComments": true, - "preserveConstEnums": true, - "sourceMap": true, - "outDir": "dist/", - "baseUrl": "./src" /* Base directory to resolve non-absolute module names. */, - "paths": { - "#messages": ["messages"], - "#schemas": ["schema"], - "#channels": ["channels"], - "#hooks": ["hooks"] - } - }, - "include": ["src/**/*"], - "exclude": ["node_modules", "**/*.spec.ts"] -} From a419cd3738fcd913364112bf91090b3cbfd68f2f Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 30 Apr 2020 12:13:01 +0200 Subject: [PATCH 020/110] Added initial $$schema$$.spec.ts.njk test generation --- .../src/tests/schemas/$$schema$$.spec.ts.njk | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 template/src/tests/schemas/$$schema$$.spec.ts.njk diff --git a/template/src/tests/schemas/$$schema$$.spec.ts.njk b/template/src/tests/schemas/$$schema$$.spec.ts.njk new file mode 100644 index 000000000..44076fced --- /dev/null +++ b/template/src/tests/schemas/$$schema$$.spec.ts.njk @@ -0,0 +1,34 @@ +import { expect } from 'chai'; +import 'mocha'; + +{% macro testProp(schema, required=true) %} + {%- if schema.allOf() | length %} + {%- for allOfSchema in schema.allOf() %} + {{testProp(allOfSchema)}} + {%- endfor %} + {%- endif %} + + {%- if schema.oneOf() | length %} + test:{{schema.oneOf() | oneOfSchemaType}} + {%- endif %} + + {%- if schema.anyOf() | length %} + {%- for oneOfSchema in schema.anyOf() %} + {{testProp(oneOfSchema, false)}} + {%- endfor %} + {%- endif %} + + {%- if schema.properties() | length %} + {%- for propertyName, property in schema.properties() %} + {{ propertyName}}{% if not required or not property.required() %}?{% endif %}: {{ property.type() | toTsType }} + {%- endfor %} + {%- endif %} + +{% endmacro %} + +describe('{{schema.uid() | camelCase}}', () => { + it('should contain ', () => { + const result = helloTest(); + expect(result).to.equal(true); + }); +}); \ No newline at end of file From 29ceaa4771f6ee8dd969519fd9c1cb5303faef33 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 30 Apr 2020 12:13:18 +0200 Subject: [PATCH 021/110] Removed extra comma from Reply.njk --- partials/channel/Reply.njk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/partials/channel/Reply.njk b/partials/channel/Reply.njk index 1e9a40410..5f1918c08 100644 --- a/partials/channel/Reply.njk +++ b/partials/channel/Reply.njk @@ -3,10 +3,10 @@ export function reply( onRequest: (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message) => {{publishMessage.uid() | pascalCase}}Message, onReplyError: (err: NatsError) => void, - {% if parameters | length %},{% endif %} {% if parameters | length %} {{parameters | realizeParametersForChannel}} - {% endif %}{% if parameters | length %},{% endif %} + , + {% endif %} nc?: Client): Promise { return new Promise(async (resolve, reject) => { if (nc) { From 0626ac0e4c08af8424c041f1df208c414b706411 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 30 Apr 2020 12:13:41 +0200 Subject: [PATCH 022/110] Removed $$schema$$.spec.ts --- template/src/tests/schemas/$$schema$$.spec.ts | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 template/src/tests/schemas/$$schema$$.spec.ts diff --git a/template/src/tests/schemas/$$schema$$.spec.ts b/template/src/tests/schemas/$$schema$$.spec.ts deleted file mode 100644 index b529dce2a..000000000 --- a/template/src/tests/schemas/$$schema$$.spec.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { expect } from 'chai'; -import 'mocha'; - -describe('First test', () => { - it('should return true', () => { - const result = helloTest(); - expect(result).to.equal(true); - }); -}); \ No newline at end of file From 7f2428d9ba55a9e77f46c0ac771d512ffba63e5c Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 30 Apr 2020 12:30:38 +0200 Subject: [PATCH 023/110] add generator version requirement to .tp-config.json --- .tp-config.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .tp-config.json diff --git a/.tp-config.json b/.tp-config.json new file mode 100644 index 000000000..964cdbac6 --- /dev/null +++ b/.tp-config.json @@ -0,0 +1,3 @@ +{ + "generator": ">=0.41.0 <2.0.0" +} \ No newline at end of file From cc4c94768568612fbe7a26e9561a0026833034a5 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 30 Apr 2020 12:50:18 +0200 Subject: [PATCH 024/110] Converted to the new approach for filters. --- filters/all.js | 496 ++++++++++++++++++++++++------------------------- 1 file changed, 246 insertions(+), 250 deletions(-) diff --git a/filters/all.js b/filters/all.js index f66b2e93d..9e083bf27 100644 --- a/filters/all.js +++ b/filters/all.js @@ -1,279 +1,275 @@ -const URL = require('url'); -const path = require('path'); +const filter = module.exports; const _ = require('lodash'); -module.exports = ({ Nunjucks }) => { - Nunjucks.addFilter('kebabCase', string => { - return _.kebabCase(string); - }); +/** + * Figure out if our message content type or default content type matches a given payload. + * @param {*} messageContentType to check + * @param {*} defaultContentType to check + * @param {*} payload to find + */ +function containsPayload(messageContentType, defaultContentType, payload) { + if ( + (messageContentType != null && + messageContentType.toLowerCase() == payload) || + (defaultContentType != null && defaultContentType == payload) + ) { + return true; + } + return false; +} +filter.isBinaryPayload = (messageContentType, defaultContentType) => { + return containsPayload(messageContentType, defaultContentType, 'binary'); +} +filter.isStringPayload = (messageContentType, defaultContentType) => { + return containsPayload(messageContentType, defaultContentType, 'string'); +} +filter.isJsonPayload = (messageContentType, defaultContentType) => { + return containsPayload(messageContentType, defaultContentType, 'json'); +} - Nunjucks.addFilter('camelCase', string => { - return camelCase(string); - }); +filter.kebabCase = string => { + return _.kebabCase(string); +} +filter.camelCase = string => { + return camelCase(string); +} - /** - * Figure out if our message content type or default content type matches a given payload. - * @param {*} messageContentType to check - * @param {*} defaultContentType to check - * @param {*} payload to find - */ - function containsPayload(messageContentType, defaultContentType, payload) { - if ( - (messageContentType != null && - messageContentType.toLowerCase() == payload) || - (defaultContentType != null && defaultContentType == payload) - ) { - return true; - } - return false; - } - Nunjucks.addFilter( - 'isBinaryPayload', - (messageContentType, defaultContentType) => { - return containsPayload(messageContentType, defaultContentType, 'binary'); - } - ); - Nunjucks.addFilter( - 'isStringPayload', - (messageContentType, defaultContentType) => { - return containsPayload(messageContentType, defaultContentType, 'string'); - } - ); - Nunjucks.addFilter( - 'isJsonPayload', - (messageContentType, defaultContentType) => { - return containsPayload(messageContentType, defaultContentType, 'json'); - } - ); - /** - * Figure out if a payload is located in the document. - * @param {*} document to look through - * @param {*} payload to find - */ - function containsPayloadInDocument(document, payload) { - if ( - document.defaultContentType() != null && - document.defaultContentType().toLowerCase() == payload - ) { - return true; - } - if (document.channels() != null) { - for (let channelName in document.channels()) { - let channel = document.channels()[channelName]; - if ( - (channel.hasPublish() && - channel - .publish() - .message() - .contentType() != null && - channel - .publish() - .message() - .contentType() - .toLowerCase() == payload) || - (channel.hasSubscribe() && - channel - .subscribe() - .message() - .contentType() != null && - channel - .subscribe() - .message() - .contentType() - .toLowerCase() == payload) - ) { - return true; - } + +/** + * Figure out if a payload is located in the document. + * @param {*} document to look through + * @param {*} payload to find + */ +function containsPayloadInDocument(document, payload) { + if ( + document.defaultContentType() != null && + document.defaultContentType().toLowerCase() == payload + ) { + return true; + } + if (document.channels() != null) { + for (let channelName in document.channels()) { + let channel = document.channels()[channelName]; + if ( + (channel.hasPublish() && + channel + .publish() + .message() + .contentType() != null && + channel + .publish() + .message() + .contentType() + .toLowerCase() == payload) || + (channel.hasSubscribe() && + channel + .subscribe() + .message() + .contentType() != null && + channel + .subscribe() + .message() + .contentType() + .toLowerCase() == payload) + ) { + return true; } } - return false; } - Nunjucks.addFilter('containsBinaryPayload', document => { - return containsPayloadInDocument(document, 'binary'); - }); - Nunjucks.addFilter('containsStringPayload', document => { - return containsPayloadInDocument(document, 'string'); - }); - Nunjucks.addFilter('containsJsonPayload', document => { - return containsPayloadInDocument(document, 'json'); - }); + return false; +} +filter.containsBinaryPayload = document => { + return containsPayloadInDocument(document, 'binary'); +} +filter.containsStringPayload = document => { + return containsPayloadInDocument(document, 'string'); +} +filter.containsJsonPayload = document => { + return containsPayloadInDocument(document, 'json'); +} - function camelCase(string) { - return _.camelCase(string); - } +function camelCase(string) { + return _.camelCase(string); +} +function pascalCase(string) { + string = _.camelCase(string); + return string.charAt(0).toUpperCase() + string.slice(1); +} - Nunjucks.addFilter('firstLowerCase', string => { - return _.lowerFirst(string); - }); - Nunjucks.addFilter('firstUpperCase', string => { - return string.charAt(0).toUpperCase() + string.slice(1); - }); - Nunjucks.addFilter('pascalCase', string => { - return pascalCase(string); - }); - function pascalCase(string) { - string = _.camelCase(string); - return string.charAt(0).toUpperCase() + string.slice(1); - } - function toTsType(jsonSchemaType) { - switch (jsonSchemaType.toLowerCase()) { - case 'string': - return 'string'; - case 'integer': - case 'number': - return 'Number'; - case 'boolean': - return 'Boolean'; - } - } - Nunjucks.addFilter('toTsType', toTsType); - Nunjucks.addFilter('realizeParametersForChannel', parameters => { - let returnString = ''; - for (paramName in parameters) { - returnString += `${paramName}:${toTsType( - parameters[paramName].schema().type() - )},`; - } - if (returnString.length >= 1) { - returnString = returnString.slice(0, -1); - } - return returnString; - }); - Nunjucks.addFilter('constructorParameters', schema => { - let returnString = ''; - if (schema.allOf()) { - schema.allOf().forEach(element => { - returnString += `${camelCase(element.uid())}: ${pascalCase( - element.uid() - )}Schema,`; - }); - } else if (schema.oneOf()) { - returnString += `oneOf: ${getTypeFromOneOf(schema.oneOf())},`; - } else if (schema.anyOf()) { - schema.anyOf().forEach(element => { - returnString += `${camelCase(element.uid())}: ${pascalCase( - element.uid() - )}Schema,`; - }); - } else if (schema.uid()) { - returnString += `${camelCase(schema.uid())}: ${pascalCase( - schema.uid() - )}Schema,`; - } - if (returnString.length > 1) { - returnString = returnString.slice(0, -1); - } - return returnString; - }); - Nunjucks.addFilter('schemaConstructor', properties => { - let returnString = ''; - for (const [key, value] of Object.entries(properties)) { - returnString += `${key},`; - } - if (returnString.length > 1) { - returnString = returnString.slice(0, -1); - } - return returnString; - }); - Nunjucks.addFilter('print', string => { - console.log(string); - }); - Nunjucks.addFilter('oneLine', string => { - if (!string) return string; - return string.replace(/\n/g, ' '); - }); - function getTypeFromOneOf(oneFromSchema) { - let type = ''; - if (oneFromSchema.oneOf().length > 0) { - type += `${getTypeFromOneOf(oneFromSchema.oneOf())}Schema`; - } - for (var i = 0; i < oneOfSchema.length; i++) { - let schema = oneOfSchema[i]; - if (type !== '') { - type += '|'; - } - if (oneOfSchema.length == i + 1) { - type += schema.uid(); - } else { - type += schema.uid() + '|'; - } - } - return type; - } - Nunjucks.addFilter('oneOfSchemaType', getTypeFromOneOf); +filter.firstLowerCase = string => { + return _.lowerFirst(string); +} +filter.firstUpperCase = string => { + return string.charAt(0).toUpperCase() + string.slice(1); +} +filter.pascalCase = string => { + return pascalCase(string); +} - Nunjucks.addFilter('fileName', string => { - return _.camelCase(string); - }); - Nunjucks.addFilter('tsPayload', server => { - return 'STRING'; - }); - Nunjucks.addFilter('tsEncoding', server => { - return 'STRING'; - }); - Nunjucks.addFilter('isPubsub', channel => { - const tempChannel = channel._json; - if (tempChannel.bindings && tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'pubsub') { - return true; - } - return false; - }); - Nunjucks.addFilter('hasNatsBindings', obj => { - return obj.bindings && obj.bindings.nats; - }); - Nunjucks.addFilter('isRequestReply', channel => { - let tempChannel = channel._json; - if ( - tempChannel.bindings && - tempChannel.bindings.nats && - tempChannel.bindings.nats.is == 'requestReply' - ) { - return true; - } - return false; - }); - Nunjucks.addFilter('isRequester', channel => { - let tempChannel = channel._json; - if ( - tempChannel.bindings && - tempChannel.bindings.nats && - tempChannel.bindings.nats.is == 'requestReply' && - tempChannel.bindings.nats.requestReply && - tempChannel.bindings.nats.requestReply.is == 'requester' - ) { - return true; - } - return false; - }); - Nunjucks.addFilter('isReplier', channel => { - let tempChannel = channel._json; - if ( - tempChannel.bindings && - tempChannel.bindings.nats && - tempChannel.bindings.nats.is == 'requestReply' && - tempChannel.bindings.nats.requestReply && - tempChannel.bindings.nats.requestReply.is == 'replier' - ) { - return true; + +function toTsType(jsonSchemaType, property) { + switch (jsonSchemaType.toLowerCase()) { + case 'string': + return 'string'; + case 'integer': + case 'number': + return 'Number'; + case 'boolean': + return 'Boolean'; + case 'object': + if(property){ + return property.uid(); + }else{ + console.log(property) + return 'UndefinedObject'; + } + default: return 'Undefined'; + } +} +filter.toTsType = toTsType +filter.realizeParametersForChannel = parameters => { + let returnString = ''; + + for (paramName in parameters) { + returnString += `${paramName}:${toTsType( + parameters[paramName].schema().type() + )},`; + } + if (returnString.length >= 1) { + returnString = returnString.slice(0, -1); + } + return returnString; +} +filter.constructorParameters = schema => { + let returnString = ''; + if (schema.allOf()) { + schema.allOf().forEach(element => { + returnString += `${camelCase(element.uid())}: ${pascalCase( + element.uid() + )}Schema,`; + }); + } else if (schema.oneOf()) { + returnString += `oneOf: ${getTypeFromOneOf(schema.oneOf())},`; + } else if (schema.anyOf()) { + schema.anyOf().forEach(element => { + returnString += `${camelCase(element.uid())}: ${pascalCase( + element.uid() + )}Schema,`; + }); + } else if (schema.uid()) { + returnString += `${camelCase(schema.uid())}: ${pascalCase( + schema.uid() + )}Schema,`; + } + if (returnString.length > 1) { + returnString = returnString.slice(0, -1); + } + return returnString; +} +filter.schemaConstructor = properties => { + let returnString = ''; + for (const [key, value] of Object.entries(properties)) { + returnString += `${key},`; + } + if (returnString.length > 1) { + returnString = returnString.slice(0, -1); + } + return returnString; +} + + +function getTypeFromOneOf(oneFromSchema) { + let type = ''; + + if (oneFromSchema.oneOf().length > 0) { + type += `${getTypeFromOneOf(oneFromSchema.oneOf())}Schema`; + } + + for (var i = 0; i < oneOfSchema.length; i++) { + let schema = oneOfSchema[i]; + if (type !== '') { + type += '|'; } - return false; - }); -}; + if (oneOfSchema.length == i + 1) { + type += schema.uid(); + } else { + type += schema.uid() + '|'; + } + } + return type; +} +filter.oneOfSchemaType = getTypeFromOneOf +filter.fileName = string => { + return _.camelCase(string); +} +filter.tsPayload = server => { + return 'STRING'; +} +filter.tsEncoding = server => { + return 'STRING'; +} +filter.isPubsub = channel => { + const tempChannel = channel._json; + if (tempChannel.bindings && tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'pubsub') { + return true; + } + return false; +} +filter.hasNatsBindings = obj => { + return obj.bindings && obj.bindings.nats; +} +filter.isRequestReply = channel => { + let tempChannel = channel._json; + if ( + tempChannel.bindings && + tempChannel.bindings.nats && + tempChannel.bindings.nats.is == 'requestReply' + ) { + return true; + } + return false; +} +filter.isRequester = channel => { + let tempChannel = channel._json; + if ( + tempChannel.bindings && + tempChannel.bindings.nats && + tempChannel.bindings.nats.is == 'requestReply' && + tempChannel.bindings.nats.requestReply && + tempChannel.bindings.nats.requestReply.is == 'requester' + ) { + return true; + } + return false; +} +filter.isReplier = channel => { + let tempChannel = channel._json; + if ( + tempChannel.bindings && + tempChannel.bindings.nats && + tempChannel.bindings.nats.is == 'requestReply' && + tempChannel.bindings.nats.requestReply && + tempChannel.bindings.nats.requestReply.is == 'replier' + ) { + return true; + } + return false; +} From e9c420ae87e58ce10695a6a9df28d7101981543e Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 30 Apr 2020 12:54:34 +0200 Subject: [PATCH 025/110] $$everySchema$$.ts.njk now imports schema dependencies. --- template/src/schema/$$everySchema$$.ts.njk | 31 +++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/template/src/schema/$$everySchema$$.ts.njk b/template/src/schema/$$everySchema$$.ts.njk index 88dfb8053..8a956be89 100644 --- a/template/src/schema/$$everySchema$$.ts.njk +++ b/template/src/schema/$$everySchema$$.ts.njk @@ -18,13 +18,42 @@ {%- if schema.properties() | length %} {%- for propertyName, property in schema.properties() %} - {{ propertyName}}{% if not required or not property.required() %}?{% endif %}: {{ property.type() | toTsType }} + {{ propertyName}}{% if not required or not property.required() %}?{% endif %}: {{ property.type() | toTsType(property) }} {%- endfor %} {%- endif %} {% endmacro %} +{% macro importSchemas(schema) %} + {%- if schema.allOf() | length %} + {%- for allOfSchema in schema.allOf() %} + {{importSchemas(allOfSchema)}} + {%- endfor %} + {%- endif %} + + {%- if schema.oneOf() | length %} + {%- for oneOfSchema in schema.oneOf() %} + {{importSchemas(oneOfSchema)}} + {%- endfor %} + {%- endif %} + + {%- if schema.anyOf() | length %} + {%- for oneOfSchema in schema.anyOf() %} + {{importSchemas(oneOfSchema)}} + {%- endfor %} + {%- endif %} + + {%- if schema.properties() | length %} + {%- for propertyName, property in schema.properties() %} + {%- if property.type() === "object" %} +import { default as {{property.uid() | pascalCase}} } from './{{property.uid() | pascalCase}}'; + {%- endif %} + {%- endfor %} + {%- endif %} + +{% endmacro %} +{{ importSchemas(schema) }} export default class {{ schema.uid() | camelCase }} { {{ initProperties(schema) }} From b6dee33c32c867469add4b2a150a410b0f108fa6 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 30 Apr 2020 14:17:22 +0200 Subject: [PATCH 026/110] Added constructor for $$everySchema$$.ts.njk --- filters/all.js | 38 ++++++++++++++++++++-- template/src/messages/$$message$$.ts.njk | 2 +- template/src/schema/$$everySchema$$.ts.njk | 38 ++++++++++++++++++++-- 3 files changed, 73 insertions(+), 5 deletions(-) diff --git a/filters/all.js b/filters/all.js index 9e083bf27..ac4d989d8 100644 --- a/filters/all.js +++ b/filters/all.js @@ -138,7 +138,6 @@ function toTsType(jsonSchemaType, property) { if(property){ return property.uid(); }else{ - console.log(property) return 'UndefinedObject'; } default: return 'Undefined'; @@ -158,7 +157,7 @@ filter.realizeParametersForChannel = parameters => { } return returnString; } -filter.constructorParameters = schema => { +filter.messageConstructorParameters = schema => { let returnString = ''; if (schema.allOf()) { schema.allOf().forEach(element => { @@ -184,6 +183,38 @@ filter.constructorParameters = schema => { } return returnString; } +filter.schemaConstructorParameters = schema => { + let returnString = ''; + if (schema.allOf()) { + schema.allOf().forEach(element => { + returnString += `${camelCase(element.uid())}: ${pascalCase( + element.uid() + )},`; + }); + } + if (schema.oneOf()) { + returnString += `oneOf: ${getTypeFromOneOf(schema.oneOf())},`; + } + if (schema.anyOf()) { + schema.anyOf().forEach(element => { + returnString += `${camelCase(element.uid())}: ${pascalCase( + element.uid() + )},`; + }); + } + if (schema.properties() && schema.required()) { + schema.required().forEach(requiredPropertyName => { + const property = schema.properties()[requiredPropertyName] + if(property && property.required()){ + returnString += `${camelCase(requiredPropertyName)}: ${toTsType(property.type(), property)},`; + } + }); + } + if (returnString.length > 1) { + returnString = returnString.slice(0, -1); + } + return returnString; +} filter.schemaConstructor = properties => { let returnString = ''; for (const [key, value] of Object.entries(properties)) { @@ -223,6 +254,9 @@ filter.fileName = string => { filter.tsPayload = server => { return 'STRING'; } +filter.print = obj => { + console.log(JSON.stringify(obj, null, 4)) +} filter.tsEncoding = server => { return 'STRING'; } diff --git a/template/src/messages/$$message$$.ts.njk b/template/src/messages/$$message$$.ts.njk index cd640f61b..e48f2e962 100644 --- a/template/src/messages/$$message$$.ts.njk +++ b/template/src/messages/$$message$$.ts.njk @@ -63,7 +63,7 @@ export default class {{ message.name() | pascalCase}} { {{ initProperties(message.payload()) }} constructor( - {{message.payload() | constructorParameters}} + {{message.payload() | messageConstructorParameters}} ){ {{setConstructorProperties(message.payload())}} } diff --git a/template/src/schema/$$everySchema$$.ts.njk b/template/src/schema/$$everySchema$$.ts.njk index 8a956be89..cc629bee3 100644 --- a/template/src/schema/$$everySchema$$.ts.njk +++ b/template/src/schema/$$everySchema$$.ts.njk @@ -18,7 +18,7 @@ {%- if schema.properties() | length %} {%- for propertyName, property in schema.properties() %} - {{ propertyName}}{% if not required or not property.required() %}?{% endif %}: {{ property.type() | toTsType(property) }} + {{ propertyName | camelCase}}{% if not required or not property.required() %}?{% endif %}: {{ property.type() | toTsType(property) }} {%- endfor %} {%- endif %} @@ -45,17 +45,51 @@ {%- if schema.properties() | length %} {%- for propertyName, property in schema.properties() %} - {%- if property.type() === "object" %} + {%- if property.type() == "object" %} import { default as {{property.uid() | pascalCase}} } from './{{property.uid() | pascalCase}}'; {%- endif %} {%- endfor %} {%- endif %} {% endmacro %} +{%- macro setConstructorProperties(schema) %} + {%- if schema.allOf() | length %} + {%- for allOfSchema in schema.allOf() %} + {{setConstructorProperties(allOfSchema)}} + {%- endfor %} + {%- endif %} + {%- if schema.oneOf() | length %} + {{setProperty("oneOf")}} + {%- endif %} + {%- if schema.anyOf() | length %} + {%- for anyOfSchema in schema.anyOf() %} + {{setConstructorProperties(anyOfSchema)}} + {%- endfor %} + {%- endif %} + {%- if schema.properties() | length %} + + {%- for propertyName, property in schema.properties() %} + {% if property.required() %} + {{setProperty(propertyName)}} + {%- endif %} + {%- endfor %} + {%- endif %} + +{%- endmacro %} + +{%- macro setProperty(propertyName) %} + this.{{propertyName | camelCase}} = {{propertyName | camelCase}}; +{% endmacro %} + {{ importSchemas(schema) }} export default class {{ schema.uid() | camelCase }} { {{ initProperties(schema) }} + constructor( + {{schema | schemaConstructorParameters}} + ){ + {{setConstructorProperties(schema)}} + } } From 879cba2bffc6cb8e5cb24f06bea0d8ee9fdc5211 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 30 Apr 2020 14:21:21 +0200 Subject: [PATCH 027/110] Updated README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 465bc8beb..a21d6b449 100644 --- a/README.md +++ b/README.md @@ -24,3 +24,9 @@ These are the available hooks: | Hookname | Callback type | Description | | BeforeSendingData | (Message: any) => new data | Called before sending any data. | RevievedData | (recieved data: any) => new data | Called after data is recieved. + + + +### OBS + +* Always specify schema id, since we cant resolve the dependency correctly atm. \ No newline at end of file From 939829d1c3a1056b74a35ab7d3b064bfd6b09d22 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 30 Apr 2020 16:35:48 +0200 Subject: [PATCH 028/110] Added general filter --- .tp-config.json | 3 ++- package.json | 3 ++- template/package.json.njk | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.tp-config.json b/.tp-config.json index 964cdbac6..94a6bf421 100644 --- a/.tp-config.json +++ b/.tp-config.json @@ -1,3 +1,4 @@ { - "generator": ">=0.41.0 <2.0.0" + "generator": ">=0.41.0 <2.0.0", + "filters": [ "@asyncapi/generator-filters"] } \ No newline at end of file diff --git a/package.json b/package.json index d0a8b7e83..53063b7e5 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "license": "Apache-2.0", "dependencies": { "filenamify": "^4.1.0", - "lodash": "^4.17.15" + "lodash": "^4.17.15", + "@asyncapi/generator-filters": "^1.0.0" }, "devDependencies": { "chai": "^4.2.0", diff --git a/template/package.json.njk b/template/package.json.njk index 383cc2610..d2b768f75 100644 --- a/template/package.json.njk +++ b/template/package.json.njk @@ -23,7 +23,7 @@ "build": "tsc", "start": "node src/api/index.js", "postinstall": "link-module-alias", - "test": "mocha -r ts-node/register tests/\*\*/\*.spec.ts" + "test": "mocha -r ts-node/register tests/**/*.spec.ts" }, "_moduleAliasIgnoreWarning": true, "_moduleAliases": { From af4235aaab0efd7caa619fe8220d03b3ce4efe70 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 30 Apr 2020 19:33:28 +0200 Subject: [PATCH 029/110] Removed unused filters --- filters/all.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/filters/all.js b/filters/all.js index ac4d989d8..e197895b2 100644 --- a/filters/all.js +++ b/filters/all.js @@ -27,13 +27,6 @@ filter.isJsonPayload = (messageContentType, defaultContentType) => { return containsPayload(messageContentType, defaultContentType, 'json'); } -filter.kebabCase = string => { - return _.kebabCase(string); -} -filter.camelCase = string => { - return camelCase(string); -} - /** From 8598618527aa2fe41868bfe12d109efd1f64a19a Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Fri, 1 May 2020 17:25:17 +0200 Subject: [PATCH 030/110] Added $$objectSchema$$.ts instead of $$everySchema$$.ts --- .../schema/{$$everySchema$$.ts.njk => $$objectSchema$$.ts.njk} | 1 - 1 file changed, 1 deletion(-) rename template/src/schema/{$$everySchema$$.ts.njk => $$objectSchema$$.ts.njk} (99%) diff --git a/template/src/schema/$$everySchema$$.ts.njk b/template/src/schema/$$objectSchema$$.ts.njk similarity index 99% rename from template/src/schema/$$everySchema$$.ts.njk rename to template/src/schema/$$objectSchema$$.ts.njk index cc629bee3..bc68f5c76 100644 --- a/template/src/schema/$$everySchema$$.ts.njk +++ b/template/src/schema/$$objectSchema$$.ts.njk @@ -81,7 +81,6 @@ import { default as {{property.uid() | pascalCase}} } from './{{property.uid() | this.{{propertyName | camelCase}} = {{propertyName | camelCase}}; {% endmacro %} - {{ importSchemas(schema) }} export default class {{ schema.uid() | camelCase }} { From 114df404a933e550b484137cfeb5bf07f32b5835 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Fri, 1 May 2020 17:25:35 +0200 Subject: [PATCH 031/110] Fixed naming issue for channel filenames. --- hooks/filename-change.js | 8 ++++++++ hooks/rename-njk.js | 1 - template/src/index.ts.njk | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 hooks/filename-change.js diff --git a/hooks/filename-change.js b/hooks/filename-change.js new file mode 100644 index 000000000..d5d9bb493 --- /dev/null +++ b/hooks/filename-change.js @@ -0,0 +1,8 @@ +const filters = require("../filters/all") +module.exports = register => { + register('generate:changeFilename', (generator, hookArguments) => { + const currentFilename = hookArguments.originalFilename; + let newFilename = filters.pascalCase(currentFilename) + return newFilename + }); +}; \ No newline at end of file diff --git a/hooks/rename-njk.js b/hooks/rename-njk.js index 91e4f3782..e3bc79991 100644 --- a/hooks/rename-njk.js +++ b/hooks/rename-njk.js @@ -12,7 +12,6 @@ var renameAllSync = function(dir) { ) { let newName = path.basename(filepath, '.njk'); let newPath = path.resolve(dir, newName); - console.log(newPath); fs.renameSync(filepath, newPath); } }); diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index 29dc89030..fe7610fbf 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -7,7 +7,7 @@ import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; {%- for channelName, _ in asyncapi.channels() %} -import * as {{ channelName | camelCase }}Channel from "./channels/{{ channelName | firstUpperCase }}"; +import * as {{ channelName | camelCase }}Channel from "./channels/{{ channelName | pascalCase | firstUpperCase }}"; {%- endfor %} {%- for messageName, _ in asyncapi.allMessages() %} From 858cae15dfa370cc289255c9a5be77da1dabb1f5 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Fri, 1 May 2020 23:58:23 +0200 Subject: [PATCH 032/110] Fixed some issues with realize channel, arguments and hooks. --- filters/all.js | 19 +++++++ package-lock.json | 70 +++++++++++++++++++++++- partials/channel/Publish.njk | 16 ++---- partials/channel/Reply.njk | 10 +--- partials/channel/Request.njk | 11 ++-- partials/channel/Subscribe.njk | 63 ++++++++++----------- partials/index/Publish.njk | 15 ++++- partials/index/Reply.njk | 17 +++++- partials/index/Request.njk | 16 +++++- partials/index/Subscribe.njk | 15 ++++- template/src/channels/$$channel$$.ts.njk | 2 +- template/src/index.ts.njk | 8 +-- 12 files changed, 183 insertions(+), 79 deletions(-) diff --git a/filters/all.js b/filters/all.js index e197895b2..991958759 100644 --- a/filters/all.js +++ b/filters/all.js @@ -137,6 +137,25 @@ function toTsType(jsonSchemaType, property) { } } filter.toTsType = toTsType + +filter.realizeChannelName = (parameters, channelName) => { + + let returnString = '\`' + channelName + '\`'; + for (paramName in parameters) { + returnString = returnString.replace(`{${paramName}}`, `\${${paramName}}`); + } + return returnString; +} +filter.realizeParametersForChannelWithoutType = parameters => { + let returnString = ''; + for (paramName in parameters) { + returnString += `${paramName},`; + } + if (returnString.length >= 1) { + returnString = returnString.slice(0, -1); + } + return returnString; +} filter.realizeParametersForChannel = parameters => { let returnString = ''; diff --git a/package-lock.json b/package-lock.json index 7a7016f30..cecc509c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,16 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@asyncapi/generator-filters": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@asyncapi/generator-filters/-/generator-filters-1.0.0.tgz", + "integrity": "sha512-LcqLwUh/PqcHzIyEWxPT3pIehzif8d7aVq/CBWx0Hni7x/jsEbQhvtgT8LQpwHFLTZrNAKuxGivzOk3Ero+SQQ==", + "requires": { + "lodash": "^4.17.15", + "markdown-it": "^10.0.0", + "openapi-sampler": "^1.0.0-beta.15" + } + }, "ansi-colors": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", @@ -39,7 +49,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, "requires": { "sprintf-js": "~1.0.2" } @@ -300,6 +309,11 @@ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, + "entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", + "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" + }, "es-abstract": { "version": "1.17.5", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", @@ -383,6 +397,11 @@ "is-buffer": "~2.0.3" } }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -580,6 +599,22 @@ "esprima": "^4.0.0" } }, + "json-pointer": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/json-pointer/-/json-pointer-0.6.0.tgz", + "integrity": "sha1-jlAFUKaqxUZKRzN32leqbMIoKNc=", + "requires": { + "foreach": "^2.0.4" + } + }, + "linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "requires": { + "uc.micro": "^1.0.1" + } + }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -604,6 +639,23 @@ "chalk": "^2.4.2" } }, + "markdown-it": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "requires": { + "argparse": "^1.0.7", + "entities": "~2.0.0", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -725,6 +777,14 @@ "wrappy": "1" } }, + "openapi-sampler": { + "version": "1.0.0-beta.15", + "resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.0.0-beta.15.tgz", + "integrity": "sha512-wUD/vD3iBHKik/sME3uwUu4X3HFA53rDrPcVvLzgEELjHLbnTpSYfm4Jo9qZT1dPfBRowAnrF/VRQfOjL5QRAw==", + "requires": { + "json-pointer": "^0.6.0" + } + }, "p-limit": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", @@ -809,8 +869,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "string-width": { "version": "2.1.1", @@ -919,6 +978,11 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/partials/channel/Publish.njk b/partials/channel/Publish.njk index 9d3d8cfce..d0c9136e5 100644 --- a/partials/channel/Publish.njk +++ b/partials/channel/Publish.njk @@ -2,25 +2,21 @@ {% macro publish(channelName, parameters, publishMessage, server) %} export function publish( - requestMessage: {{publishMessage.uid() | pascalCase}}Message, + requestMessage: {{publishMessage.uid() | pascalCase}}Message, + nc: Client, {% if parameters | length %} {{parameters | realizeParametersForChannel}} - {% endif %}{% if parameters | length %},{% endif %} - nc?: Client + {% endif %} ): Promise { return new Promise(async (resolve, reject) => { if (nc) { try{ - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; + let publishDataHooks = Hooks.getHooks(Hooks.AvailableHooks.BeforeSendingData) as Hooks.BeforeSendingDataHook[]; var dataToPublish; - for(let hook in publishDataHooks){ + for(let hook of publishDataHooks){ dataToPublish = hook(requestMessage); } - nc.publish(realizeChannelName('{{channelName}}', { - {% for parameterName, parameter in parameters %} - "{{parameterName}}": {{parameterName}} - {% endfor %} - }), dataToPublish); + nc.publish({{parameters | realizeChannelName(channelName)}}, dataToPublish); resolve(); }catch(e){ reject(e); diff --git a/partials/channel/Reply.njk b/partials/channel/Reply.njk index 5f1918c08..bf472616e 100644 --- a/partials/channel/Reply.njk +++ b/partials/channel/Reply.njk @@ -3,11 +3,11 @@ export function reply( onRequest: (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message) => {{publishMessage.uid() | pascalCase}}Message, onReplyError: (err: NatsError) => void, + nc: Client, {% if parameters | length %} {{parameters | realizeParametersForChannel}} - , {% endif %} - nc?: Client): Promise { + ): Promise { return new Promise(async (resolve, reject) => { if (nc) { try { @@ -24,11 +24,7 @@ export function reply( {%- endif %} {%- endif %} - let subscription = nc.subscribe(realizeChannelName('{{channelName}}', { - {% for parameterName, parameter in parameters %} - "{{parameterName}}": {{parameterName}} - {% endfor %} - }), (err, msg) => { + let subscription = nc.subscribe({{parameters | realizeChannelName(channelName)}}, (err, msg) => { if (err) { onRequest(err); } else { diff --git a/partials/channel/Request.njk b/partials/channel/Request.njk index eca0b276c..b73a84f08 100644 --- a/partials/channel/Request.njk +++ b/partials/channel/Request.njk @@ -2,10 +2,11 @@ {% macro request(channelName, parameters, publishMessage, subscribtionMessage, server) %} export function request( requestMessage: {{publishMessage.uid() | pascalCase}}Message, + nc: Client, {% if parameters | length %} {{parameters | realizeParametersForChannel}} - {% endif %}{% if parameters | length %},{% endif %} - nc?: Client): Promise<{{subscribtionMessage.uid() | pascalCase}}Message> { + {% endif %} + ): Promise<{{subscribtionMessage.uid() | pascalCase}}Message> { return new Promise<{{subscribtionMessage.uid() | pascalCase}}Message>(async (resolve, reject) => { if (nc) { try { @@ -24,11 +25,7 @@ export function request( for(let hook in publishDataHooks){ requestData = hook(requestMessage); } - nc.publish(realizeChannelName('{{channelName}}', { - {% for parameterName, parameter in parameters %} - "{{parameterName}}": {{parameterName}} - {% endfor %} - }), requestData, inbox); + nc.publish({{parameters | realizeChannelName(channelName)}}, requestData, inbox); }catch(e){ reject(e); } diff --git a/partials/channel/Subscribe.njk b/partials/channel/Subscribe.njk index 4c43de417..7f3b47997 100644 --- a/partials/channel/Subscribe.njk +++ b/partials/channel/Subscribe.njk @@ -4,45 +4,38 @@ import {getHooks, AvailableHooks} from '#hooks'; export function subscribe( onDataCallback : (err?: NatsError, msg?: {{subscribtionMessage.uid() | camelCase}}) => void, + nc: Client, {% if parameters | length %} {{parameters | realizeParametersForChannel}} - {% endif %}{% if parameters | length %},{% endif %} - nc?: Client): Promise { + {% endif %} + ): Promise { return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let subscribeOptions: SubscriptionOptions = {}; - {%- if subscribtionMessage | hasNatsBindings %} - {%- if subscribtionMessage.bindings().nats().queue() | length %} - //If queue - subscribeOptions.queue = '{{subscribtionMessage.bindings().nats().queue().name()}}'; - {%- endif %} - {%- if subscribtionMessage.bindings().nats().unsubAfter() | length %} - //If unsubafter - subscribeOptions.max = {{subscribtionMessage.bindings().nats().unsubAfter()}}; - {%- endif %} - {%- endif %} + try{ + let subscribeOptions: SubscriptionOptions = {}; + {%- if subscribtionMessage | hasNatsBindings %} + {%- if subscribtionMessage.bindings().nats().queue() | length %} + //If queue + subscribeOptions.queue = '{{subscribtionMessage.bindings().nats().queue().name()}}'; + {%- endif %} + {%- if subscribtionMessage.bindings().nats().unsubAfter() | length %} + //If unsubafter + subscribeOptions.max = {{subscribtionMessage.bindings().nats().unsubAfter()}}; + {%- endif %} + {%- endif %} - let subscription = nc.subscribe(realizeChannelName('{{channelName}}', { - {% for parameterName, parameter in parameters %} - "{{parameterName}}": {{parameterName}} - {% endfor %} - }), (err, msg) => { - if(err){ - onDataCallback(err); - }else{ - let processedData = utils.processRecievedData(msg.data, Payload.{{server | tsPayload}}, '{{server | tsEncoding}}'); - let publishedData = new {{subscribtionMessage.name() | camelCase}}(); - publishedData.copyFrom(processedData); - onDataCallback(undefined, publishedData); - } - }, subscribeOptions); - resolve(subscription); - }catch(e){ - reject(e); - } - }else{ - reject(new Error("Nats client is not connected")); + let subscription = nc.subscribe({{parameters | realizeChannelName(channelName)}}, (err, msg) => { + if(err){ + onDataCallback(err); + }else{ + let processedData = utils.processRecievedData(msg.data, Payload.{{server | tsPayload}}, '{{server | tsEncoding}}'); + let publishedData = new {{subscribtionMessage.name() | camelCase}}(); + publishedData.copyFrom(processedData); + onDataCallback(undefined, publishedData); + } + }, subscribeOptions); + resolve(subscription); + }catch(e){ + reject(e); } }) } diff --git a/partials/index/Publish.njk b/partials/index/Publish.njk index 2edde59e9..f6f3002b8 100644 --- a/partials/index/Publish.njk +++ b/partials/index/Publish.njk @@ -1,10 +1,12 @@ -{% macro publish(defaultContentType, channelName, message, messageDescription) %} +{% macro publish(defaultContentType, channelName, message, messageDescription, parameters) %} /** * {{messageDescription}} * @param requestMessage The message to publish. */ - public publishTo{{channelName | pascalCase }}(requestMessage: {{ message.uid() | pascalCase }}Message): Promise { + public publishTo{{channelName | pascalCase }}(requestMessage: {{ message.uid() | pascalCase }}Message {% if parameters | length %} + ,{{parameters | realizeParametersForChannel}} + {% endif %}): Promise { {%- if message.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; {%- endif %} @@ -14,6 +16,13 @@ {%- if message.contentType() | isJsonPayload(defaultContentType) %} const nc: Client = this.jsonClient!; {%- endif %} - return {{ channelName | camelCase }}Channel.publish(requestMessage, nc); + if(nc){ + return {{ channelName | camelCase }}Channel.publish(requestMessage, nc + {% if parameters | length %} + ,{{parameters | realizeParametersForChannelWithoutType}} + {% endif %}); + }else{ + reject(new Error("Nats client is not connected")); + } } {% endmacro %} diff --git a/partials/index/Reply.njk b/partials/index/Reply.njk index 0140c2ac6..8b82ae807 100644 --- a/partials/index/Reply.njk +++ b/partials/index/Reply.njk @@ -1,11 +1,14 @@ -{% macro reply(defaultContentType, channelName, subscribeMessage, publishMessage, messageDescription) %} +{% macro reply(defaultContentType, channelName, subscribeMessage, publishMessage, messageDescription, parameters) %} /** * {{messageDescription}} * @param onRequest Called when request recieved. * @param onReplyError Called when it was not possible to send the reply. */ - public replyTo{{channelName | pascalCase }}(onRequest : (err?: NatsError, msg?: {{ subscribeMessage.uid() | pascalCase }}Message) => {{ publishMessage.uid() | pascalCase }}Message, onReplyError : (err: NatsError) => void): Promise { + public replyTo{{channelName | pascalCase }}(onRequest : (err?: NatsError, msg?: {{ subscribeMessage.uid() | pascalCase }}Message) => {{ publishMessage.uid() | pascalCase }}Message, onReplyError : (err: NatsError) => void + {% if parameters | length %} + ,{{parameters | realizeParametersForChannel}} + {% endif %}): Promise { {%- if subscribeMessage.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; {%- endif %} @@ -15,6 +18,14 @@ {%- if subscribeMessage.contentType() | isJsonPayload(defaultContentType) %} const nc: Client = this.jsonClient!; {%- endif %} - return {{ channelName | camelCase }}Channel.reply(onRequest, onReplyError, nc); + + if(nc){ + return {{ channelName | camelCase }}Channel.reply(onRequest, onReplyError, nc + {% if parameters | length %} + ,{{parameters | realizeParametersForChannelWithoutType}} + {% endif %}); + }else{ + reject(new Error("Nats client is not connected")); + } } {% endmacro %} diff --git a/partials/index/Request.njk b/partials/index/Request.njk index 78409278b..fcd3e2d67 100644 --- a/partials/index/Request.njk +++ b/partials/index/Request.njk @@ -1,10 +1,13 @@ -{% macro request(defaultContentType, channelName, publishMessage, subscribeMessage, messageDescription) %} +{% macro request(defaultContentType, channelName, publishMessage, subscribeMessage, messageDescription, parameters) %} /** * {{messageDescription}} * @param requestMessage The request message to send. */ - public request{{channelName | pascalCase }}(requestMessage: {{ publishMessage.uid() | pascalCase }}Message): Promise<{{ subscribeMessage.uid() | pascalCase }}Message> { + public request{{channelName | pascalCase }}(requestMessage: {{ publishMessage.uid() | pascalCase }}Message + {% if parameters | length %} + ,{{parameters | realizeParametersForChannel}} + {% endif %}): Promise<{{ subscribeMessage.uid() | pascalCase }}Message> { {%- if publishMessage.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; {%- endif %} @@ -14,6 +17,13 @@ {%- if publishMessage.contentType() | isJsonPayload(defaultContentType) %} const nc: Client = this.jsonClient!; {%- endif %} - return {{ channelName | camelCase }}Channel.request(requestMessage, nc); + if(nc){ + return {{ channelName | camelCase }}Channel.request(requestMessage, nc + {% if parameters | length %} + ,{{parameters | realizeParametersForChannelWithoutType}} + {% endif %}); + }else{ + reject(new Error("Nats client is not connected")); + } } {% endmacro %} diff --git a/partials/index/Subscribe.njk b/partials/index/Subscribe.njk index 3c70d6591..0ae9db7b0 100644 --- a/partials/index/Subscribe.njk +++ b/partials/index/Subscribe.njk @@ -1,10 +1,12 @@ -{% macro subscribe(defaultContentType, channelName, message, messageDescription) %} +{% macro subscribe(defaultContentType, channelName, message, messageDescription, parameters) %} /** * {{messageDescription}} * @param onDataCallback Called when message recieved. */ - public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsError, msg?: {{ message.uid() | pascalCase }}Message) => void): Promise { + public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsError, msg?: {{ message.uid() | pascalCase }}Message) => void, {% if parameters | length %} + ,{{parameters | realizeParametersForChannel}} + {% endif %}): Promise { {%- if message.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; {%- endif %} @@ -14,6 +16,13 @@ {%- if message.contentType() | isJsonPayload(defaultContentType) %} const nc: Client = this.jsonClient!; {%- endif %} - return {{ channelName | camelCase }}Channel.subscribe(onDataCallback, nc); + if(nc){ + return {{ channelName | camelCase }}Channel.subscribe(onDataCallback, nc + {% if parameters | length %} + ,{{parameters | realizeParametersForChannelWithoutType}} + {% endif %}); + }else{ + reject(new Error("Nats client is not connected")); + } } {% endmacro %} diff --git a/template/src/channels/$$channel$$.ts.njk b/template/src/channels/$$channel$$.ts.njk index c2de8b52b..14cf527b4 100644 --- a/template/src/channels/$$channel$$.ts.njk +++ b/template/src/channels/$$channel$$.ts.njk @@ -11,7 +11,7 @@ import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Messag {%- endif %} import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; +import * as Hooks from '#hooks'; {%- if channel | isRequestReply %} {%- if channel | isRequester %} {{ request(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index fe7610fbf..f39cf18b0 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -65,19 +65,19 @@ export default class NatsAsyncApiClient { {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{request(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description())}} + {{request(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- if channel | isReplier %} - {{reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description())}} + {{reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- endif %} {%- if channel | isPubsub %} {%- if channel.hasSubscribe() %} - {{subscribe(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.description())}} + {{subscribe(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- if channel.hasPublish() %} - {{publish(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.description())}} + {{publish(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- endif %} From 1471cdd60672c3e5c72d761833e4a28cdd3a01a9 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sat, 2 May 2020 01:02:04 +0200 Subject: [PATCH 033/110] Fixed some typescript errors --- partials/channel/Publish.njk | 4 +- partials/channel/Reply.njk | 18 +++-- partials/channel/Request.njk | 15 +++-- partials/channel/Subscribe.njk | 13 ++-- partials/index/Publish.njk | 2 +- partials/index/Reply.njk | 2 +- partials/index/Request.njk | 2 +- partials/index/Subscribe.njk | 4 +- template/src/channels/$$channel$$.ts.njk | 1 - template/src/channels/utils.ts | 11 --- template/src/hooks.ts | 4 +- template/src/tests/testclient/index.ts.njk | 67 +++++++++++++++++-- .../testchannels/$$channel$$.ts.njk | 8 +-- template/tsconfig.json | 2 +- 14 files changed, 108 insertions(+), 45 deletions(-) delete mode 100644 template/src/channels/utils.ts diff --git a/partials/channel/Publish.njk b/partials/channel/Publish.njk index d0c9136e5..004d90463 100644 --- a/partials/channel/Publish.njk +++ b/partials/channel/Publish.njk @@ -12,9 +12,9 @@ export function publish( if (nc) { try{ let publishDataHooks = Hooks.getHooks(Hooks.AvailableHooks.BeforeSendingData) as Hooks.BeforeSendingDataHook[]; - var dataToPublish; + var dataToPublish : any = requestMessage; for(let hook of publishDataHooks){ - dataToPublish = hook(requestMessage); + dataToPublish = hook(dataToPublish); } nc.publish({{parameters | realizeChannelName(channelName)}}, dataToPublish); resolve(); diff --git a/partials/channel/Reply.njk b/partials/channel/Reply.njk index bf472616e..efc1e42c0 100644 --- a/partials/channel/Reply.njk +++ b/partials/channel/Reply.njk @@ -28,15 +28,23 @@ export function reply( if (err) { onRequest(err); } else { - let processedData = utils.processRecievedData(msg.data, Payload.{{server | tsPayload}}, '{{server | tsEncoding}}'); - let requestData = new {{subscribtionMessage.name() | pascalCase}}Message(); - requestData.copyFrom(processedData); + + let receivedDataHooks = Hooks.getHooks(Hooks.AvailableHooks.RecievedData) as Hooks.RecievedDataHook[]; + var processedDataReceived : any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + let requestData = {{subscribtionMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); let responseObject = onRequest(undefined, requestData); if (msg.reply) { try { - let requestData = utils.beforeResponse(responseObject, Payload.{{server | tsPayload}}, '{{server | tsEncoding}}'); - nc.publish(msg.reply, requestData); + let publishDataHooks = Hooks.getHooks(Hooks.AvailableHooks.BeforeSendingData) as Hooks.BeforeSendingDataHook[]; + var dataToPublish : any = responseObject; + for(let hook of publishDataHooks){ + dataToPublish = hook(dataToPublish); + } + nc.publish(msg.reply, dataToPublish); } catch (e) { if (onReplyError) { onReplyError(e) diff --git a/partials/channel/Request.njk b/partials/channel/Request.njk index b73a84f08..a79e62c9e 100644 --- a/partials/channel/Request.njk +++ b/partials/channel/Request.njk @@ -15,15 +15,18 @@ export function request( if (err) { reject(err); } else { - let processedData = utils.processRecievedData(msg.data, Payload.{{server | tsPayload}}, '{{server | tsEncoding}}'); - resolve({{subscribtionMessage.uid() | pascalCase}}Message.toMessage(processedData)); + let receivedDataHooks = Hooks.getHooks(Hooks.AvailableHooks.RecievedData) as Hooks.RecievedDataHook[]; + var processedDataReceived : any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + resolve({{subscribtionMessage.uid() | pascalCase}}Message.toMessage(processedDataReceived)); } }, { max: 1 }); - let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var requestData; + let publishDataHooks = Hooks.getHooks(Hooks.AvailableHooks.BeforeSendingData) as Hooks.BeforeSendingDataHook[]; + var requestData : any = requestMessage; for(let hook in publishDataHooks){ - requestData = hook(requestMessage); + requestData = hook(requestData); } nc.publish({{parameters | realizeChannelName(channelName)}}, requestData, inbox); }catch(e){ diff --git a/partials/channel/Subscribe.njk b/partials/channel/Subscribe.njk index 7f3b47997..94a1c4622 100644 --- a/partials/channel/Subscribe.njk +++ b/partials/channel/Subscribe.njk @@ -3,7 +3,7 @@ import {getHooks, AvailableHooks} from '#hooks'; export function subscribe( - onDataCallback : (err?: NatsError, msg?: {{subscribtionMessage.uid() | camelCase}}) => void, + onDataCallback : (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message) => void, nc: Client, {% if parameters | length %} {{parameters | realizeParametersForChannel}} @@ -27,9 +27,14 @@ export function subscribe( if(err){ onDataCallback(err); }else{ - let processedData = utils.processRecievedData(msg.data, Payload.{{server | tsPayload}}, '{{server | tsEncoding}}'); - let publishedData = new {{subscribtionMessage.name() | camelCase}}(); - publishedData.copyFrom(processedData); + + let receivedDataHooks = Hooks.getHooks(Hooks.AvailableHooks.RecievedData) as Hooks.RecievedDataHook[]; + var processedDataReceived: any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + let publishedData = {{subscribtionMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); + onDataCallback(undefined, publishedData); } }, subscribeOptions); diff --git a/partials/index/Publish.njk b/partials/index/Publish.njk index f6f3002b8..a8efd2700 100644 --- a/partials/index/Publish.njk +++ b/partials/index/Publish.njk @@ -22,7 +22,7 @@ ,{{parameters | realizeParametersForChannelWithoutType}} {% endif %}); }else{ - reject(new Error("Nats client is not connected")); + throw new Error("Nats client is not connected"); } } {% endmacro %} diff --git a/partials/index/Reply.njk b/partials/index/Reply.njk index 8b82ae807..a13272c60 100644 --- a/partials/index/Reply.njk +++ b/partials/index/Reply.njk @@ -25,7 +25,7 @@ ,{{parameters | realizeParametersForChannelWithoutType}} {% endif %}); }else{ - reject(new Error("Nats client is not connected")); + throw new Error("Nats client is not connected"); } } {% endmacro %} diff --git a/partials/index/Request.njk b/partials/index/Request.njk index fcd3e2d67..906f8d256 100644 --- a/partials/index/Request.njk +++ b/partials/index/Request.njk @@ -23,7 +23,7 @@ ,{{parameters | realizeParametersForChannelWithoutType}} {% endif %}); }else{ - reject(new Error("Nats client is not connected")); + throw new Error("Nats client is not connected"); } } {% endmacro %} diff --git a/partials/index/Subscribe.njk b/partials/index/Subscribe.njk index 0ae9db7b0..fd6818492 100644 --- a/partials/index/Subscribe.njk +++ b/partials/index/Subscribe.njk @@ -4,7 +4,7 @@ * {{messageDescription}} * @param onDataCallback Called when message recieved. */ - public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsError, msg?: {{ message.uid() | pascalCase }}Message) => void, {% if parameters | length %} + public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsError, msg?: {{ message.uid() | pascalCase }}Message) => void {% if parameters | length %} ,{{parameters | realizeParametersForChannel}} {% endif %}): Promise { {%- if message.contentType() | isBinaryPayload(defaultContentType) %} @@ -22,7 +22,7 @@ ,{{parameters | realizeParametersForChannelWithoutType}} {% endif %}); }else{ - reject(new Error("Nats client is not connected")); + throw new Error("Nats client is not connected"); } } {% endmacro %} diff --git a/template/src/channels/$$channel$$.ts.njk b/template/src/channels/$$channel$$.ts.njk index 14cf527b4..80739eb44 100644 --- a/template/src/channels/$$channel$$.ts.njk +++ b/template/src/channels/$$channel$$.ts.njk @@ -10,7 +10,6 @@ import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '../messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' {%- endif %} import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; import * as Hooks from '#hooks'; {%- if channel | isRequestReply %} {%- if channel | isRequester %} diff --git a/template/src/channels/utils.ts b/template/src/channels/utils.ts deleted file mode 100644 index 8810b700d..000000000 --- a/template/src/channels/utils.ts +++ /dev/null @@ -1,11 +0,0 @@ -export function realizeChannelName(channelName: string, parameters: any) { - let returnString = channelName; - returnString = returnString.replace('/', '.'); - for (let parameterName in parameters) { - returnString = returnString.replace( - `{${parameterName}}`, - parameters[parameterName] - ); - } - return returnString; -} diff --git a/template/src/hooks.ts b/template/src/hooks.ts index 7dfcbfbd9..361f56592 100644 --- a/template/src/hooks.ts +++ b/template/src/hooks.ts @@ -6,8 +6,8 @@ export enum AvailableHooks { RecievedData = 'RecievedData', BeforeSendingData = 'BeforeSendingData' } -export type RecievedDataHook = () => void; -export type BeforeSendingDataHook = (messageToSend: any) => void; +export type RecievedDataHook = (receivedData: any) => string; +export type BeforeSendingDataHook = (messageToSend: any) => string; export var hooks: { BeforeSendingData: BeforeSendingDataHook[]; RecievedData: RecievedDataHook[]; diff --git a/template/src/tests/testclient/index.ts.njk b/template/src/tests/testclient/index.ts.njk index b63286917..3728f99f6 100644 --- a/template/src/tests/testclient/index.ts.njk +++ b/template/src/tests/testclient/index.ts.njk @@ -4,24 +4,83 @@ {%- from "../../../../partials/index/Request.njk" import request %} {%- from "../../../../partials/index/Subscribe.njk" import subscribe %} +import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; + +{%- for channelName, _ in asyncapi.channels() %} +import * as {{ channelName | camelCase }}Channel from "./testchannels/{{ channelName | pascalCase | firstUpperCase }}"; +{%- endfor %} + +{%- for messageName, _ in asyncapi.allMessages() %} +import {default as {{ messageName | pascalCase }}Message} from "../../../src/messages/{{ messageName | pascalCase }}"; +{%- endfor %} + +export default class NatsAsyncApiClient { + public jsonClient?: Client; + public stringClient?: Client; + public binaryClient?: Client; + public options: NatsConnectionOptions; + + /** + * + * @param options options to use, payload is omitted if sat in the AsyncAPI document. + */ + constructor(options : NatsConnectionOptions) { + this.options = this.setDefaultOptions(options); + this.connect(); + } + + /** + * Try to connect to the NATS server with the different payloads. + */ + private async connect(){ + try{ + {%- if asyncapi | containsBinaryPayload %} + this.options.payload = Payload.BINARY; + this.binaryClient = await connect(this.options); + {%- endif %} + {%- if asyncapi | containsStringPayload %} + this.options.payload = Payload.STRING; + this.stringClient = await connect(this.options); + {%- endif %} + {%- if asyncapi | containsJsonPayload %} + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + {%- endif %} + }catch(e){ + console.error("Could not connect to NATS: " + e) + } + } + + /** + * Set the default options based on the AsyncAPI file. + * @param options to set + */ + private setDefaultOptions(options: NatsConnectionOptions){ + //If server binding options sat set the options + options.encoding = 'utf8'; + return options; + } + {%- for channelName, channel in asyncapi.channels() %} {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{reply(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel)}} + {{reply(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- if channel | isReplier %} - {{request(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel)}} + {{request(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- endif %} {%- if channel | isPubsub %} {%- if channel.hasSubscribe() %} - {{publish(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel)}} + {{publish(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- if channel.hasPublish() %} - {{subscribe(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel)}} + {{subscribe(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- endif %} {%- endfor %} + +} \ No newline at end of file diff --git a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk index 866b107a3..559b5279f 100644 --- a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk +++ b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk @@ -4,14 +4,14 @@ {%- from "../../../../../partials/channel/Request.njk" import request %} {%- from "../../../../../partials/channel/Subscribe.njk" import subscribe %} {%- if channel.hasPublish() %} -import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '../../../messages/{{ channel.publish().message(0).uid() | pascalCase}}' +import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '../../../../src/messages/{{ channel.publish().message(0).uid() | pascalCase}}' {%- endif %} {%- if channel.hasSubscribe() %} -import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '../../../messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' +import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '../../../../src//messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' {%- endif %} - import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; +import * as Hooks from '#hooks'; + {%- if channel | isRequestReply %} {%- if channel | isRequester %} diff --git a/template/tsconfig.json b/template/tsconfig.json index 9fb047824..e2cedf397 100644 --- a/template/tsconfig.json +++ b/template/tsconfig.json @@ -17,6 +17,6 @@ "#hooks": ["hooks"] } }, - "include": ["src/**/*"], + "include": ["src"], "exclude": ["node_modules", "**/*.spec.ts"] } From 483f2f1cd449fe535ebbde361ac68245c0fd0241 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Tue, 5 May 2020 11:21:55 +0200 Subject: [PATCH 034/110] Fixed all of the known problems for a stable commit --- filters/all.js | 92 +++++++++++++++------ partials/channel/Publish.njk | 2 +- partials/channel/Reply.njk | 4 +- partials/channel/Request.njk | 6 +- partials/channel/Subscribe.njk | 4 +- template/src/hooks.ts | 18 ++-- template/src/messages/$$message$$.ts.njk | 50 ++++------- template/src/schema/$$objectSchema$$.ts.njk | 54 ++++-------- 8 files changed, 117 insertions(+), 113 deletions(-) diff --git a/filters/all.js b/filters/all.js index 991958759..583dde347 100644 --- a/filters/all.js +++ b/filters/all.js @@ -129,7 +129,7 @@ function toTsType(jsonSchemaType, property) { return 'Boolean'; case 'object': if(property){ - return property.uid(); + return property.uid() + 'Schema'; }else{ return 'UndefinedObject'; } @@ -177,15 +177,8 @@ filter.messageConstructorParameters = schema => { element.uid() )}Schema,`; }); - } else if (schema.oneOf()) { - returnString += `oneOf: ${getTypeFromOneOf(schema.oneOf())},`; - } else if (schema.anyOf()) { - schema.anyOf().forEach(element => { - returnString += `${camelCase(element.uid())}: ${pascalCase( - element.uid() - )}Schema,`; - }); - } else if (schema.uid()) { + } + if (schema.uid() && schema.type() === "object") { returnString += `${camelCase(schema.uid())}: ${pascalCase( schema.uid() )}Schema,`; @@ -195,6 +188,59 @@ filter.messageConstructorParameters = schema => { } return returnString; } +function genericImports(schema, imports) { + if(!imports){ + imports = {} + } + if (schema.allOf()) { + for(var allOf of schema.allOf()){ + imports = genericImports(allOf, imports); + } + } + if (schema.oneOf()) { + for(var oneOf of schema.oneOf()){ + imports = genericImports(oneOf, imports); + } + } + if (schema.anyOf()) { + for(var anyOf of schema.anyOf()){ + imports = genericImports(anyOf, imports); + } + } + if (schema.type() && schema.type() === "object"){ + imports[schema.uid()] = `import { default as ${pascalCase(schema.uid())}Schema } from '#schemas/${pascalCase(schema.uid())}';` + } + return imports; +} +function schemaImports(schema, imports) { + if(!imports){ + imports = {} + } + if (schema.allOf()) { + for(var allOf of schema.allOf()){ + imports = schemaImports(allOf, imports) + } + } + if (schema.oneOf()) { + for(var oneOf of schema.oneOf()){ + imports = schemaImports(oneOf, imports) + } + } + if (schema.anyOf()) { + for(var anyOf of schema.anyOf()){ + imports = schemaImports(anyOf, imports) + } + } + if (schema.properties()){ + for(const [_, property] of Object.entries(schema.properties())){ + imports = genericImports(property, imports) + } + } + return imports; +} +filter.genericImports = genericImports; +filter.schemaImports = schemaImports; + filter.schemaConstructorParameters = schema => { let returnString = ''; if (schema.allOf()) { @@ -214,23 +260,16 @@ filter.schemaConstructorParameters = schema => { )},`; }); } - if (schema.properties() && schema.required()) { - schema.required().forEach(requiredPropertyName => { - const property = schema.properties()[requiredPropertyName] - if(property && property.required()){ - returnString += `${camelCase(requiredPropertyName)}: ${toTsType(property.type(), property)},`; + if (schema.type() && schema.type() === "object"){ + if (schema.properties() && schema.required()) { + for(const [propertyName, property] of Object.entries(schema.properties())){ + if(property.required()){ + returnString += `${camelCase(propertyName)}: ${toTsType(property.type(), property)},`; + } } - }); - } - if (returnString.length > 1) { - returnString = returnString.slice(0, -1); - } - return returnString; -} -filter.schemaConstructor = properties => { - let returnString = ''; - for (const [key, value] of Object.entries(properties)) { - returnString += `${key},`; + } + }else if(schema.type()){ + returnString += `type: ${toTsType(schema.type())},`; } if (returnString.length > 1) { returnString = returnString.slice(0, -1); @@ -239,6 +278,7 @@ filter.schemaConstructor = properties => { } + function getTypeFromOneOf(oneFromSchema) { let type = ''; diff --git a/partials/channel/Publish.njk b/partials/channel/Publish.njk index 004d90463..4e09e6c2b 100644 --- a/partials/channel/Publish.njk +++ b/partials/channel/Publish.njk @@ -11,7 +11,7 @@ export function publish( return new Promise(async (resolve, reject) => { if (nc) { try{ - let publishDataHooks = Hooks.getHooks(Hooks.AvailableHooks.BeforeSendingData) as Hooks.BeforeSendingDataHook[]; + let publishDataHooks = Hooks.getBeforeSendingDataHook(); var dataToPublish : any = requestMessage; for(let hook of publishDataHooks){ dataToPublish = hook(dataToPublish); diff --git a/partials/channel/Reply.njk b/partials/channel/Reply.njk index efc1e42c0..c65e5126b 100644 --- a/partials/channel/Reply.njk +++ b/partials/channel/Reply.njk @@ -29,7 +29,7 @@ export function reply( onRequest(err); } else { - let receivedDataHooks = Hooks.getHooks(Hooks.AvailableHooks.RecievedData) as Hooks.RecievedDataHook[]; + let receivedDataHooks = Hooks.getRecievedDataHook(); var processedDataReceived : any = msg.data; for(let hook of receivedDataHooks){ processedDataReceived = hook(processedDataReceived); @@ -39,7 +39,7 @@ export function reply( let responseObject = onRequest(undefined, requestData); if (msg.reply) { try { - let publishDataHooks = Hooks.getHooks(Hooks.AvailableHooks.BeforeSendingData) as Hooks.BeforeSendingDataHook[]; + let publishDataHooks = Hooks.getBeforeSendingDataHook(); var dataToPublish : any = responseObject; for(let hook of publishDataHooks){ dataToPublish = hook(dataToPublish); diff --git a/partials/channel/Request.njk b/partials/channel/Request.njk index a79e62c9e..6de19a78d 100644 --- a/partials/channel/Request.njk +++ b/partials/channel/Request.njk @@ -15,7 +15,7 @@ export function request( if (err) { reject(err); } else { - let receivedDataHooks = Hooks.getHooks(Hooks.AvailableHooks.RecievedData) as Hooks.RecievedDataHook[]; + let receivedDataHooks = Hooks.getRecievedDataHook(); var processedDataReceived : any = msg.data; for(let hook of receivedDataHooks){ processedDataReceived = hook(processedDataReceived); @@ -23,9 +23,9 @@ export function request( resolve({{subscribtionMessage.uid() | pascalCase}}Message.toMessage(processedDataReceived)); } }, { max: 1 }); - let publishDataHooks = Hooks.getHooks(Hooks.AvailableHooks.BeforeSendingData) as Hooks.BeforeSendingDataHook[]; + let publishDataHooks = Hooks.getBeforeSendingDataHook(); var requestData : any = requestMessage; - for(let hook in publishDataHooks){ + for(let hook of publishDataHooks){ requestData = hook(requestData); } nc.publish({{parameters | realizeChannelName(channelName)}}, requestData, inbox); diff --git a/partials/channel/Subscribe.njk b/partials/channel/Subscribe.njk index 94a1c4622..5c0880050 100644 --- a/partials/channel/Subscribe.njk +++ b/partials/channel/Subscribe.njk @@ -1,7 +1,5 @@ {% macro subscribe(channelName, parameters, subscribtionMessage, server) %} - -import {getHooks, AvailableHooks} from '#hooks'; export function subscribe( onDataCallback : (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message) => void, nc: Client, @@ -28,7 +26,7 @@ export function subscribe( onDataCallback(err); }else{ - let receivedDataHooks = Hooks.getHooks(Hooks.AvailableHooks.RecievedData) as Hooks.RecievedDataHook[]; + let receivedDataHooks = Hooks.getRecievedDataHook(); var processedDataReceived: any = msg.data; for(let hook of receivedDataHooks){ processedDataReceived = hook(processedDataReceived); diff --git a/template/src/hooks.ts b/template/src/hooks.ts index 361f56592..af87046e9 100644 --- a/template/src/hooks.ts +++ b/template/src/hooks.ts @@ -51,13 +51,15 @@ export async function registerRecievedData(hook: RecievedDataHook) { : [hook]; } -/** - * Get all the hooks registered at a given hook point/name. - * @param hook to find hooks for - * @returns all hooks - */ -export function getHooks(hook: AvailableHooks): Function[] { - if (!Array.isArray(hooks[hook])) return []; + +export function getRecievedDataHook(): RecievedDataHook[] { + if (!Array.isArray(hooks[AvailableHooks.RecievedData])) return []; + // Return valid hooks + return hooks[AvailableHooks.RecievedData]; +} + +export function getBeforeSendingDataHook(): BeforeSendingDataHook[] { + if (!Array.isArray(hooks[AvailableHooks.BeforeSendingData])) return []; // Return valid hooks - return hooks[hook]; + return hooks[AvailableHooks.BeforeSendingData]; } diff --git a/template/src/messages/$$message$$.ts.njk b/template/src/messages/$$message$$.ts.njk index e48f2e962..c9d91f6bb 100644 --- a/template/src/messages/$$message$$.ts.njk +++ b/template/src/messages/$$message$$.ts.njk @@ -3,14 +3,20 @@ {%- for allOfSchema in schema.allOf() %} {{initProperties(allOfSchema)}} {%- endfor %} - {%- elif schema.oneOf() | length %} + {%- endif %} + {%- if schema.oneOf() | length %} oneOf:{{schema.oneOf() | oneOfSchemaType}} - {%- elif schema.anyOf() | length %} + {%- endif %} + {%- if schema.anyOf() | length %} {%- for anyOfSchema in schema.anyOf() %} {{initProperties(anyOfSchema, false)}} {%- endfor %} - {%- elif schema.uid() | length %} + {%- endif %} + + {%- if schema.type() == "object" %} {{initProperty(schema.uid(), schema.uid())}} + {%- elif schema.type() | length%} + type: {{ schema.type() | toTsType }} {%- endif %} {%- endmacro %} {%- macro setConstructorProperties(schema) %} @@ -18,32 +24,12 @@ {%- for allOfSchema in schema.allOf() %} {{setConstructorProperties(allOfSchema)}} {%- endfor %} - {%- elif schema.oneOf() | length %} - {{setProperty("oneOf")}} - {%- elif schema.anyOf() | length %} - {%- for anyOfSchema in schema.anyOf() %} - {{setConstructorProperties(anyOfSchema)}} - {%- endfor %} - {%- elif schema.uid() | length %} - {{setProperty(schema.uid())}} {%- endif %} -{%- endmacro %} -{%- macro importSchemas(schema) %} - {%- if schema.allOf() | length %} - {%- for allOfSchema in schema.allOf() %} - {{importSchemas(allOfSchema)}} - {%- endfor %} - {%- elif schema.oneOf() | length %} - {{importSchema("OneOf")}} - {%- for oneOfSchema in schema.oneOf() %} - {{importSchemas(oneOfSchema)}} - {%- endfor %} - {%- elif schema.anyOf() | length %} - {%- for anyOfSchema in schema.anyOf() %} - {{importSchemas(anyOfSchema)}} - {%- endfor %} - {%- elif schema.uid() | length %} - {{importSchema(schema.uid())}} + + {%- if schema.type() == "object" %} + {{setProperty(schema.uid())}} + {%- elif schema.type() | length %} + {{setProperty("type")}} {%- endif %} {%- endmacro %} {%- macro initProperty(propertyName, propertyType) %} @@ -54,11 +40,9 @@ this.{{propertyName | camelCase}} = {{propertyName | camelCase}}; {% endmacro %} -{%- macro importSchema(propertyName) %} -import { default as {{propertyName | pascalCase}}Schema } from '../schema/{{propertyName | pascalCase}}'; -{% endmacro %} -{{ importSchemas(message.payload()) }} - +{%- for _, import in (message.payload() | genericImports) %} +{{import | safe }} +{%- endfor %} export default class {{ message.name() | pascalCase}} { {{ initProperties(message.payload()) }} diff --git a/template/src/schema/$$objectSchema$$.ts.njk b/template/src/schema/$$objectSchema$$.ts.njk index bc68f5c76..527d6527f 100644 --- a/template/src/schema/$$objectSchema$$.ts.njk +++ b/template/src/schema/$$objectSchema$$.ts.njk @@ -16,42 +16,16 @@ {%- endfor %} {%- endif %} - {%- if schema.properties() | length %} + {%- if schema.type() == "object" %} {%- for propertyName, property in schema.properties() %} {{ propertyName | camelCase}}{% if not required or not property.required() %}?{% endif %}: {{ property.type() | toTsType(property) }} {%- endfor %} + {%- elif schema.type() | length %} + type: {{ schema.type() | toTsType }} {%- endif %} {% endmacro %} -{% macro importSchemas(schema) %} - {%- if schema.allOf() | length %} - {%- for allOfSchema in schema.allOf() %} - {{importSchemas(allOfSchema)}} - {%- endfor %} - {%- endif %} - - {%- if schema.oneOf() | length %} - {%- for oneOfSchema in schema.oneOf() %} - {{importSchemas(oneOfSchema)}} - {%- endfor %} - {%- endif %} - - {%- if schema.anyOf() | length %} - {%- for oneOfSchema in schema.anyOf() %} - {{importSchemas(oneOfSchema)}} - {%- endfor %} - {%- endif %} - - {%- if schema.properties() | length %} - {%- for propertyName, property in schema.properties() %} - {%- if property.type() == "object" %} -import { default as {{property.uid() | pascalCase}} } from './{{property.uid() | pascalCase}}'; - {%- endif %} - {%- endfor %} - {%- endif %} - -{% endmacro %} {%- macro setConstructorProperties(schema) %} {%- if schema.allOf() | length %} {%- for allOfSchema in schema.allOf() %} @@ -66,13 +40,15 @@ import { default as {{property.uid() | pascalCase}} } from './{{property.uid() | {{setConstructorProperties(anyOfSchema)}} {%- endfor %} {%- endif %} - {%- if schema.properties() | length %} - - {%- for propertyName, property in schema.properties() %} - {% if property.required() %} - {{setProperty(propertyName)}} - {%- endif %} - {%- endfor %} + + {%- if schema.type() == "object" %} + {%- for propertyName, property in schema.properties() %} + {% if property.required() %} + {{setProperty(propertyName)}} + {%- endif %} + {%- endfor %} + {%- elif schema.type() | length %} + {{setProperty("type")}} {%- endif %} {%- endmacro %} @@ -81,7 +57,11 @@ import { default as {{property.uid() | pascalCase}} } from './{{property.uid() | this.{{propertyName | camelCase}} = {{propertyName | camelCase}}; {% endmacro %} -{{ importSchemas(schema) }} + +{%- for _, import in (schema | schemaImports) %} +{{import | safe }} +{%- endfor %} + export default class {{ schema.uid() | camelCase }} { {{ initProperties(schema) }} From 68ea06bec83fd27367b63abfdfc661b3c910da37 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Fri, 8 May 2020 16:47:35 +0200 Subject: [PATCH 035/110] Fixed problems with index channel generation. Fixed problems with generated code and module aliases. Added event listener to client. Fixed promises was never returned if a client is not connected. --- partials/index/Publish.njk | 1 + partials/index/Reply.njk | 2 +- partials/index/Request.njk | 2 +- partials/index/Subscribe.njk | 2 +- template/package.json.njk | 19 +++++++++++++++---- template/src/channels/$$channel$$.ts.njk | 4 ++-- template/src/index.ts.njk | 10 +++++++++- .../testchannels/$$channel$$.ts.njk | 4 ++-- 8 files changed, 32 insertions(+), 12 deletions(-) diff --git a/partials/index/Publish.njk b/partials/index/Publish.njk index a8efd2700..d5636ad35 100644 --- a/partials/index/Publish.njk +++ b/partials/index/Publish.njk @@ -23,6 +23,7 @@ {% endif %}); }else{ throw new Error("Nats client is not connected"); + return Promise.reject(new Error('Nats client is not connected, could not send message on channel {{ channelName | camelCase }}')) } } {% endmacro %} diff --git a/partials/index/Reply.njk b/partials/index/Reply.njk index a13272c60..7e9a8b7aa 100644 --- a/partials/index/Reply.njk +++ b/partials/index/Reply.njk @@ -25,7 +25,7 @@ ,{{parameters | realizeParametersForChannelWithoutType}} {% endif %}); }else{ - throw new Error("Nats client is not connected"); + return Promise.reject(new Error('Nats client is not connected, could not send message on channel {{ channelName | camelCase }}')) } } {% endmacro %} diff --git a/partials/index/Request.njk b/partials/index/Request.njk index 906f8d256..b7219addc 100644 --- a/partials/index/Request.njk +++ b/partials/index/Request.njk @@ -23,7 +23,7 @@ ,{{parameters | realizeParametersForChannelWithoutType}} {% endif %}); }else{ - throw new Error("Nats client is not connected"); + return Promise.reject(new Error('Nats client is not connected, could not send message on channel {{ channelName | camelCase }}')) } } {% endmacro %} diff --git a/partials/index/Subscribe.njk b/partials/index/Subscribe.njk index fd6818492..7c37d6883 100644 --- a/partials/index/Subscribe.njk +++ b/partials/index/Subscribe.njk @@ -22,7 +22,7 @@ ,{{parameters | realizeParametersForChannelWithoutType}} {% endif %}); }else{ - throw new Error("Nats client is not connected"); + return Promise.reject(new Error('Nats client is not connected, could not send message on channel {{ channelName | camelCase }}')) } } {% endmacro %} diff --git a/template/package.json.njk b/template/package.json.njk index d2b768f75..6d88fbcd3 100644 --- a/template/package.json.njk +++ b/template/package.json.njk @@ -26,11 +26,22 @@ "test": "mocha -r ts-node/register tests/**/*.spec.ts" }, "_moduleAliasIgnoreWarning": true, + "baseUrl": "./src", + "paths": { + "#messages": [ + "messages/*" + ], + "#schemas": [ + "schema/*" + ], + "#hooks": [ + "hooks" + ] + }, "_moduleAliases": { - "#messages": "./src/messages", - "#schemas": "./src/schema", - "#channels": "./src/channels", - "#hooks": "./src/hooks" + "#messages": "./dist/messages", + "#schemas": "./dist/schema", + "#hooks": "./dist/hooks" }, "dependencies": { "@types/klaw-sync": "^6.0.0", diff --git a/template/src/channels/$$channel$$.ts.njk b/template/src/channels/$$channel$$.ts.njk index 80739eb44..b1d2ecb97 100644 --- a/template/src/channels/$$channel$$.ts.njk +++ b/template/src/channels/$$channel$$.ts.njk @@ -4,10 +4,10 @@ {%- from "../../../partials/channel/Request.njk" import request %} {%- from "../../../partials/channel/Subscribe.njk" import subscribe %} {%- if channel.hasPublish() %} -import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '../messages/{{ channel.publish().message(0).uid() | pascalCase}}' +import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '#messages/{{ channel.publish().message(0).uid() | pascalCase}}' {%- endif %} {%- if channel.hasSubscribe() %} -import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '../messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' +import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '#messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' {%- endif %} import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; import * as Hooks from '#hooks'; diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index f39cf18b0..1459c3f85 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -14,6 +14,13 @@ import * as {{ channelName | camelCase }}Channel from "./channels/{{ channelName import {default as {{ messageName | pascalCase }}Message} from "./messages/{{ messageName | pascalCase }}"; {%- endfor %} +export enum AvailableEvents { + connection_error = 'connection_error' +} +export declare interface NatsAsyncApiClient { + on(event: AvailableEvents.connection_error, listener: (error: any) => void): this; + //on(event: AvailableEvents.connection_error, listener: Function): this; +} export default class NatsAsyncApiClient { public jsonClient?: Client; public stringClient?: Client; @@ -25,6 +32,7 @@ export default class NatsAsyncApiClient { * @param options options to use, payload is omitted if sat in the AsyncAPI document. */ constructor(options : NatsConnectionOptions) { + super(); this.options = this.setDefaultOptions(options); this.connect(); } @@ -47,7 +55,7 @@ export default class NatsAsyncApiClient { this.jsonClient = await connect(this.options); {%- endif %} }catch(e){ - console.error("Could not connect to NATS: " + e) + this.emit(AvailableEvents.connection_error, e) } } diff --git a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk index 559b5279f..8a7855d0c 100644 --- a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk +++ b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk @@ -4,10 +4,10 @@ {%- from "../../../../../partials/channel/Request.njk" import request %} {%- from "../../../../../partials/channel/Subscribe.njk" import subscribe %} {%- if channel.hasPublish() %} -import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '../../../../src/messages/{{ channel.publish().message(0).uid() | pascalCase}}' +import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '#messages/{{ channel.publish().message(0).uid() | pascalCase}}' {%- endif %} {%- if channel.hasSubscribe() %} -import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '../../../../src//messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' +import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '#messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' {%- endif %} import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; import * as Hooks from '#hooks'; From 9800419a7fb4d68abb53d977f48ccb03aa24ba50 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Fri, 8 May 2020 17:01:17 +0200 Subject: [PATCH 036/110] Fixed packages --- template/package.json.njk | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/template/package.json.njk b/template/package.json.njk index 6d88fbcd3..5afb6d103 100644 --- a/template/package.json.njk +++ b/template/package.json.njk @@ -45,17 +45,12 @@ }, "dependencies": { "@types/klaw-sync": "^6.0.0", - "@types/uuid": "3.4.5", "@types/node": "13.9.5", "klaw-sync": "6.0.0", "link-module-alias": "^1.2.0", - "msgpack-lite": "^0.1.26", "ts-nats": "1.2.4", - "node-yaml-config": "0.0.5", "typescript": "3.4.3", - "uuid": "3.3.3", - "winston": "3.2.1", - "winston-daily-rotate-file": "3.10.0" + "ts-nkeys":"1.0.16" }, "devDependencies": { "@types/chai": "^4.2.11", From b961a96e36c2d053660109d2b77d1a64f6b305bb Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Fri, 8 May 2020 17:01:38 +0200 Subject: [PATCH 037/110] Changed how to connect with nkey authentication --- template/src/index.ts.njk | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index 1459c3f85..56396ad08 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -31,7 +31,7 @@ export default class NatsAsyncApiClient { * * @param options options to use, payload is omitted if sat in the AsyncAPI document. */ - constructor(options : NatsConnectionOptions) { + constructor() { super(); this.options = this.setDefaultOptions(options); this.connect(); @@ -40,7 +40,8 @@ export default class NatsAsyncApiClient { /** * Try to connect to the NATS server with the different payloads. */ - private async connect(){ + async connect(options : NatsConnectionOptions){ + this.options = this.setDefaultOptions(options); try{ {%- if asyncapi | containsBinaryPayload %} this.options.payload = Payload.BINARY; @@ -59,6 +60,17 @@ export default class NatsAsyncApiClient { } } + /** + * Try to connect to the NATS server with nkey authentication + */ + async connectWithNkey(options : NatsConnectionOptions, publicNkey: string, seed: string){ + options.nkey = publicNkey; + options.nonceSigner = (nonce: string): Buffer => { + const sk = fromSeed(Buffer.from(seed)); + return sk.sign(Buffer.from(nonce)); + } + await connect(options); + } /** * Set the default options based on the AsyncAPI file. * @param options to set From 0fca24ef1d0f573ca7a698f848d78a5325156b6f Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 11 May 2020 01:00:09 +0200 Subject: [PATCH 038/110] Fixed hooks and event emitter for client --- partials/channel/Publish.njk | 2 +- partials/channel/Reply.njk | 4 +- partials/channel/Request.njk | 4 +- partials/channel/Subscribe.njk | 2 +- partials/index/Publish.njk | 1 - template/package.json.njk | 23 +--- template/src/channels/$$channel$$.ts.njk | 2 +- template/src/hooks.ts | 103 ++++++++--------- template/src/index.ts.njk | 109 +++++++++++++++--- template/src/tests/testclient/index.ts.njk | 2 +- .../testchannels/$$channel$$.ts.njk | 2 +- template/tsconfig.json | 8 +- 12 files changed, 164 insertions(+), 98 deletions(-) diff --git a/partials/channel/Publish.njk b/partials/channel/Publish.njk index 4e09e6c2b..b3966be1b 100644 --- a/partials/channel/Publish.njk +++ b/partials/channel/Publish.njk @@ -11,7 +11,7 @@ export function publish( return new Promise(async (resolve, reject) => { if (nc) { try{ - let publishDataHooks = Hooks.getBeforeSendingDataHook(); + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); var dataToPublish : any = requestMessage; for(let hook of publishDataHooks){ dataToPublish = hook(dataToPublish); diff --git a/partials/channel/Reply.njk b/partials/channel/Reply.njk index c65e5126b..da18ef452 100644 --- a/partials/channel/Reply.njk +++ b/partials/channel/Reply.njk @@ -29,7 +29,7 @@ export function reply( onRequest(err); } else { - let receivedDataHooks = Hooks.getRecievedDataHook(); + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); var processedDataReceived : any = msg.data; for(let hook of receivedDataHooks){ processedDataReceived = hook(processedDataReceived); @@ -39,7 +39,7 @@ export function reply( let responseObject = onRequest(undefined, requestData); if (msg.reply) { try { - let publishDataHooks = Hooks.getBeforeSendingDataHook(); + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); var dataToPublish : any = responseObject; for(let hook of publishDataHooks){ dataToPublish = hook(dataToPublish); diff --git a/partials/channel/Request.njk b/partials/channel/Request.njk index 6de19a78d..e5e7ccaf6 100644 --- a/partials/channel/Request.njk +++ b/partials/channel/Request.njk @@ -15,7 +15,7 @@ export function request( if (err) { reject(err); } else { - let receivedDataHooks = Hooks.getRecievedDataHook(); + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); var processedDataReceived : any = msg.data; for(let hook of receivedDataHooks){ processedDataReceived = hook(processedDataReceived); @@ -23,7 +23,7 @@ export function request( resolve({{subscribtionMessage.uid() | pascalCase}}Message.toMessage(processedDataReceived)); } }, { max: 1 }); - let publishDataHooks = Hooks.getBeforeSendingDataHook(); + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); var requestData : any = requestMessage; for(let hook of publishDataHooks){ requestData = hook(requestData); diff --git a/partials/channel/Subscribe.njk b/partials/channel/Subscribe.njk index 5c0880050..418fdd7ea 100644 --- a/partials/channel/Subscribe.njk +++ b/partials/channel/Subscribe.njk @@ -26,7 +26,7 @@ export function subscribe( onDataCallback(err); }else{ - let receivedDataHooks = Hooks.getRecievedDataHook(); + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); var processedDataReceived: any = msg.data; for(let hook of receivedDataHooks){ processedDataReceived = hook(processedDataReceived); diff --git a/partials/index/Publish.njk b/partials/index/Publish.njk index d5636ad35..80e6c7131 100644 --- a/partials/index/Publish.njk +++ b/partials/index/Publish.njk @@ -22,7 +22,6 @@ ,{{parameters | realizeParametersForChannelWithoutType}} {% endif %}); }else{ - throw new Error("Nats client is not connected"); return Promise.reject(new Error('Nats client is not connected, could not send message on channel {{ channelName | camelCase }}')) } } diff --git a/template/package.json.njk b/template/package.json.njk index 5afb6d103..4414fe63e 100644 --- a/template/package.json.njk +++ b/template/package.json.njk @@ -20,28 +20,17 @@ "types": "dist/index.d.ts", "scripts": { "watch": "tsc --watch", - "build": "tsc", + "build": "tsc && npm run dopostinstall", "start": "node src/api/index.js", - "postinstall": "link-module-alias", + "dopostinstall": "link-module-alias", "test": "mocha -r ts-node/register tests/**/*.spec.ts" }, "_moduleAliasIgnoreWarning": true, - "baseUrl": "./src", - "paths": { - "#messages": [ - "messages/*" - ], - "#schemas": [ - "schema/*" - ], - "#hooks": [ - "hooks" - ] - }, "_moduleAliases": { - "#messages": "./dist/messages", - "#schemas": "./dist/schema", - "#hooks": "./dist/hooks" + "#messages": "dist/messages/", + "#schemas": "dist/schema/", + "#channels": "dist/channels/", + "#hooks": "dist/hooks.js" }, "dependencies": { "@types/klaw-sync": "^6.0.0", diff --git a/template/src/channels/$$channel$$.ts.njk b/template/src/channels/$$channel$$.ts.njk index b1d2ecb97..d0f6fa9ca 100644 --- a/template/src/channels/$$channel$$.ts.njk +++ b/template/src/channels/$$channel$$.ts.njk @@ -10,7 +10,7 @@ import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '#messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' {%- endif %} import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as Hooks from '#hooks'; +import { Hooks } from '#hooks'; {%- if channel | isRequestReply %} {%- if channel | isRequester %} {{ request(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} diff --git a/template/src/hooks.ts b/template/src/hooks.ts index af87046e9..51e71a158 100644 --- a/template/src/hooks.ts +++ b/template/src/hooks.ts @@ -1,4 +1,3 @@ -const HOOKS_DIRNAME = './hooks'; import * as fs from 'fs'; import * as path from 'path'; import * as walkSync from 'klaw-sync'; @@ -8,58 +7,54 @@ export enum AvailableHooks { } export type RecievedDataHook = (receivedData: any) => string; export type BeforeSendingDataHook = (messageToSend: any) => string; -export var hooks: { - BeforeSendingData: BeforeSendingDataHook[]; - RecievedData: RecievedDataHook[]; -}; - -/** - * Loads the custom hooks. - */ -try { - const hooksPath = path.resolve(HOOKS_DIRNAME); - if (fs.existsSync(hooksPath)) { - const files = walkSync(hooksPath, { nodir: true }); - files.forEach((file: any) => { - require(file.path)((when: AvailableHooks, hook: any) => { - hooks[when].push(hook); - }); - }); +export class Hooks { + private static instance: Hooks; + + private hooks: { + BeforeSendingData: BeforeSendingDataHook[]; + RecievedData: RecievedDataHook[]; + }; + private constructor() { + this.hooks = { + BeforeSendingData: [], + RecievedData: [] + } + } + public static getInstance(): Hooks { + if (!Hooks.instance) { + Hooks.instance = new Hooks(); + } + return Hooks.instance; } -} catch (e) { - e.message = `There was a problem registering the hooks: ${e.message}`; - throw e; -} - -/** - * Register a hook for BeforeSendingData - * @param hook - */ -export async function registerBeforeSendingData(hook: BeforeSendingDataHook) { - hooks[AvailableHooks.BeforeSendingData] - ? hooks[AvailableHooks.BeforeSendingData].push(hook) - : [hook]; -} - -/** - * Register a hook for BeforeSendingData - * @param hook - */ -export async function registerRecievedData(hook: RecievedDataHook) { - hooks[AvailableHooks.RecievedData] - ? hooks[AvailableHooks.RecievedData].push(hook) - : [hook]; -} - - -export function getRecievedDataHook(): RecievedDataHook[] { - if (!Array.isArray(hooks[AvailableHooks.RecievedData])) return []; - // Return valid hooks - return hooks[AvailableHooks.RecievedData]; -} -export function getBeforeSendingDataHook(): BeforeSendingDataHook[] { - if (!Array.isArray(hooks[AvailableHooks.BeforeSendingData])) return []; - // Return valid hooks - return hooks[AvailableHooks.BeforeSendingData]; -} + + + /** + * Register a hook for BeforeSendingData + * @param hook + */ + public async registerBeforeSendingData(hook: BeforeSendingDataHook) { + this.hooks[AvailableHooks.BeforeSendingData] + ? this.hooks[AvailableHooks.BeforeSendingData].push(hook) + : [hook]; + } + + /** + * Register a hook for BeforeSendingData + * @param hook + */ + public async registerRecievedData(hook: RecievedDataHook) { + this.hooks[AvailableHooks.RecievedData] + ? this.hooks[AvailableHooks.RecievedData].push(hook) + : [hook]; + } + + + public getRecievedDataHook(): RecievedDataHook[] { + return this.hooks[AvailableHooks.RecievedData]; + } + + public getBeforeSendingDataHook(): BeforeSendingDataHook[] { + return this.hooks[AvailableHooks.BeforeSendingData]; + } +} \ No newline at end of file diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index 56396ad08..81153ac50 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -4,28 +4,66 @@ {%- from "../../partials/index/Request.njk" import request %} {%- from "../../partials/index/Subscribe.njk" import subscribe %} -import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; +import { + Client, + NatsConnectionOptions, + connect, + Payload, + NatsError, + Subscription, + ServersChangedEvent, + SubEvent, + ServerInfo + } from 'ts-nats'; {%- for channelName, _ in asyncapi.channels() %} -import * as {{ channelName | camelCase }}Channel from "./channels/{{ channelName | pascalCase | firstUpperCase }}"; +import * as {{ channelName | camelCase }}Channel from "#channels/{{ channelName | pascalCase | firstUpperCase }}"; {%- endfor %} {%- for messageName, _ in asyncapi.allMessages() %} -import {default as {{ messageName | pascalCase }}Message} from "./messages/{{ messageName | pascalCase }}"; +import {default as {{ messageName | pascalCase }}Message} from "#messages/{{ messageName | pascalCase }}"; {%- endfor %} - +import {fromSeed} from 'ts-nkeys'; +import * as events from 'events'; export enum AvailableEvents { - connection_error = 'connection_error' + connectionError = 'connectionError', + permissionError = 'permissionError', + close = 'close', + connect = 'connect', + connecting = 'connecting', + disconnect = 'disconnect', + error = 'error', + pingcount = 'pingcount', + pingtimer = 'pingtimer', + reconnect = 'reconnect', + reconnecting = 'reconnecting', + serversChanged = 'serversChanged', + subscribe = 'subscribe', + unsubscribe = 'unsubscribe', + yield = 'yield' } export declare interface NatsAsyncApiClient { - on(event: AvailableEvents.connection_error, listener: (error: any) => void): this; - //on(event: AvailableEvents.connection_error, listener: Function): this; + on(event: AvailableEvents.connectionError, listener: (error: any) => void): this; + on(event: AvailableEvents.permissionError, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.close, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; + on(event: AvailableEvents.connecting, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.error, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.pingcount, listener: () => void): this; + on(event: AvailableEvents.pingtimer, listener: () => void): this; + on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; + on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; + on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.yield, listener: () => void): this; } -export default class NatsAsyncApiClient { +export class NatsAsyncApiClient extends events.EventEmitter{ public jsonClient?: Client; public stringClient?: Client; public binaryClient?: Client; - public options: NatsConnectionOptions; + public options?: NatsConnectionOptions; /** * @@ -33,8 +71,6 @@ export default class NatsAsyncApiClient { */ constructor() { super(); - this.options = this.setDefaultOptions(options); - this.connect(); } /** @@ -46,20 +82,67 @@ export default class NatsAsyncApiClient { {%- if asyncapi | containsBinaryPayload %} this.options.payload = Payload.BINARY; this.binaryClient = await connect(this.options); + this.chainEvents(this.binaryClient); {%- endif %} {%- if asyncapi | containsStringPayload %} this.options.payload = Payload.STRING; this.stringClient = await connect(this.options); + this.chainEvents(this.stringClient); {%- endif %} {%- if asyncapi | containsJsonPayload %} this.options.payload = Payload.JSON; this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); {%- endif %} }catch(e){ - this.emit(AvailableEvents.connection_error, e) + this.emit(AvailableEvents.connectionError, e) } } + private chainEvents(ns: Client){ + ns.on('permissionError', (e: NatsError) => { + this.emit(AvailableEvents.permissionError, e) + }); + ns.on('close', (e: NatsError) => { + this.emit(AvailableEvents.close, e) + }); + ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.connect, connection, serverURL, info) + }); + ns.on('connecting', (serverURL: NatsError) => { + this.emit(AvailableEvents.connecting, serverURL) + }); + ns.on('disconnect', (serverURL: string) => { + this.emit(AvailableEvents.disconnect, serverURL) + }); + ns.on('error', (e: NatsError) => { + this.emit(AvailableEvents.error, e) + }); + ns.on('pingcount', () => { + this.emit(AvailableEvents.pingcount) + }); + ns.on('pingtimer', () => { + this.emit(AvailableEvents.pingtimer) + }); + ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.reconnect, connection, serverURL, info) + }); + ns.on('reconnecting', (serverURL: string) => { + this.emit(AvailableEvents.reconnecting, serverURL) + }); + ns.on('serversChanged', (e: ServersChangedEvent) => { + this.emit(AvailableEvents.serversChanged, e) + }); + ns.on('subscribe', (e: SubEvent) => { + this.emit(AvailableEvents.subscribe, e) + }); + ns.on('unsubscribe', (e: SubEvent) => { + this.emit(AvailableEvents.unsubscribe, e) + }); + ns.on('yield', () => { + this.emit(AvailableEvents.yield) + }); + } /** * Try to connect to the NATS server with nkey authentication */ @@ -69,7 +152,7 @@ export default class NatsAsyncApiClient { const sk = fromSeed(Buffer.from(seed)); return sk.sign(Buffer.from(nonce)); } - await connect(options); + await this.connect(options); } /** * Set the default options based on the AsyncAPI file. diff --git a/template/src/tests/testclient/index.ts.njk b/template/src/tests/testclient/index.ts.njk index 3728f99f6..703d0401f 100644 --- a/template/src/tests/testclient/index.ts.njk +++ b/template/src/tests/testclient/index.ts.njk @@ -11,7 +11,7 @@ import * as {{ channelName | camelCase }}Channel from "./testchannels/{{ channel {%- endfor %} {%- for messageName, _ in asyncapi.allMessages() %} -import {default as {{ messageName | pascalCase }}Message} from "../../../src/messages/{{ messageName | pascalCase }}"; +import {default as {{ messageName | pascalCase }}Message} from "#messages/{{ messageName | pascalCase }}"; {%- endfor %} export default class NatsAsyncApiClient { diff --git a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk index 8a7855d0c..764cb2a89 100644 --- a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk +++ b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk @@ -10,7 +10,7 @@ import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '#messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' {%- endif %} import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as Hooks from '#hooks'; +import { Hooks } from '#hooks'; {%- if channel | isRequestReply %} diff --git a/template/tsconfig.json b/template/tsconfig.json index e2cedf397..32b631498 100644 --- a/template/tsconfig.json +++ b/template/tsconfig.json @@ -9,11 +9,11 @@ "preserveConstEnums": true, "sourceMap": true, "outDir": "dist/", - "baseUrl": "./src" /* Base directory to resolve non-absolute module names. */, + "baseUrl": "./src", "paths": { - "#messages": ["messages"], - "#schemas": ["schema"], - "#channels": ["channels"], + "#messages/*": ["messages/*"], + "#schemas/*": ["schema/*"], + "#channels/*": ["channels/*"], "#hooks": ["hooks"] } }, From afd8ed2b9ef753f0111f2813be58f5b4e2c40242 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Wed, 13 May 2020 00:18:03 +0200 Subject: [PATCH 039/110] Added disconnect function to the client. --- template/src/index.ts.njk | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index 81153ac50..6baf9cc01 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -99,6 +99,21 @@ export class NatsAsyncApiClient extends events.EventEmitter{ } } + /** + * Disconnect all clients from the server + */ + async disconnect(){ + {%- if asyncapi | containsBinaryPayload %} + this.binaryClient!.close() + {%- endif %} + {%- if asyncapi | containsStringPayload %} + this.stringClient!.close() + {%- endif %} + {%- if asyncapi | containsJsonPayload %} + this.jsonClient!.close() + {%- endif %} + } + private chainEvents(ns: Client){ ns.on('permissionError', (e: NatsError) => { this.emit(AvailableEvents.permissionError, e) From d1e237529ae4458eaf41c80b3bcd54b8331263ea Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Wed, 13 May 2020 00:18:26 +0200 Subject: [PATCH 040/110] Added missing aliases. Added disconnect to test client. --- template/package.json.njk | 4 +- template/src/tests/testclient/index.ts.njk | 140 +++++++++++++++++++-- template/tsconfig.json | 5 +- 3 files changed, 136 insertions(+), 13 deletions(-) diff --git a/template/package.json.njk b/template/package.json.njk index 4414fe63e..3028d223e 100644 --- a/template/package.json.njk +++ b/template/package.json.njk @@ -30,7 +30,9 @@ "#messages": "dist/messages/", "#schemas": "dist/schema/", "#channels": "dist/channels/", - "#hooks": "dist/hooks.js" + "#testchannels": "dist/tests/testclient/testchannels/", + "#hooks": "dist/hooks.js", + "#testclient": "dist/tests/testclient/index.js" }, "dependencies": { "@types/klaw-sync": "^6.0.0", diff --git a/template/src/tests/testclient/index.ts.njk b/template/src/tests/testclient/index.ts.njk index 703d0401f..a17f45136 100644 --- a/template/src/tests/testclient/index.ts.njk +++ b/template/src/tests/testclient/index.ts.njk @@ -3,54 +3,172 @@ {%- from "../../../../partials/index/Reply.njk" import reply %} {%- from "../../../../partials/index/Request.njk" import request %} {%- from "../../../../partials/index/Subscribe.njk" import subscribe %} - -import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; +import { + Client, + NatsConnectionOptions, + connect, + Payload, + NatsError, + Subscription, + ServersChangedEvent, + SubEvent, + ServerInfo + } from 'ts-nats'; {%- for channelName, _ in asyncapi.channels() %} -import * as {{ channelName | camelCase }}Channel from "./testchannels/{{ channelName | pascalCase | firstUpperCase }}"; +import * as {{ channelName | camelCase }}Channel from "#testchannels/{{ channelName | pascalCase | firstUpperCase }}"; {%- endfor %} {%- for messageName, _ in asyncapi.allMessages() %} import {default as {{ messageName | pascalCase }}Message} from "#messages/{{ messageName | pascalCase }}"; {%- endfor %} - -export default class NatsAsyncApiClient { +import {fromSeed} from 'ts-nkeys'; +import * as events from 'events'; +export enum AvailableEvents { + connectionError = 'connectionError', + permissionError = 'permissionError', + close = 'close', + connect = 'connect', + connecting = 'connecting', + disconnect = 'disconnect', + error = 'error', + pingcount = 'pingcount', + pingtimer = 'pingtimer', + reconnect = 'reconnect', + reconnecting = 'reconnecting', + serversChanged = 'serversChanged', + subscribe = 'subscribe', + unsubscribe = 'unsubscribe', + yield = 'yield' +} +export declare interface NatsAsyncApiTestClient { + on(event: AvailableEvents.connectionError, listener: (error: any) => void): this; + on(event: AvailableEvents.permissionError, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.close, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; + on(event: AvailableEvents.connecting, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.error, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.pingcount, listener: () => void): this; + on(event: AvailableEvents.pingtimer, listener: () => void): this; + on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; + on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; + on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.yield, listener: () => void): this; +} +export class NatsAsyncApiTestClient extends events.EventEmitter{ public jsonClient?: Client; public stringClient?: Client; public binaryClient?: Client; - public options: NatsConnectionOptions; + public options?: NatsConnectionOptions; /** * * @param options options to use, payload is omitted if sat in the AsyncAPI document. */ - constructor(options : NatsConnectionOptions) { - this.options = this.setDefaultOptions(options); - this.connect(); + constructor() { + super(); } /** * Try to connect to the NATS server with the different payloads. */ - private async connect(){ + async connect(options : NatsConnectionOptions){ + this.options = this.setDefaultOptions(options); try{ {%- if asyncapi | containsBinaryPayload %} this.options.payload = Payload.BINARY; this.binaryClient = await connect(this.options); + this.chainEvents(this.binaryClient); {%- endif %} {%- if asyncapi | containsStringPayload %} this.options.payload = Payload.STRING; this.stringClient = await connect(this.options); + this.chainEvents(this.stringClient); {%- endif %} {%- if asyncapi | containsJsonPayload %} this.options.payload = Payload.JSON; this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); {%- endif %} }catch(e){ - console.error("Could not connect to NATS: " + e) + this.emit(AvailableEvents.connectionError, e) } } + + /** + * Disconnect all clients from the server + */ + async disconnect(){ + {%- if asyncapi | containsBinaryPayload %} + this.binaryClient!.close() + {%- endif %} + {%- if asyncapi | containsStringPayload %} + this.stringClient!.close() + {%- endif %} + {%- if asyncapi | containsJsonPayload %} + this.jsonClient!.close() + {%- endif %} + } + + private chainEvents(ns: Client){ + ns.on('permissionError', (e: NatsError) => { + this.emit(AvailableEvents.permissionError, e) + }); + ns.on('close', (e: NatsError) => { + this.emit(AvailableEvents.close, e) + }); + ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.connect, connection, serverURL, info) + }); + ns.on('connecting', (serverURL: NatsError) => { + this.emit(AvailableEvents.connecting, serverURL) + }); + ns.on('disconnect', (serverURL: string) => { + this.emit(AvailableEvents.disconnect, serverURL) + }); + ns.on('error', (e: NatsError) => { + this.emit(AvailableEvents.error, e) + }); + ns.on('pingcount', () => { + this.emit(AvailableEvents.pingcount) + }); + ns.on('pingtimer', () => { + this.emit(AvailableEvents.pingtimer) + }); + ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.reconnect, connection, serverURL, info) + }); + ns.on('reconnecting', (serverURL: string) => { + this.emit(AvailableEvents.reconnecting, serverURL) + }); + ns.on('serversChanged', (e: ServersChangedEvent) => { + this.emit(AvailableEvents.serversChanged, e) + }); + ns.on('subscribe', (e: SubEvent) => { + this.emit(AvailableEvents.subscribe, e) + }); + ns.on('unsubscribe', (e: SubEvent) => { + this.emit(AvailableEvents.unsubscribe, e) + }); + ns.on('yield', () => { + this.emit(AvailableEvents.yield) + }); + } + /** + * Try to connect to the NATS server with nkey authentication + */ + async connectWithNkey(options : NatsConnectionOptions, publicNkey: string, seed: string){ + options.nkey = publicNkey; + options.nonceSigner = (nonce: string): Buffer => { + const sk = fromSeed(Buffer.from(seed)); + return sk.sign(Buffer.from(nonce)); + } + await this.connect(options); + } /** * Set the default options based on the AsyncAPI file. * @param options to set diff --git a/template/tsconfig.json b/template/tsconfig.json index 32b631498..b1d6a9fac 100644 --- a/template/tsconfig.json +++ b/template/tsconfig.json @@ -14,7 +14,10 @@ "#messages/*": ["messages/*"], "#schemas/*": ["schema/*"], "#channels/*": ["channels/*"], - "#hooks": ["hooks"] + "#testchannels/*": ["tests/testclient/testchannels/*"], + "#hooks": ["hooks"], + "#testclient": ["tests/testclient/index"], + "#client": ["index"] } }, "include": ["src"], From 1c42e196de1dbedd50991d786fcea4a18c782be8 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Wed, 13 May 2020 00:18:56 +0200 Subject: [PATCH 041/110] Fixed messages would not get parsed correctly --- template/src/messages/$$message$$.ts.njk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/template/src/messages/$$message$$.ts.njk b/template/src/messages/$$message$$.ts.njk index c9d91f6bb..ab4d7ed4e 100644 --- a/template/src/messages/$$message$$.ts.njk +++ b/template/src/messages/$$message$$.ts.njk @@ -54,10 +54,10 @@ export default class {{ message.name() | pascalCase}} { /** * Parses a JSON string to an object of {{ message.name() | pascalCase}} message class. - * @param json string to be parsed as {{ message.name() | pascalCase}}. + * @param json any to be parsed as {{ message.name() | pascalCase}}. */ - public static toMessage(json: string): {{ message.name() | pascalCase }} { - return JSON.parse(json); + public static toMessage(json: any): {{ message.name() | pascalCase }} { + return JSON.parse(JSON.stringify(json)); } } From c1b86cac04cb6fa65b281c3419f7c154ddf7f089 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Wed, 13 May 2020 12:24:30 +0200 Subject: [PATCH 042/110] Added optional test files --- .tp-config.json | 7 +++++++ hooks/remove-test-files.js | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 hooks/remove-test-files.js diff --git a/.tp-config.json b/.tp-config.json index 94a6bf421..4a14fb0bc 100644 --- a/.tp-config.json +++ b/.tp-config.json @@ -1,4 +1,11 @@ { + "supportedProtocols": ["nats"], + "parameters": { + "generateTestFiles": { + "description": "Generate the test files for the client as well", + "required": false + } + }, "generator": ">=0.41.0 <2.0.0", "filters": [ "@asyncapi/generator-filters"] } \ No newline at end of file diff --git a/hooks/remove-test-files.js b/hooks/remove-test-files.js new file mode 100644 index 000000000..80683f082 --- /dev/null +++ b/hooks/remove-test-files.js @@ -0,0 +1,24 @@ +const fs = require('fs'); +const Path = require('path'); + +const deleteFolderRecursive = function(path) { + if (fs.existsSync(path) && path !== "/") { + fs.readdirSync(path).forEach((file, index) => { + const curPath = Path.join(path, file); + if (fs.lstatSync(curPath).isDirectory()) { // recurse + deleteFolderRecursive(curPath); + } else { // delete file + fs.unlinkSync(curPath); + } + }); + fs.rmdirSync(path); + } + }; +module.exports = register => { + register('generate:after', generator => { + if(generator.targetDir && generator.templateParams && !generator.templateParams.generateTestFiles){ + pathToTests = Path.resolve(generator.targetDir, "src/tests/") + deleteFolderRecursive(pathToTests) + } + }); +}; From e73a8ad91ef272cc68adf2538b185b089abed5d1 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 14 May 2020 23:26:52 +0200 Subject: [PATCH 043/110] Fixed the hooks to work with the new generator. --- hooks/filename-change.js | 8 +++++--- hooks/remove-test-files.js | 6 +++--- hooks/rename-njk.js | 6 +++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/hooks/filename-change.js b/hooks/filename-change.js index d5d9bb493..3b9ba8c05 100644 --- a/hooks/filename-change.js +++ b/hooks/filename-change.js @@ -1,8 +1,10 @@ const filters = require("../filters/all") -module.exports = register => { - register('generate:changeFilename', (generator, hookArguments) => { + +module.exports = { + 'setFileTemplateName': (generator, hookArguments) => { const currentFilename = hookArguments.originalFilename; let newFilename = filters.pascalCase(currentFilename) + return newFilename - }); + } }; \ No newline at end of file diff --git a/hooks/remove-test-files.js b/hooks/remove-test-files.js index 80683f082..90a123f12 100644 --- a/hooks/remove-test-files.js +++ b/hooks/remove-test-files.js @@ -14,11 +14,11 @@ const deleteFolderRecursive = function(path) { fs.rmdirSync(path); } }; -module.exports = register => { - register('generate:after', generator => { +module.exports = { + 'generate:after': (generator) => { if(generator.targetDir && generator.templateParams && !generator.templateParams.generateTestFiles){ pathToTests = Path.resolve(generator.targetDir, "src/tests/") deleteFolderRecursive(pathToTests) } - }); + } }; diff --git a/hooks/rename-njk.js b/hooks/rename-njk.js index e3bc79991..477525333 100644 --- a/hooks/rename-njk.js +++ b/hooks/rename-njk.js @@ -16,8 +16,8 @@ var renameAllSync = function(dir) { } }); }; -module.exports = register => { - register('generate:after', generator => { +module.exports = { + 'generate:after': (generator) => { renameAllSync(path.resolve(generator.targetDir)); - }); + } }; From a1f5b2d3330a59b68db760cbe692fe4cb65026aa Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Fri, 15 May 2020 00:39:45 +0200 Subject: [PATCH 044/110] Fixed realize channel name filter didnt change / character to . used in nats. --- filters/all.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filters/all.js b/filters/all.js index 583dde347..98037e57e 100644 --- a/filters/all.js +++ b/filters/all.js @@ -139,8 +139,8 @@ function toTsType(jsonSchemaType, property) { filter.toTsType = toTsType filter.realizeChannelName = (parameters, channelName) => { - let returnString = '\`' + channelName + '\`'; + returnString = returnString.replace(`/`, `.`); for (paramName in parameters) { returnString = returnString.replace(`{${paramName}}`, `\${${paramName}}`); } From 18da367919bfd80391b793eadd7d26a9ec1eb699 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Fri, 15 May 2020 20:38:31 +0200 Subject: [PATCH 045/110] Fixed parameters are not provided when receiving messages. --- filters/all.js | 23 ++++++++++++++++++----- partials/channel/Reply.njk | 22 ++++++++++++++++++---- partials/channel/Subscribe.njk | 22 ++++++++++++++++++---- partials/index/Reply.njk | 2 +- partials/index/Subscribe.njk | 2 +- 5 files changed, 56 insertions(+), 15 deletions(-) diff --git a/filters/all.js b/filters/all.js index 98037e57e..22e797332 100644 --- a/filters/all.js +++ b/filters/all.js @@ -140,13 +140,26 @@ filter.toTsType = toTsType filter.realizeChannelName = (parameters, channelName) => { let returnString = '\`' + channelName + '\`'; - returnString = returnString.replace(`/`, `.`); + returnString = returnString.replace(/\//g, `.`); for (paramName in parameters) { returnString = returnString.replace(`{${paramName}}`, `\${${paramName}}`); } return returnString; } -filter.realizeParametersForChannelWithoutType = parameters => { +filter.realizeChannelNameWithoutParameters = (channelName) => { + return toNatsChannel(channelName, null) +} +function toNatsChannel(channelName, parameters){ + let returnString = '\`' + channelName + '\`'; + returnString = returnString.replace(/\//g, `.`); + if(parameters){ + for (paramName in parameters) { + returnString = returnString.replace(`{${paramName}}`, `\${${paramName}}`); + } + } + return returnString; +} +filter.realizeParametersForChannelWithoutType = (parameters) => { let returnString = ''; for (paramName in parameters) { returnString += `${paramName},`; @@ -156,11 +169,11 @@ filter.realizeParametersForChannelWithoutType = parameters => { } return returnString; } -filter.realizeParametersForChannel = parameters => { +filter.realizeParametersForChannel = (parameters, required = true) => { let returnString = ''; - + const requiredType = !required ? '?' : '' for (paramName in parameters) { - returnString += `${paramName}:${toTsType( + returnString += `${paramName}${requiredType}: ${toTsType( parameters[paramName].schema().type() )},`; } diff --git a/partials/channel/Reply.njk b/partials/channel/Reply.njk index da18ef452..ccd598413 100644 --- a/partials/channel/Reply.njk +++ b/partials/channel/Reply.njk @@ -1,7 +1,7 @@ {% macro reply(channelName, parameters, subscribtionMessage, publishMessage, server) %} export function reply( - onRequest: (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message) => {{publishMessage.uid() | pascalCase}}Message, + onRequest: (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message{% if parameters | length %}, {{parameters | realizeParametersForChannel(false)}}{% endif %}) => {{publishMessage.uid() | pascalCase}}Message, onReplyError: (err: NatsError) => void, nc: Client, {% if parameters | length %} @@ -11,7 +11,6 @@ export function reply( return new Promise(async (resolve, reject) => { if (nc) { try { - let subscribeOptions: SubscriptionOptions = {}; {%- if subscribtionMessage | hasNatsBindings %} {%- if subscribtionMessage.bindings().nats().queue() | length %} @@ -28,7 +27,16 @@ export function reply( if (err) { onRequest(err); } else { - + {%- if parameters | length %} + const unmodifiedChannel = {{channelName | realizeChannelNameWithoutParameters}} + const receivedTopicParameters = { + {%- set counter = 1 %} + {%- for parameterName, parameter in parameters %} + {{parameterName}} : msg.subject.slice(unmodifiedChannel.split("${{'{'+ parameterName+ '}'}}")[0].length, msg.subject.length-unmodifiedChannel.split("${{'{'+parameterName+'}'}}")[1].length){%- if counter < (parameters | length) %},{%- endif %} + {%- set counter = counter+1 %} + {%- endfor %} + } + {%- endif %} let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); var processedDataReceived : any = msg.data; for(let hook of receivedDataHooks){ @@ -36,7 +44,13 @@ export function reply( } let requestData = {{subscribtionMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); - let responseObject = onRequest(undefined, requestData); + let responseObject = onRequest(undefined, requestData{% if parameters | length %}, + {%- set counter = 1 %} + {%- for parameterName, parameter in parameters %} + receivedTopicParameters['{{parameterName}}']{%- if counter < (parameters | length) %},{%- endif %} + {%- set counter = counter+1 %} + {%- endfor %} + {%- endif %}); if (msg.reply) { try { let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); diff --git a/partials/channel/Subscribe.njk b/partials/channel/Subscribe.njk index 418fdd7ea..b742fabff 100644 --- a/partials/channel/Subscribe.njk +++ b/partials/channel/Subscribe.njk @@ -1,7 +1,7 @@ {% macro subscribe(channelName, parameters, subscribtionMessage, server) %} export function subscribe( - onDataCallback : (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message) => void, + onDataCallback : (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message{% if parameters | length %}, {{parameters | realizeParametersForChannel(false)}}{% endif %}) => void, nc: Client, {% if parameters | length %} {{parameters | realizeParametersForChannel}} @@ -25,15 +25,29 @@ export function subscribe( if(err){ onDataCallback(err); }else{ - + {%- if parameters | length %} + const unmodifiedChannel = {{channelName | realizeChannelNameWithoutParameters}} + const receivedTopicParameters = { + {%- set counter = 1 %} + {%- for parameterName, parameter in parameters %} + {{parameterName}} : msg.subject.slice(unmodifiedChannel.split("${{'{'+ parameterName+ '}'}}")[0].length, msg.subject.length-unmodifiedChannel.split("${{'{'+parameterName+'}'}}")[1].length){%- if counter < (parameters | length) %},{%- endif %} + {%- set counter = counter+1 %} + {%- endfor %} + } + {%- endif %} let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); var processedDataReceived: any = msg.data; for(let hook of receivedDataHooks){ processedDataReceived = hook(processedDataReceived); } let publishedData = {{subscribtionMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); - - onDataCallback(undefined, publishedData); + onDataCallback(undefined, publishedData{% if parameters | length %}, + {%- set counter = 1 %} + {%- for parameterName, parameter in parameters %} + receivedTopicParameters['{{parameterName}}']{%- if counter < (parameters | length) %},{%- endif %} + {%- set counter = counter+1 %} + {%- endfor %} + {%- endif %}); } }, subscribeOptions); resolve(subscription); diff --git a/partials/index/Reply.njk b/partials/index/Reply.njk index 7e9a8b7aa..5952da29b 100644 --- a/partials/index/Reply.njk +++ b/partials/index/Reply.njk @@ -5,7 +5,7 @@ * @param onRequest Called when request recieved. * @param onReplyError Called when it was not possible to send the reply. */ - public replyTo{{channelName | pascalCase }}(onRequest : (err?: NatsError, msg?: {{ subscribeMessage.uid() | pascalCase }}Message) => {{ publishMessage.uid() | pascalCase }}Message, onReplyError : (err: NatsError) => void + public replyTo{{channelName | pascalCase }}(onRequest : (err?: NatsError, msg?: {{ subscribeMessage.uid() | pascalCase }}Message{% if parameters | length %}, {{parameters | realizeParametersForChannel(false)}}{% endif %}) => {{ publishMessage.uid() | pascalCase }}Message, onReplyError : (err: NatsError) => void {% if parameters | length %} ,{{parameters | realizeParametersForChannel}} {% endif %}): Promise { diff --git a/partials/index/Subscribe.njk b/partials/index/Subscribe.njk index 7c37d6883..f98ea56c6 100644 --- a/partials/index/Subscribe.njk +++ b/partials/index/Subscribe.njk @@ -4,7 +4,7 @@ * {{messageDescription}} * @param onDataCallback Called when message recieved. */ - public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsError, msg?: {{ message.uid() | pascalCase }}Message) => void {% if parameters | length %} + public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsError, msg?: {{ message.uid() | pascalCase }}Message{% if parameters | length %}, {{parameters | realizeParametersForChannel(false)}}{% endif %}) => void {% if parameters | length %} ,{{parameters | realizeParametersForChannel}} {% endif %}): Promise { {%- if message.contentType() | isBinaryPayload(defaultContentType) %} From 246ec829354ea88071cc5f86128c2578481fb6cf Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Wed, 20 May 2020 20:03:20 +0200 Subject: [PATCH 046/110] Finished promisify parameter for reply callback --- .tp-config.json | 4 ++ partials/channel/Publish.njk | 8 +-- partials/channel/Reply.njk | 27 +++++---- partials/channel/Request.njk | 8 +-- partials/channel/Subscribe.njk | 22 ++++---- partials/index/Publish.njk | 10 ++-- partials/index/Reply.njk | 12 ++-- partials/index/Request.njk | 10 ++-- partials/index/Subscribe.njk | 10 ++-- template/src/channels/$$channel$$.ts.njk | 2 +- template/src/index.ts.njk | 2 +- template/src/tests/$$channel$$.ts | 0 .../tests/blackbox/$$channel$$.spec.ts.njk | 56 +++++++++++++++++++ ...ec.ts.njk => $$objectSchema$$.spec.ts.njk} | 0 .../testchannels/$$channel$$.ts.njk | 2 +- 15 files changed, 116 insertions(+), 57 deletions(-) delete mode 100644 template/src/tests/$$channel$$.ts create mode 100644 template/src/tests/blackbox/$$channel$$.spec.ts.njk rename template/src/tests/schemas/{$$schema$$.spec.ts.njk => $$objectSchema$$.spec.ts.njk} (100%) diff --git a/.tp-config.json b/.tp-config.json index 4a14fb0bc..e887bf06d 100644 --- a/.tp-config.json +++ b/.tp-config.json @@ -4,6 +4,10 @@ "generateTestFiles": { "description": "Generate the test files for the client as well", "required": false + }, + "promisifyReplyCallback": { + "description": "Use promises as callbacks for reply operation", + "required": false } }, "generator": ">=0.41.0 <2.0.0", diff --git a/partials/channel/Publish.njk b/partials/channel/Publish.njk index b3966be1b..b26c2b6f0 100644 --- a/partials/channel/Publish.njk +++ b/partials/channel/Publish.njk @@ -1,11 +1,11 @@ -{% macro publish(channelName, parameters, publishMessage, server) %} +{% macro publish(channelName, channelParameters, publishMessage, server) %} export function publish( requestMessage: {{publishMessage.uid() | pascalCase}}Message, nc: Client, - {% if parameters | length %} - {{parameters | realizeParametersForChannel}} + {% if channelParameters | length %} + {{channelParameters | realizeParametersForChannel}} {% endif %} ): Promise { return new Promise(async (resolve, reject) => { @@ -16,7 +16,7 @@ export function publish( for(let hook of publishDataHooks){ dataToPublish = hook(dataToPublish); } - nc.publish({{parameters | realizeChannelName(channelName)}}, dataToPublish); + nc.publish({{channelParameters | realizeChannelName(channelName)}}, dataToPublish); resolve(); }catch(e){ reject(e); diff --git a/partials/channel/Reply.njk b/partials/channel/Reply.njk index ccd598413..adb5ca5c8 100644 --- a/partials/channel/Reply.njk +++ b/partials/channel/Reply.njk @@ -1,11 +1,12 @@ -{% macro reply(channelName, parameters, subscribtionMessage, publishMessage, server) %} +{% macro reply(channelName, channelParameters, subscribtionMessage, publishMessage, server, params) %} export function reply( - onRequest: (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message{% if parameters | length %}, {{parameters | realizeParametersForChannel(false)}}{% endif %}) => {{publishMessage.uid() | pascalCase}}Message, + onRequest: (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => + {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{publishMessage.uid() | pascalCase}}Message{%-if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError: (err: NatsError) => void, nc: Client, - {% if parameters | length %} - {{parameters | realizeParametersForChannel}} + {% if channelParameters | length %} + {{channelParameters | realizeParametersForChannel}} {% endif %} ): Promise { return new Promise(async (resolve, reject) => { @@ -23,16 +24,16 @@ export function reply( {%- endif %} {%- endif %} - let subscription = nc.subscribe({{parameters | realizeChannelName(channelName)}}, (err, msg) => { + let subscription = nc.subscribe({{channelParameters | realizeChannelName(channelName)}}, {%- if params.promisifyReplyCallback | length %}async{%- endif %} (err, msg) => { if (err) { onRequest(err); } else { - {%- if parameters | length %} + {%- if channelParameters | length %} const unmodifiedChannel = {{channelName | realizeChannelNameWithoutParameters}} const receivedTopicParameters = { {%- set counter = 1 %} - {%- for parameterName, parameter in parameters %} - {{parameterName}} : msg.subject.slice(unmodifiedChannel.split("${{'{'+ parameterName+ '}'}}")[0].length, msg.subject.length-unmodifiedChannel.split("${{'{'+parameterName+'}'}}")[1].length){%- if counter < (parameters | length) %},{%- endif %} + {%- for parameterName, parameter in channelParameters %} + {{parameterName}} : msg.subject.slice(unmodifiedChannel.split("${{'{'+ parameterName+ '}'}}")[0].length, msg.subject.length-unmodifiedChannel.split("${{'{'+parameterName+'}'}}")[1].length){%- if counter < (channelParameters | length) %},{%- endif %} {%- set counter = counter+1 %} {%- endfor %} } @@ -43,11 +44,10 @@ export function reply( processedDataReceived = hook(processedDataReceived); } let requestData = {{subscribtionMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); - - let responseObject = onRequest(undefined, requestData{% if parameters | length %}, + let responseObject = {%-if params.promisifyReplyCallback | length %}await{%- endif %} onRequest(undefined, requestData{% if channelParameters | length %}, {%- set counter = 1 %} - {%- for parameterName, parameter in parameters %} - receivedTopicParameters['{{parameterName}}']{%- if counter < (parameters | length) %},{%- endif %} + {%- for parameterName, parameter in channelParameters %} + receivedTopicParameters['{{parameterName}}']{%- if counter < (channelParameters | length) %},{%- endif %} {%- set counter = counter+1 %} {%- endfor %} {%- endif %}); @@ -70,8 +70,7 @@ export function reply( let error = new NatsError('Expected request to need a reply, did not..', '000'); if (onReplyError) { onReplyError(error) - } else { - console.error(error) + } else { } } } diff --git a/partials/channel/Request.njk b/partials/channel/Request.njk index e5e7ccaf6..451f77b03 100644 --- a/partials/channel/Request.njk +++ b/partials/channel/Request.njk @@ -1,10 +1,10 @@ -{% macro request(channelName, parameters, publishMessage, subscribtionMessage, server) %} +{% macro request(channelName, channelParameters, publishMessage, subscribtionMessage, server) %} export function request( requestMessage: {{publishMessage.uid() | pascalCase}}Message, nc: Client, - {% if parameters | length %} - {{parameters | realizeParametersForChannel}} + {% if channelParameters | length %} + {{channelParameters | realizeParametersForChannel}} {% endif %} ): Promise<{{subscribtionMessage.uid() | pascalCase}}Message> { return new Promise<{{subscribtionMessage.uid() | pascalCase}}Message>(async (resolve, reject) => { @@ -28,7 +28,7 @@ export function request( for(let hook of publishDataHooks){ requestData = hook(requestData); } - nc.publish({{parameters | realizeChannelName(channelName)}}, requestData, inbox); + nc.publish({{channelParameters | realizeChannelName(channelName)}}, requestData, inbox); }catch(e){ reject(e); } diff --git a/partials/channel/Subscribe.njk b/partials/channel/Subscribe.njk index b742fabff..4643ca2e2 100644 --- a/partials/channel/Subscribe.njk +++ b/partials/channel/Subscribe.njk @@ -1,10 +1,10 @@ -{% macro subscribe(channelName, parameters, subscribtionMessage, server) %} +{% macro subscribe(channelName, channelParameters, subscribtionMessage, server) %} export function subscribe( - onDataCallback : (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message{% if parameters | length %}, {{parameters | realizeParametersForChannel(false)}}{% endif %}) => void, + onDataCallback : (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void, nc: Client, - {% if parameters | length %} - {{parameters | realizeParametersForChannel}} + {% if channelParameters | length %} + {{channelParameters | realizeParametersForChannel}} {% endif %} ): Promise { return new Promise(async (resolve, reject) => { @@ -21,16 +21,16 @@ export function subscribe( {%- endif %} {%- endif %} - let subscription = nc.subscribe({{parameters | realizeChannelName(channelName)}}, (err, msg) => { + let subscription = nc.subscribe({{channelParameters | realizeChannelName(channelName)}}, (err, msg) => { if(err){ onDataCallback(err); }else{ - {%- if parameters | length %} + {%- if channelParameters | length %} const unmodifiedChannel = {{channelName | realizeChannelNameWithoutParameters}} const receivedTopicParameters = { {%- set counter = 1 %} - {%- for parameterName, parameter in parameters %} - {{parameterName}} : msg.subject.slice(unmodifiedChannel.split("${{'{'+ parameterName+ '}'}}")[0].length, msg.subject.length-unmodifiedChannel.split("${{'{'+parameterName+'}'}}")[1].length){%- if counter < (parameters | length) %},{%- endif %} + {%- for parameterName, parameter in channelParameters %} + {{parameterName}} : msg.subject.slice(unmodifiedChannel.split("${{'{'+ parameterName+ '}'}}")[0].length, msg.subject.length-unmodifiedChannel.split("${{'{'+parameterName+'}'}}")[1].length){%- if counter < (channelParameters | length) %},{%- endif %} {%- set counter = counter+1 %} {%- endfor %} } @@ -41,10 +41,10 @@ export function subscribe( processedDataReceived = hook(processedDataReceived); } let publishedData = {{subscribtionMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); - onDataCallback(undefined, publishedData{% if parameters | length %}, + onDataCallback(undefined, publishedData{% if channelParameters | length %}, {%- set counter = 1 %} - {%- for parameterName, parameter in parameters %} - receivedTopicParameters['{{parameterName}}']{%- if counter < (parameters | length) %},{%- endif %} + {%- for parameterName, parameter in channelParameters %} + receivedTopicParameters['{{parameterName}}']{%- if counter < (channelParameters | length) %},{%- endif %} {%- set counter = counter+1 %} {%- endfor %} {%- endif %}); diff --git a/partials/index/Publish.njk b/partials/index/Publish.njk index 80e6c7131..4e6468ec9 100644 --- a/partials/index/Publish.njk +++ b/partials/index/Publish.njk @@ -1,11 +1,11 @@ -{% macro publish(defaultContentType, channelName, message, messageDescription, parameters) %} +{% macro publish(defaultContentType, channelName, message, messageDescription, channelParameters) %} /** * {{messageDescription}} * @param requestMessage The message to publish. */ - public publishTo{{channelName | pascalCase }}(requestMessage: {{ message.uid() | pascalCase }}Message {% if parameters | length %} - ,{{parameters | realizeParametersForChannel}} + public publishTo{{channelName | pascalCase }}(requestMessage: {{ message.uid() | pascalCase }}Message {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannel}} {% endif %}): Promise { {%- if message.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; @@ -18,8 +18,8 @@ {%- endif %} if(nc){ return {{ channelName | camelCase }}Channel.publish(requestMessage, nc - {% if parameters | length %} - ,{{parameters | realizeParametersForChannelWithoutType}} + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannelWithoutType}} {% endif %}); }else{ return Promise.reject(new Error('Nats client is not connected, could not send message on channel {{ channelName | camelCase }}')) diff --git a/partials/index/Reply.njk b/partials/index/Reply.njk index 5952da29b..f79034fcf 100644 --- a/partials/index/Reply.njk +++ b/partials/index/Reply.njk @@ -1,13 +1,13 @@ -{% macro reply(defaultContentType, channelName, subscribeMessage, publishMessage, messageDescription, parameters) %} +{% macro reply(defaultContentType, channelName, subscribeMessage, publishMessage, messageDescription, channelParameters, params) %} /** * {{messageDescription}} * @param onRequest Called when request recieved. * @param onReplyError Called when it was not possible to send the reply. */ - public replyTo{{channelName | pascalCase }}(onRequest : (err?: NatsError, msg?: {{ subscribeMessage.uid() | pascalCase }}Message{% if parameters | length %}, {{parameters | realizeParametersForChannel(false)}}{% endif %}) => {{ publishMessage.uid() | pascalCase }}Message, onReplyError : (err: NatsError) => void - {% if parameters | length %} - ,{{parameters | realizeParametersForChannel}} + public replyTo{{channelName | pascalCase }}(onRequest : (err?: NatsError, msg?: {{ subscribeMessage.uid() | pascalCase }}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{ publishMessage.uid() | pascalCase }}Message{%- if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError : (err: NatsError) => void + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannel}} {% endif %}): Promise { {%- if subscribeMessage.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; @@ -21,8 +21,8 @@ if(nc){ return {{ channelName | camelCase }}Channel.reply(onRequest, onReplyError, nc - {% if parameters | length %} - ,{{parameters | realizeParametersForChannelWithoutType}} + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannelWithoutType}} {% endif %}); }else{ return Promise.reject(new Error('Nats client is not connected, could not send message on channel {{ channelName | camelCase }}')) diff --git a/partials/index/Request.njk b/partials/index/Request.njk index b7219addc..a2c98f429 100644 --- a/partials/index/Request.njk +++ b/partials/index/Request.njk @@ -1,12 +1,12 @@ -{% macro request(defaultContentType, channelName, publishMessage, subscribeMessage, messageDescription, parameters) %} +{% macro request(defaultContentType, channelName, publishMessage, subscribeMessage, messageDescription, channelParameters) %} /** * {{messageDescription}} * @param requestMessage The request message to send. */ public request{{channelName | pascalCase }}(requestMessage: {{ publishMessage.uid() | pascalCase }}Message - {% if parameters | length %} - ,{{parameters | realizeParametersForChannel}} + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannel}} {% endif %}): Promise<{{ subscribeMessage.uid() | pascalCase }}Message> { {%- if publishMessage.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; @@ -19,8 +19,8 @@ {%- endif %} if(nc){ return {{ channelName | camelCase }}Channel.request(requestMessage, nc - {% if parameters | length %} - ,{{parameters | realizeParametersForChannelWithoutType}} + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannelWithoutType}} {% endif %}); }else{ return Promise.reject(new Error('Nats client is not connected, could not send message on channel {{ channelName | camelCase }}')) diff --git a/partials/index/Subscribe.njk b/partials/index/Subscribe.njk index f98ea56c6..fa50ef4e3 100644 --- a/partials/index/Subscribe.njk +++ b/partials/index/Subscribe.njk @@ -1,11 +1,11 @@ -{% macro subscribe(defaultContentType, channelName, message, messageDescription, parameters) %} +{% macro subscribe(defaultContentType, channelName, message, messageDescription, channelParameters) %} /** * {{messageDescription}} * @param onDataCallback Called when message recieved. */ - public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsError, msg?: {{ message.uid() | pascalCase }}Message{% if parameters | length %}, {{parameters | realizeParametersForChannel(false)}}{% endif %}) => void {% if parameters | length %} - ,{{parameters | realizeParametersForChannel}} + public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsError, msg?: {{ message.uid() | pascalCase }}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannel}} {% endif %}): Promise { {%- if message.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; @@ -18,8 +18,8 @@ {%- endif %} if(nc){ return {{ channelName | camelCase }}Channel.subscribe(onDataCallback, nc - {% if parameters | length %} - ,{{parameters | realizeParametersForChannelWithoutType}} + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannelWithoutType}} {% endif %}); }else{ return Promise.reject(new Error('Nats client is not connected, could not send message on channel {{ channelName | camelCase }}')) diff --git a/template/src/channels/$$channel$$.ts.njk b/template/src/channels/$$channel$$.ts.njk index d0f6fa9ca..cfa587e23 100644 --- a/template/src/channels/$$channel$$.ts.njk +++ b/template/src/channels/$$channel$$.ts.njk @@ -16,7 +16,7 @@ import { Hooks } from '#hooks'; {{ request(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} {%- endif %} {%- if channel | isReplier %} - {{ reply(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server)) }} + {{ reply(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), params) }} {%- endif %} {%- endif %} diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index 6baf9cc01..234f95d55 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -186,7 +186,7 @@ export class NatsAsyncApiClient extends events.EventEmitter{ {{request(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- if channel | isReplier %} - {{reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters())}} + {{reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters(), params)}} {%- endif %} {%- endif %} diff --git a/template/src/tests/$$channel$$.ts b/template/src/tests/$$channel$$.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/template/src/tests/blackbox/$$channel$$.spec.ts.njk b/template/src/tests/blackbox/$$channel$$.spec.ts.njk new file mode 100644 index 000000000..11a649f34 --- /dev/null +++ b/template/src/tests/blackbox/$$channel$$.spec.ts.njk @@ -0,0 +1,56 @@ +import {NatsAsyncApiTestClient} from '#testclient' +import {NatsAsyncApiClient} from '#client' +import { default as AchievementSchema } from '#schemas/Achievement'; +{%- if channel.hasPublish() %} +import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '#messages/{{ channel.publish().message(0).uid() | pascalCase}}' +{%- for _, import in (channel.publish().message(0).payload() | genericImports) %} +{{import | safe }} +{%- endfor %} +{%- endif %} +{%- if channel.hasSubscribe() %} +import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '#messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' +{%- for _, import in (channel.subscribe().message(0).payload() | genericImports) %} +{{import | safe }} +{%- endfor %} +{%- endif %} +import { expect } from 'chai'; +import 'mocha'; + +describe('{{channelName | pascalCase}}', () => { + it('should be able to publish to publish to channel', () => { + return new Promise(async (resolve, reject) => { + try{ + const natsRustAPiClient = new NatsAsyncApiClient(); + const testNatsRustAPiClient = new NatsAsyncApiTestClient(); + await natsRustAPiClient.connect({url: "0.0.0.0:8589", reconnectTimeWait: 1000, reconnect: true, waitOnFirstConnect: true, maxReconnectAttempts: -1}); + await testNatsRustAPiClient.connect({url: "0.0.0.0:8589", reconnectTimeWait: 1000, reconnect: true, waitOnFirstConnect: true, maxReconnectAttempts: -1}); + + const achievement = new AchievementSchema(); + const message = new PublishForServerPlayerAchievementsAcquired(achievement) + const parameterServerId = 2; + const parameterPlayerId = "test" + let subscription = await testNatsRustAPiClient.subscribeToRustServersServerIdPlayersSteamIdAchievementsAcquired((err, msg) => { + try{ + expect(msg).to.deep.equal(message); + resolve(); + }catch(e){ + reject(e); + } + subscription.unsubscribe() + natsRustAPiClient.disconnect(); + testNatsRustAPiClient.disconnect(); + }, parameterServerId, parameterPlayerId); + //Delay a bit + setTimeout(async () => { + try{ + await natsRustAPiClient.publishToRustServersServerIdPlayersSteamIdAchievementsAcquired(message, parameterServerId, parameterPlayerId); + }catch(e){ + console.log(e); + } + }, 150); + }catch(e){ + reject(e) + } + }) + }); +}); diff --git a/template/src/tests/schemas/$$schema$$.spec.ts.njk b/template/src/tests/schemas/$$objectSchema$$.spec.ts.njk similarity index 100% rename from template/src/tests/schemas/$$schema$$.spec.ts.njk rename to template/src/tests/schemas/$$objectSchema$$.spec.ts.njk diff --git a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk index 764cb2a89..a76dc230f 100644 --- a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk +++ b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk @@ -15,7 +15,7 @@ import { Hooks } from '#hooks'; {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{ reply(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} + {{ reply(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server), params) }} {%- endif %} {%- if channel | isReplier %} {{ request(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server)) }} From 153808097222bca564abe849143fecc328219f4f Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sun, 24 May 2020 21:22:26 +0200 Subject: [PATCH 047/110] Reversed the generation of channel operations to fitting the spec. --- template/src/index.ts.njk | 30 ++++++++++------------ template/src/tests/testclient/index.ts.njk | 30 ++++++++++------------ 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index 234f95d55..a1e05abb8 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -180,24 +180,22 @@ export class NatsAsyncApiClient extends events.EventEmitter{ } {%- for channelName, channel in asyncapi.channels() %} - - {%- if channel | isRequestReply %} - {%- if channel | isRequester %} - {{request(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters())}} - {%- endif %} - {%- if channel | isReplier %} - {{reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters(), params)}} + {%- if channel | isRequestReply %} + {%- if channel | isRequester %} + {{reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters(), params)}} + {%- endif %} + {%- if channel | isReplier %} + {{request(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters())}} + {%- endif %} {%- endif %} - {%- endif %} - {%- if channel | isPubsub %} - {%- if channel.hasSubscribe() %} - {{subscribe(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.description(), channel.parameters())}} - {%- endif %} - {%- if channel.hasPublish() %} - {{publish(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.description(), channel.parameters())}} + {%- if channel | isPubsub %} + {%- if channel.hasSubscribe() %} + {{publish(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.description(), channel.parameters())}} + {%- endif %} + {%- if channel.hasPublish() %} + {{subscribe(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.description(), channel.parameters())}} + {%- endif %} {%- endif %} - {%- endif %} - {%- endfor %} } diff --git a/template/src/tests/testclient/index.ts.njk b/template/src/tests/testclient/index.ts.njk index a17f45136..323e7028c 100644 --- a/template/src/tests/testclient/index.ts.njk +++ b/template/src/tests/testclient/index.ts.njk @@ -180,25 +180,23 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ } {%- for channelName, channel in asyncapi.channels() %} - - {%- if channel | isRequestReply %} - {%- if channel | isRequester %} - {{reply(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters())}} - {%- endif %} - {%- if channel | isReplier %} - {{request(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters())}} + {%- if channel | isRequestReply %} + {%- if channel | isRequester %} + {{request(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters())}} + {%- endif %} + {%- if channel | isReplier %} + {{reply(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters(), params)}} + {%- endif %} {%- endif %} - {%- endif %} - {%- if channel | isPubsub %} - {%- if channel.hasSubscribe() %} - {{publish(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.description(), channel.parameters())}} - {%- endif %} - {%- if channel.hasPublish() %} - {{subscribe(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.description(), channel.parameters())}} + {%- if channel | isPubsub %} + {%- if channel.hasSubscribe() %} + {{subscribe(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.description(), channel.parameters())}} + {%- endif %} + {%- if channel.hasPublish() %} + {{publish(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.description(), channel.parameters())}} + {%- endif %} {%- endif %} - {%- endif %} - {%- endfor %} } \ No newline at end of file From 135ce9ed4947962039dc709bc41b185d3e47c040 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sun, 24 May 2020 21:32:05 +0200 Subject: [PATCH 048/110] Created macro for standard client code to avoid dublicated code. --- partials/index/Standard.njk | 179 +++++++++++++++++++++ template/src/index.ts.njk | 177 +------------------- template/src/tests/testclient/index.ts.njk | 178 +------------------- 3 files changed, 183 insertions(+), 351 deletions(-) create mode 100644 partials/index/Standard.njk diff --git a/partials/index/Standard.njk b/partials/index/Standard.njk new file mode 100644 index 000000000..7fbe9207a --- /dev/null +++ b/partials/index/Standard.njk @@ -0,0 +1,179 @@ + +{% macro standard(asyncapi) %} +import { + Client, + NatsConnectionOptions, + connect, + Payload, + NatsError, + Subscription, + ServersChangedEvent, + SubEvent, + ServerInfo + } from 'ts-nats'; + +{%- for channelName, _ in asyncapi.channels() %} +import * as {{ channelName | camelCase }}Channel from "#testchannels/{{ channelName | pascalCase | firstUpperCase }}"; +{%- endfor %} + +{%- for messageName, _ in asyncapi.allMessages() %} +import {default as {{ messageName | pascalCase }}Message} from "#messages/{{ messageName | pascalCase }}"; +{%- endfor %} +import {fromSeed} from 'ts-nkeys'; +import * as events from 'events'; +export enum AvailableEvents { + connectionError = 'connectionError', + permissionError = 'permissionError', + close = 'close', + connect = 'connect', + connecting = 'connecting', + disconnect = 'disconnect', + error = 'error', + pingcount = 'pingcount', + pingtimer = 'pingtimer', + reconnect = 'reconnect', + reconnecting = 'reconnecting', + serversChanged = 'serversChanged', + subscribe = 'subscribe', + unsubscribe = 'unsubscribe', + yield = 'yield' +} +export declare interface NatsAsyncApiTestClient { + on(event: AvailableEvents.connectionError, listener: (error: any) => void): this; + on(event: AvailableEvents.permissionError, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.close, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; + on(event: AvailableEvents.connecting, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.error, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.pingcount, listener: () => void): this; + on(event: AvailableEvents.pingtimer, listener: () => void): this; + on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; + on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; + on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.yield, listener: () => void): this; +} +export class NatsAsyncApiTestClient extends events.EventEmitter{ + public jsonClient?: Client; + public stringClient?: Client; + public binaryClient?: Client; + public options?: NatsConnectionOptions; + + /** + * + * @param options options to use, payload is omitted if sat in the AsyncAPI document. + */ + constructor() { + super(); + } + + /** + * Try to connect to the NATS server with the different payloads. + */ + async connect(options : NatsConnectionOptions){ + this.options = this.setDefaultOptions(options); + try{ + {%- if asyncapi | containsBinaryPayload %} + this.options.payload = Payload.BINARY; + this.binaryClient = await connect(this.options); + this.chainEvents(this.binaryClient); + {%- endif %} + {%- if asyncapi | containsStringPayload %} + this.options.payload = Payload.STRING; + this.stringClient = await connect(this.options); + this.chainEvents(this.stringClient); + {%- endif %} + {%- if asyncapi | containsJsonPayload %} + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); + {%- endif %} + }catch(e){ + this.emit(AvailableEvents.connectionError, e) + } + } + + + /** + * Disconnect all clients from the server + */ + async disconnect(){ + {%- if asyncapi | containsBinaryPayload %} + this.binaryClient!.close() + {%- endif %} + {%- if asyncapi | containsStringPayload %} + this.stringClient!.close() + {%- endif %} + {%- if asyncapi | containsJsonPayload %} + this.jsonClient!.close() + {%- endif %} + } + + private chainEvents(ns: Client){ + ns.on('permissionError', (e: NatsError) => { + this.emit(AvailableEvents.permissionError, e) + }); + ns.on('close', (e: NatsError) => { + this.emit(AvailableEvents.close, e) + }); + ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.connect, connection, serverURL, info) + }); + ns.on('connecting', (serverURL: NatsError) => { + this.emit(AvailableEvents.connecting, serverURL) + }); + ns.on('disconnect', (serverURL: string) => { + this.emit(AvailableEvents.disconnect, serverURL) + }); + ns.on('error', (e: NatsError) => { + this.emit(AvailableEvents.error, e) + }); + ns.on('pingcount', () => { + this.emit(AvailableEvents.pingcount) + }); + ns.on('pingtimer', () => { + this.emit(AvailableEvents.pingtimer) + }); + ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.reconnect, connection, serverURL, info) + }); + ns.on('reconnecting', (serverURL: string) => { + this.emit(AvailableEvents.reconnecting, serverURL) + }); + ns.on('serversChanged', (e: ServersChangedEvent) => { + this.emit(AvailableEvents.serversChanged, e) + }); + ns.on('subscribe', (e: SubEvent) => { + this.emit(AvailableEvents.subscribe, e) + }); + ns.on('unsubscribe', (e: SubEvent) => { + this.emit(AvailableEvents.unsubscribe, e) + }); + ns.on('yield', () => { + this.emit(AvailableEvents.yield) + }); + } + /** + * Try to connect to the NATS server with nkey authentication + */ + async connectWithNkey(options : NatsConnectionOptions, publicNkey: string, seed: string){ + options.nkey = publicNkey; + options.nonceSigner = (nonce: string): Buffer => { + const sk = fromSeed(Buffer.from(seed)); + return sk.sign(Buffer.from(nonce)); + } + await this.connect(options); + } + /** + * Set the default options based on the AsyncAPI file. + * @param options to set + */ + private setDefaultOptions(options: NatsConnectionOptions){ + //If server binding options sat set the options + options.encoding = 'utf8'; + return options; + } + +{% endmacro %} \ No newline at end of file diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index a1e05abb8..0ce08fd1d 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -3,181 +3,8 @@ {%- from "../../partials/index/Reply.njk" import reply %} {%- from "../../partials/index/Request.njk" import request %} {%- from "../../partials/index/Subscribe.njk" import subscribe %} - -import { - Client, - NatsConnectionOptions, - connect, - Payload, - NatsError, - Subscription, - ServersChangedEvent, - SubEvent, - ServerInfo - } from 'ts-nats'; - -{%- for channelName, _ in asyncapi.channels() %} -import * as {{ channelName | camelCase }}Channel from "#channels/{{ channelName | pascalCase | firstUpperCase }}"; -{%- endfor %} - -{%- for messageName, _ in asyncapi.allMessages() %} -import {default as {{ messageName | pascalCase }}Message} from "#messages/{{ messageName | pascalCase }}"; -{%- endfor %} -import {fromSeed} from 'ts-nkeys'; -import * as events from 'events'; -export enum AvailableEvents { - connectionError = 'connectionError', - permissionError = 'permissionError', - close = 'close', - connect = 'connect', - connecting = 'connecting', - disconnect = 'disconnect', - error = 'error', - pingcount = 'pingcount', - pingtimer = 'pingtimer', - reconnect = 'reconnect', - reconnecting = 'reconnecting', - serversChanged = 'serversChanged', - subscribe = 'subscribe', - unsubscribe = 'unsubscribe', - yield = 'yield' -} -export declare interface NatsAsyncApiClient { - on(event: AvailableEvents.connectionError, listener: (error: any) => void): this; - on(event: AvailableEvents.permissionError, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.close, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; - on(event: AvailableEvents.connecting, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; - on(event: AvailableEvents.error, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.pingcount, listener: () => void): this; - on(event: AvailableEvents.pingtimer, listener: () => void): this; - on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; - on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; - on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; - on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; - on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; - on(event: AvailableEvents.yield, listener: () => void): this; -} -export class NatsAsyncApiClient extends events.EventEmitter{ - public jsonClient?: Client; - public stringClient?: Client; - public binaryClient?: Client; - public options?: NatsConnectionOptions; - - /** - * - * @param options options to use, payload is omitted if sat in the AsyncAPI document. - */ - constructor() { - super(); - } - - /** - * Try to connect to the NATS server with the different payloads. - */ - async connect(options : NatsConnectionOptions){ - this.options = this.setDefaultOptions(options); - try{ - {%- if asyncapi | containsBinaryPayload %} - this.options.payload = Payload.BINARY; - this.binaryClient = await connect(this.options); - this.chainEvents(this.binaryClient); - {%- endif %} - {%- if asyncapi | containsStringPayload %} - this.options.payload = Payload.STRING; - this.stringClient = await connect(this.options); - this.chainEvents(this.stringClient); - {%- endif %} - {%- if asyncapi | containsJsonPayload %} - this.options.payload = Payload.JSON; - this.jsonClient = await connect(this.options); - this.chainEvents(this.jsonClient); - {%- endif %} - }catch(e){ - this.emit(AvailableEvents.connectionError, e) - } - } - - /** - * Disconnect all clients from the server - */ - async disconnect(){ - {%- if asyncapi | containsBinaryPayload %} - this.binaryClient!.close() - {%- endif %} - {%- if asyncapi | containsStringPayload %} - this.stringClient!.close() - {%- endif %} - {%- if asyncapi | containsJsonPayload %} - this.jsonClient!.close() - {%- endif %} - } - - private chainEvents(ns: Client){ - ns.on('permissionError', (e: NatsError) => { - this.emit(AvailableEvents.permissionError, e) - }); - ns.on('close', (e: NatsError) => { - this.emit(AvailableEvents.close, e) - }); - ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { - this.emit(AvailableEvents.connect, connection, serverURL, info) - }); - ns.on('connecting', (serverURL: NatsError) => { - this.emit(AvailableEvents.connecting, serverURL) - }); - ns.on('disconnect', (serverURL: string) => { - this.emit(AvailableEvents.disconnect, serverURL) - }); - ns.on('error', (e: NatsError) => { - this.emit(AvailableEvents.error, e) - }); - ns.on('pingcount', () => { - this.emit(AvailableEvents.pingcount) - }); - ns.on('pingtimer', () => { - this.emit(AvailableEvents.pingtimer) - }); - ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { - this.emit(AvailableEvents.reconnect, connection, serverURL, info) - }); - ns.on('reconnecting', (serverURL: string) => { - this.emit(AvailableEvents.reconnecting, serverURL) - }); - ns.on('serversChanged', (e: ServersChangedEvent) => { - this.emit(AvailableEvents.serversChanged, e) - }); - ns.on('subscribe', (e: SubEvent) => { - this.emit(AvailableEvents.subscribe, e) - }); - ns.on('unsubscribe', (e: SubEvent) => { - this.emit(AvailableEvents.unsubscribe, e) - }); - ns.on('yield', () => { - this.emit(AvailableEvents.yield) - }); - } - /** - * Try to connect to the NATS server with nkey authentication - */ - async connectWithNkey(options : NatsConnectionOptions, publicNkey: string, seed: string){ - options.nkey = publicNkey; - options.nonceSigner = (nonce: string): Buffer => { - const sk = fromSeed(Buffer.from(seed)); - return sk.sign(Buffer.from(nonce)); - } - await this.connect(options); - } - /** - * Set the default options based on the AsyncAPI file. - * @param options to set - */ - private setDefaultOptions(options: NatsConnectionOptions){ - //If server binding options sat set the options - options.encoding = 'utf8'; - return options; - } +{%- from "../../partials/index/Standard.njk" import standard %} + {{standard(asyncapi)}} {%- for channelName, channel in asyncapi.channels() %} {%- if channel | isRequestReply %} diff --git a/template/src/tests/testclient/index.ts.njk b/template/src/tests/testclient/index.ts.njk index 323e7028c..ff0eb84af 100644 --- a/template/src/tests/testclient/index.ts.njk +++ b/template/src/tests/testclient/index.ts.njk @@ -3,182 +3,8 @@ {%- from "../../../../partials/index/Reply.njk" import reply %} {%- from "../../../../partials/index/Request.njk" import request %} {%- from "../../../../partials/index/Subscribe.njk" import subscribe %} -import { - Client, - NatsConnectionOptions, - connect, - Payload, - NatsError, - Subscription, - ServersChangedEvent, - SubEvent, - ServerInfo - } from 'ts-nats'; - -{%- for channelName, _ in asyncapi.channels() %} -import * as {{ channelName | camelCase }}Channel from "#testchannels/{{ channelName | pascalCase | firstUpperCase }}"; -{%- endfor %} - -{%- for messageName, _ in asyncapi.allMessages() %} -import {default as {{ messageName | pascalCase }}Message} from "#messages/{{ messageName | pascalCase }}"; -{%- endfor %} -import {fromSeed} from 'ts-nkeys'; -import * as events from 'events'; -export enum AvailableEvents { - connectionError = 'connectionError', - permissionError = 'permissionError', - close = 'close', - connect = 'connect', - connecting = 'connecting', - disconnect = 'disconnect', - error = 'error', - pingcount = 'pingcount', - pingtimer = 'pingtimer', - reconnect = 'reconnect', - reconnecting = 'reconnecting', - serversChanged = 'serversChanged', - subscribe = 'subscribe', - unsubscribe = 'unsubscribe', - yield = 'yield' -} -export declare interface NatsAsyncApiTestClient { - on(event: AvailableEvents.connectionError, listener: (error: any) => void): this; - on(event: AvailableEvents.permissionError, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.close, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; - on(event: AvailableEvents.connecting, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; - on(event: AvailableEvents.error, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.pingcount, listener: () => void): this; - on(event: AvailableEvents.pingtimer, listener: () => void): this; - on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; - on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; - on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; - on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; - on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; - on(event: AvailableEvents.yield, listener: () => void): this; -} -export class NatsAsyncApiTestClient extends events.EventEmitter{ - public jsonClient?: Client; - public stringClient?: Client; - public binaryClient?: Client; - public options?: NatsConnectionOptions; - - /** - * - * @param options options to use, payload is omitted if sat in the AsyncAPI document. - */ - constructor() { - super(); - } - - /** - * Try to connect to the NATS server with the different payloads. - */ - async connect(options : NatsConnectionOptions){ - this.options = this.setDefaultOptions(options); - try{ - {%- if asyncapi | containsBinaryPayload %} - this.options.payload = Payload.BINARY; - this.binaryClient = await connect(this.options); - this.chainEvents(this.binaryClient); - {%- endif %} - {%- if asyncapi | containsStringPayload %} - this.options.payload = Payload.STRING; - this.stringClient = await connect(this.options); - this.chainEvents(this.stringClient); - {%- endif %} - {%- if asyncapi | containsJsonPayload %} - this.options.payload = Payload.JSON; - this.jsonClient = await connect(this.options); - this.chainEvents(this.jsonClient); - {%- endif %} - }catch(e){ - this.emit(AvailableEvents.connectionError, e) - } - } - - - /** - * Disconnect all clients from the server - */ - async disconnect(){ - {%- if asyncapi | containsBinaryPayload %} - this.binaryClient!.close() - {%- endif %} - {%- if asyncapi | containsStringPayload %} - this.stringClient!.close() - {%- endif %} - {%- if asyncapi | containsJsonPayload %} - this.jsonClient!.close() - {%- endif %} - } - - private chainEvents(ns: Client){ - ns.on('permissionError', (e: NatsError) => { - this.emit(AvailableEvents.permissionError, e) - }); - ns.on('close', (e: NatsError) => { - this.emit(AvailableEvents.close, e) - }); - ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { - this.emit(AvailableEvents.connect, connection, serverURL, info) - }); - ns.on('connecting', (serverURL: NatsError) => { - this.emit(AvailableEvents.connecting, serverURL) - }); - ns.on('disconnect', (serverURL: string) => { - this.emit(AvailableEvents.disconnect, serverURL) - }); - ns.on('error', (e: NatsError) => { - this.emit(AvailableEvents.error, e) - }); - ns.on('pingcount', () => { - this.emit(AvailableEvents.pingcount) - }); - ns.on('pingtimer', () => { - this.emit(AvailableEvents.pingtimer) - }); - ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { - this.emit(AvailableEvents.reconnect, connection, serverURL, info) - }); - ns.on('reconnecting', (serverURL: string) => { - this.emit(AvailableEvents.reconnecting, serverURL) - }); - ns.on('serversChanged', (e: ServersChangedEvent) => { - this.emit(AvailableEvents.serversChanged, e) - }); - ns.on('subscribe', (e: SubEvent) => { - this.emit(AvailableEvents.subscribe, e) - }); - ns.on('unsubscribe', (e: SubEvent) => { - this.emit(AvailableEvents.unsubscribe, e) - }); - ns.on('yield', () => { - this.emit(AvailableEvents.yield) - }); - } - /** - * Try to connect to the NATS server with nkey authentication - */ - async connectWithNkey(options : NatsConnectionOptions, publicNkey: string, seed: string){ - options.nkey = publicNkey; - options.nonceSigner = (nonce: string): Buffer => { - const sk = fromSeed(Buffer.from(seed)); - return sk.sign(Buffer.from(nonce)); - } - await this.connect(options); - } - /** - * Set the default options based on the AsyncAPI file. - * @param options to set - */ - private setDefaultOptions(options: NatsConnectionOptions){ - //If server binding options sat set the options - options.encoding = 'utf8'; - return options; - } - +{%- from "../../../../partials/index/Standard.njk" import standard %} + {{standard(asyncapi)}} {%- for channelName, channel in asyncapi.channels() %} {%- if channel | isRequestReply %} {%- if channel | isRequester %} From a0ac01c89d145b66b5ea4d17f400c50d73ed3427 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 25 May 2020 00:35:13 +0200 Subject: [PATCH 049/110] Migrated to new generator. Removed unfinished tests. Changed the template README.md --- .tp-config.json | 15 ----- README.md | 49 +++++++++------- hooks/remove-test-files.js | 2 +- package.json | 15 +++++ .../tests/blackbox/$$channel$$.spec.ts.njk | 56 ------------------- .../schemas/$$objectSchema$$.spec.ts.njk | 34 ----------- 6 files changed, 44 insertions(+), 127 deletions(-) delete mode 100644 .tp-config.json delete mode 100644 template/src/tests/blackbox/$$channel$$.spec.ts.njk delete mode 100644 template/src/tests/schemas/$$objectSchema$$.spec.ts.njk diff --git a/.tp-config.json b/.tp-config.json deleted file mode 100644 index e887bf06d..000000000 --- a/.tp-config.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "supportedProtocols": ["nats"], - "parameters": { - "generateTestFiles": { - "description": "Generate the test files for the client as well", - "required": false - }, - "promisifyReplyCallback": { - "description": "Use promises as callbacks for reply operation", - "required": false - } - }, - "generator": ">=0.41.0 <2.0.0", - "filters": [ "@asyncapi/generator-filters"] -} \ No newline at end of file diff --git a/README.md b/README.md index a21d6b449..ee976654c 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,39 @@ -# Typescript NATS template +

Typescript NATS template

+

+ This is a typescript NATS template for the AsyncAPI generator. +

-## Template development -* Why use `.sh` files instead of just javascript files for generating the testing scenarios? +## Requirements +* @asyncapi/generator v1.0.0+ -Because of circular dependencies it is not possible to install the generator and then use this template directly. +Install the generator through [npm or run it from dockerofficial installer](https://github.com/asyncapi/generator) +## Features -## Template usage +## Available Parameters +These are the available parameters available when you generate code with the template: +|Parameter|Type|Description| +|---|---|---| +| generateTestClient | Boolean | Use this parameter to generate the [test client](###test-client). Add the following to the CLI when generating your code `--param "generateTestClient=true"` +| promisifyReplyCallback | Boolean | Use this parameter to change from the default regular callback when using the request operation. Add the following to the CLI when generating your code `--param "promisifyReplyCallback=true"` -### content types +## Test Client +The test client is like a mirror client. It does everything the opposite, when you define a subscription operation it will generate a subscription operation in the test client. This is opposite to what the specification dictates. This client can be used to create integration tests etc. -For binary payloads use: `binary` content type -For json payloads use: `json` content type -For string payloads use: `string` content type +## Supported Content Types +The following payload types are supported, this is limited to the underlying NATS typescript library: -### Hooks +* For binary payloads use: `binary` content type +* For json payloads use: `json` content type +* For string payloads use: `string` content type -Use the hooks to control the flow of information outside the generated code. - -These are the available hooks: - -| Hookname | Callback type | Description | -| BeforeSendingData | (Message: any) => new data | Called before sending any data. -| RevievedData | (recieved data: any) => new data | Called after data is recieved. +## Client Hooks +The client support custom hooks used to control the flow of information outside the generated code. The hooks can be used to alter the payload before sending or after recieving any data i.e. encrypt, compress data, etc. - -### OBS - -* Always specify schema id, since we cant resolve the dependency correctly atm. \ No newline at end of file +These are the available hooks: +|Hookname|Callback type|Description| +|---|---|---| +| BeforeSendingData | (Message: any) => new data | Called before sending any data. +| RecievedData | (recieved data: any) => new data | Called after data is recieved. diff --git a/hooks/remove-test-files.js b/hooks/remove-test-files.js index 90a123f12..4a668e82b 100644 --- a/hooks/remove-test-files.js +++ b/hooks/remove-test-files.js @@ -16,7 +16,7 @@ const deleteFolderRecursive = function(path) { }; module.exports = { 'generate:after': (generator) => { - if(generator.targetDir && generator.templateParams && !generator.templateParams.generateTestFiles){ + if(generator.targetDir && generator.templateParams && !generator.templateParams.generateTestClient){ pathToTests = Path.resolve(generator.targetDir, "src/tests/") deleteFolderRecursive(pathToTests) } diff --git a/package.json b/package.json index 53063b7e5..6ba04d427 100644 --- a/package.json +++ b/package.json @@ -24,5 +24,20 @@ "chai": "^4.2.0", "dir-compare": "^2.2.0", "mocha": "^7.1.1" + }, + "generator": { + "supportedProtocols": ["nats"], + "parameters": { + "generateTestClient": { + "description": "Generate the test client", + "required": false + }, + "promisifyReplyCallback": { + "description": "Use promises as callbacks for reply operation", + "required": false + } + }, + "generator": ">=0.50.0 <2.0.0", + "filters": [ "@asyncapi/generator-filters"] } } diff --git a/template/src/tests/blackbox/$$channel$$.spec.ts.njk b/template/src/tests/blackbox/$$channel$$.spec.ts.njk deleted file mode 100644 index 11a649f34..000000000 --- a/template/src/tests/blackbox/$$channel$$.spec.ts.njk +++ /dev/null @@ -1,56 +0,0 @@ -import {NatsAsyncApiTestClient} from '#testclient' -import {NatsAsyncApiClient} from '#client' -import { default as AchievementSchema } from '#schemas/Achievement'; -{%- if channel.hasPublish() %} -import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '#messages/{{ channel.publish().message(0).uid() | pascalCase}}' -{%- for _, import in (channel.publish().message(0).payload() | genericImports) %} -{{import | safe }} -{%- endfor %} -{%- endif %} -{%- if channel.hasSubscribe() %} -import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '#messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' -{%- for _, import in (channel.subscribe().message(0).payload() | genericImports) %} -{{import | safe }} -{%- endfor %} -{%- endif %} -import { expect } from 'chai'; -import 'mocha'; - -describe('{{channelName | pascalCase}}', () => { - it('should be able to publish to publish to channel', () => { - return new Promise(async (resolve, reject) => { - try{ - const natsRustAPiClient = new NatsAsyncApiClient(); - const testNatsRustAPiClient = new NatsAsyncApiTestClient(); - await natsRustAPiClient.connect({url: "0.0.0.0:8589", reconnectTimeWait: 1000, reconnect: true, waitOnFirstConnect: true, maxReconnectAttempts: -1}); - await testNatsRustAPiClient.connect({url: "0.0.0.0:8589", reconnectTimeWait: 1000, reconnect: true, waitOnFirstConnect: true, maxReconnectAttempts: -1}); - - const achievement = new AchievementSchema(); - const message = new PublishForServerPlayerAchievementsAcquired(achievement) - const parameterServerId = 2; - const parameterPlayerId = "test" - let subscription = await testNatsRustAPiClient.subscribeToRustServersServerIdPlayersSteamIdAchievementsAcquired((err, msg) => { - try{ - expect(msg).to.deep.equal(message); - resolve(); - }catch(e){ - reject(e); - } - subscription.unsubscribe() - natsRustAPiClient.disconnect(); - testNatsRustAPiClient.disconnect(); - }, parameterServerId, parameterPlayerId); - //Delay a bit - setTimeout(async () => { - try{ - await natsRustAPiClient.publishToRustServersServerIdPlayersSteamIdAchievementsAcquired(message, parameterServerId, parameterPlayerId); - }catch(e){ - console.log(e); - } - }, 150); - }catch(e){ - reject(e) - } - }) - }); -}); diff --git a/template/src/tests/schemas/$$objectSchema$$.spec.ts.njk b/template/src/tests/schemas/$$objectSchema$$.spec.ts.njk deleted file mode 100644 index 44076fced..000000000 --- a/template/src/tests/schemas/$$objectSchema$$.spec.ts.njk +++ /dev/null @@ -1,34 +0,0 @@ -import { expect } from 'chai'; -import 'mocha'; - -{% macro testProp(schema, required=true) %} - {%- if schema.allOf() | length %} - {%- for allOfSchema in schema.allOf() %} - {{testProp(allOfSchema)}} - {%- endfor %} - {%- endif %} - - {%- if schema.oneOf() | length %} - test:{{schema.oneOf() | oneOfSchemaType}} - {%- endif %} - - {%- if schema.anyOf() | length %} - {%- for oneOfSchema in schema.anyOf() %} - {{testProp(oneOfSchema, false)}} - {%- endfor %} - {%- endif %} - - {%- if schema.properties() | length %} - {%- for propertyName, property in schema.properties() %} - {{ propertyName}}{% if not required or not property.required() %}?{% endif %}: {{ property.type() | toTsType }} - {%- endfor %} - {%- endif %} - -{% endmacro %} - -describe('{{schema.uid() | camelCase}}', () => { - it('should contain ', () => { - const result = helloTest(); - expect(result).to.equal(true); - }); -}); \ No newline at end of file From af2a93db502a5d3b647448374b9601d9e535e53c Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Tue, 26 May 2020 19:21:43 +0200 Subject: [PATCH 050/110] Fixed expected and actual comparator generations. --- scripts/generate_new_actual_comparators.sh | 4 +- scripts/generate_new_expected_comparators.sh | 4 +- template/src/index.ts.njk | 8 +- template/src/tests/testclient/index.ts.njk | 8 +- test/docs/0.1.0/frontend.yml | 58 ++-- test/docs/0.1.0/light-controller.yml | 58 ++-- .../latest/frontend/README.md | 4 +- .../latest/frontend/package.json | 27 +- ...ingStreetlights10ActionStreetlightIdDim.ts | 70 +++++ ...treetlights10ActionStreetlightIdTurnOff.ts | 70 +++++ ...Streetlights10ActionStreetlightIdTurnOn.ts | 70 +++++ ...hts10EventStreetlightIdLightingMeasured.ts | 32 +++ ...etlights-1-0-action-{streetlightId}-dim.ts | 46 ---- ...hts-1-0-action-{streetlightId}-turn-off.ts | 46 ---- ...ghts-1-0-action-{streetlightId}-turn-on.ts | 46 ---- ...event-{streetlightId}-lighting-measured.ts | 44 ---- .../smartylighting-streetlights-1-0-event.ts | 40 --- .../latest/frontend/src/channels/utils.ts | 11 - .../latest/frontend/src/hooks.ts | 105 ++++---- .../latest/frontend/src/index.ts | 229 ++++++++++++---- .../latest/frontend/src/messages/DimLight.ts | 29 ++ .../src/messages/DimLightResponse.ts} | 12 +- .../src/messages/LightMeasured.ts} | 12 +- .../messages/{turnOnOff.ts => TurnOnOff.ts} | 12 +- .../src/messages/TurnOnOffResponse.ts} | 12 +- .../latest/frontend/src/messages/dimLight.ts | 45 ---- .../src/schema/DimLightPayloadserere.ts | 19 ++ .../src/schema/LightMeasuredPayload.ts} | 8 +- .../src/schema/Response.ts} | 9 +- .../src/schema/TurnOnOffPayload.ts} | 8 +- .../frontend/src/schema/anonymous-schema-4.ts | 11 - .../frontend/src/schema/anonymous-schema-5.ts | 22 -- ...etlights-1-0-action-{streetlightId}-dim.ts | 0 ...hts-1-0-action-{streetlightId}-turn-off.ts | 0 ...ghts-1-0-action-{streetlightId}-turn-on.ts | 0 ...event-{streetlightId}-lighting-measured.ts | 0 .../smartylighting-streetlights-1-0-event.ts | 0 .../frontend/src/tests/testclient/index.ts | 239 +++++++++++++++-- ...ingStreetlights10ActionStreetlightIdDim.ts | 45 ++++ ...treetlights10ActionStreetlightIdTurnOff.ts | 45 ++++ ...Streetlights10ActionStreetlightIdTurnOn.ts | 45 ++++ ...hts10EventStreetlightIdLightingMeasured.ts | 42 +++ ...etlights-1-0-action-{streetlightId}-dim.ts | 66 ----- ...hts-1-0-action-{streetlightId}-turn-off.ts | 66 ----- ...ghts-1-0-action-{streetlightId}-turn-on.ts | 66 ----- ...event-{streetlightId}-lighting-measured.ts | 37 --- .../smartylighting-streetlights-1-0-event.ts | 33 --- .../latest/frontend/tsconfig.json | 15 +- .../latest/light-controller/README.md | 4 +- .../latest/light-controller/package.json | 27 +- ...ingStreetlights10ActionStreetlightIdDim.ts | 45 ++++ ...treetlights10ActionStreetlightIdTurnOff.ts | 45 ++++ ...Streetlights10ActionStreetlightIdTurnOn.ts | 45 ++++ .../SmartylightingStreetlights10Event.ts | 35 +++ ...hts10EventStreetlightIdLightingMeasured.ts | 42 +++ ...etlights-1-0-action-{streetlightId}-dim.ts | 66 ----- ...hts-1-0-action-{streetlightId}-turn-off.ts | 66 ----- ...ghts-1-0-action-{streetlightId}-turn-on.ts | 66 ----- ...event-{streetlightId}-lighting-measured.ts | 37 --- .../light-controller/src/channels/utils.ts | 11 - .../latest/light-controller/src/hooks.ts | 105 ++++---- .../latest/light-controller/src/index.ts | 239 ++++++++++++++--- .../light-controller/src/messages/DimLight.ts | 29 ++ .../src/messages/DimLightResponse.ts} | 12 +- .../src/messages/LightMeasured.ts} | 12 +- .../messages/{turnOnOff.ts => TurnOnOff.ts} | 12 +- .../src/messages/TurnOnOffResponse.ts} | 12 +- .../light-controller/src/messages/dimLight.ts | 45 ---- .../src/schema/DimLightPayloadserere.ts | 19 ++ .../src/schema/LightMeasuredPayload.ts} | 8 +- .../src/schema/Response.ts} | 9 +- .../src/schema/TurnOnOffPayload.ts} | 8 +- .../src/schema/anonymous-schema-4.ts | 11 - .../src/schema/anonymous-schema-5.ts | 22 -- ...etlights-1-0-action-{streetlightId}-dim.ts | 0 ...hts-1-0-action-{streetlightId}-turn-off.ts | 0 ...ghts-1-0-action-{streetlightId}-turn-on.ts | 0 ...event-{streetlightId}-lighting-measured.ts | 0 .../src/tests/testclient/index.ts | 248 ++++++++++++++++-- ...ingStreetlights10ActionStreetlightIdDim.ts | 70 +++++ ...treetlights10ActionStreetlightIdTurnOff.ts | 70 +++++ ...Streetlights10ActionStreetlightIdTurnOn.ts | 70 +++++ .../SmartylightingStreetlights10Event.ts | 30 +++ ...hts10EventStreetlightIdLightingMeasured.ts | 32 +++ ...etlights-1-0-action-{streetlightId}-dim.ts | 46 ---- ...hts-1-0-action-{streetlightId}-turn-off.ts | 46 ---- ...ghts-1-0-action-{streetlightId}-turn-on.ts | 46 ---- ...event-{streetlightId}-lighting-measured.ts | 44 ---- .../latest/light-controller/tsconfig.json | 15 +- 89 files changed, 2129 insertions(+), 1498 deletions(-) create mode 100644 test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdDim.ts create mode 100644 test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts create mode 100644 test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts create mode 100644 test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts delete mode 100644 test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts delete mode 100644 test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts delete mode 100644 test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts delete mode 100644 test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts delete mode 100644 test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event.ts delete mode 100644 test/expected_comparators/latest/frontend/src/channels/utils.ts create mode 100644 test/expected_comparators/latest/frontend/src/messages/DimLight.ts rename test/expected_comparators/latest/{light-controller/src/messages/dimLightResponse.ts => frontend/src/messages/DimLightResponse.ts} (54%) rename test/expected_comparators/latest/{light-controller/src/messages/lightMeasured.ts => frontend/src/messages/LightMeasured.ts} (58%) rename test/expected_comparators/latest/frontend/src/messages/{turnOnOff.ts => TurnOnOff.ts} (57%) rename test/expected_comparators/latest/{light-controller/src/messages/turnOnOffResponse.ts => frontend/src/messages/TurnOnOffResponse.ts} (54%) delete mode 100644 test/expected_comparators/latest/frontend/src/messages/dimLight.ts create mode 100644 test/expected_comparators/latest/frontend/src/schema/DimLightPayloadserere.ts rename test/expected_comparators/latest/{light-controller/src/schema/lightMeasuredPayload.ts => frontend/src/schema/LightMeasuredPayload.ts} (66%) rename test/expected_comparators/latest/{light-controller/src/schema/response.ts => frontend/src/schema/Response.ts} (66%) rename test/expected_comparators/latest/{light-controller/src/schema/turnOnOffPayload.ts => frontend/src/schema/TurnOnOffPayload.ts} (65%) delete mode 100644 test/expected_comparators/latest/frontend/src/schema/anonymous-schema-4.ts delete mode 100644 test/expected_comparators/latest/frontend/src/schema/anonymous-schema-5.ts delete mode 100644 test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts delete mode 100644 test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts delete mode 100644 test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts delete mode 100644 test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts delete mode 100644 test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event.ts create mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdDim.ts create mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts create mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts create mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts delete mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts delete mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts delete mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts delete mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts delete mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event.ts create mode 100644 test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdDim.ts create mode 100644 test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts create mode 100644 test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts create mode 100644 test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10Event.ts create mode 100644 test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/channels/utils.ts create mode 100644 test/expected_comparators/latest/light-controller/src/messages/DimLight.ts rename test/expected_comparators/latest/{frontend/src/messages/dimLightResponse.ts => light-controller/src/messages/DimLightResponse.ts} (54%) rename test/expected_comparators/latest/{frontend/src/messages/lightMeasured.ts => light-controller/src/messages/LightMeasured.ts} (58%) rename test/expected_comparators/latest/light-controller/src/messages/{turnOnOff.ts => TurnOnOff.ts} (57%) rename test/expected_comparators/latest/{frontend/src/messages/turnOnOffResponse.ts => light-controller/src/messages/TurnOnOffResponse.ts} (54%) delete mode 100644 test/expected_comparators/latest/light-controller/src/messages/dimLight.ts create mode 100644 test/expected_comparators/latest/light-controller/src/schema/DimLightPayloadserere.ts rename test/expected_comparators/latest/{frontend/src/schema/lightMeasuredPayload.ts => light-controller/src/schema/LightMeasuredPayload.ts} (66%) rename test/expected_comparators/latest/{frontend/src/schema/response.ts => light-controller/src/schema/Response.ts} (66%) rename test/expected_comparators/latest/{frontend/src/schema/turnOnOffPayload.ts => light-controller/src/schema/TurnOnOffPayload.ts} (65%) delete mode 100644 test/expected_comparators/latest/light-controller/src/schema/anonymous-schema-4.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/schema/anonymous-schema-5.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts create mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdDim.ts create mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts create mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts create mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10Event.ts create mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts diff --git a/scripts/generate_new_actual_comparators.sh b/scripts/generate_new_actual_comparators.sh index 9af3a673e..aa8b125af 100644 --- a/scripts/generate_new_actual_comparators.sh +++ b/scripts/generate_new_actual_comparators.sh @@ -25,12 +25,12 @@ docker run --rm -it \ -v ${currentDir}/test/docs/0.1.0/components:/app/components \ -v ${currentDir}/test/actual_comparators/latest/frontend:/app/output \ -v ${currentDir}:/app/template \ - asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --force-write --install + asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --install --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" docker run --rm -it \ -v ${currentDir}/test/docs/0.1.0/light-controller.yml:/app/asyncapi.yml \ -v ${currentDir}/test/docs/0.1.0/components:/app/components \ -v ${currentDir}/test/actual_comparators/latest/light-controller:/app/output \ -v ${currentDir}:/app/template \ - asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --force-write --install + asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --install --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" diff --git a/scripts/generate_new_expected_comparators.sh b/scripts/generate_new_expected_comparators.sh index 423b7ed4f..6fd145902 100644 --- a/scripts/generate_new_expected_comparators.sh +++ b/scripts/generate_new_expected_comparators.sh @@ -22,12 +22,12 @@ docker run --rm -it \ -v ${currentDir}/test/docs/0.1.0/components:/app/components \ -v ${currentDir}/test/expected_comparators/latest/frontend:/app/output \ -v ${currentDir}:/app/template \ - asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --force-write --install + asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --install --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" docker run --rm -it \ -v ${currentDir}/test/docs/0.1.0/light-controller.yml:/app/asyncapi.yml \ -v ${currentDir}/test/docs/0.1.0/components:/app/components \ -v ${currentDir}/test/expected_comparators/latest/light-controller:/app/output \ -v ${currentDir}:/app/template \ - asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --force-write --install + asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --install --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index 0ce08fd1d..078a4cd89 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -9,19 +9,19 @@ {%- for channelName, channel in asyncapi.channels() %} {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters(), params)}} + {{reply(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters(), params)}} {%- endif %} {%- if channel | isReplier %} - {{request(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters())}} + {{request(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- endif %} {%- if channel | isPubsub %} {%- if channel.hasSubscribe() %} - {{publish(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.description(), channel.parameters())}} + {{publish(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- if channel.hasPublish() %} - {{subscribe(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.description(), channel.parameters())}} + {{subscribe(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- endif %} {%- endfor %} diff --git a/template/src/tests/testclient/index.ts.njk b/template/src/tests/testclient/index.ts.njk index ff0eb84af..41a1e78e0 100644 --- a/template/src/tests/testclient/index.ts.njk +++ b/template/src/tests/testclient/index.ts.njk @@ -8,19 +8,19 @@ {%- for channelName, channel in asyncapi.channels() %} {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{request(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters())}} + {{request(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- if channel | isReplier %} - {{reply(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters(), params)}} + {{reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters(), params)}} {%- endif %} {%- endif %} {%- if channel | isPubsub %} {%- if channel.hasSubscribe() %} - {{subscribe(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.description(), channel.parameters())}} + {{subscribe(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- if channel.hasPublish() %} - {{publish(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.description(), channel.parameters())}} + {{publish(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- endif %} {%- endfor %} diff --git a/test/docs/0.1.0/frontend.yml b/test/docs/0.1.0/frontend.yml index 25d903dcb..ead10b58d 100644 --- a/test/docs/0.1.0/frontend.yml +++ b/test/docs/0.1.0/frontend.yml @@ -1,11 +1,11 @@ asyncapi: '2.0.0' info: - title: Streetlights Nats API for the frontend + title: Streetlights Nats API for lightning controllers version: '1.0.0' description: | The Smartylighting Streetlights API allows you to remotely manage the city lights. - This is for the frontend where the lights can be controlled, which assumed are multiple instances to ensure availability. + This is for the lighting controllers, which assumed are multiple instances to ensure availability. ### Check out its awesome features: @@ -28,93 +28,87 @@ servers: - apiKey: [] defaultContentType: json - channels: - smartylighting/streetlights/1/0/event/*: - description: Topic for which one can subscribe to all measurements regardless of id. - subscribe: - operationId: receiveAllLightMeasurements - message: - $ref: './components/messages.yml#/lightMeasured' - bindings: - $ref: './components/channel-bindings.yml#/smartylightingMeasurement' - smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured: - description: Topic for which one can subscribe to measurements on a specific streetlightId. + description: Any measured values will be published through this method. parameters: streetlightId: $ref: './components/parameters.yml#/streetlightId' - subscribe: - operationId: receiveLightMeasurements + publish: + operationId: publishLightMeasurement message: $ref: './components/messages.yml#/lightMeasured' bindings: $ref: './components/channel-bindings.yml#/smartylightingMeasurement' smartylighting/streetlights/1/0/action/{streetlightId}/turn/on: + description: Get notified when a streetlight should be turned on. This should only be handled by 1 subscriber but ensured by request reply. parameters: streetlightId: $ref: './components/parameters.yml#/streetlightId' publish: - operationId: turnOn - description: The turn on request send to the light controller. - message: - $ref: './components/messages.yml#/turnOnOff' - subscribe: operationId: turnOnResponse - description: The response returned by the light controller. + description: The response returned by us to the frontend. message: $ref: './components/messages.yml#/turnOnOffResponse' + subscribe: + operationId: turnOn + description: The turn on request received from the frontend. + message: + $ref: './components/messages.yml#/turnOnOff' bindings: nats: is: requestReply requestReply: - is: requester + is: replier queue: name: smartylightingTurnOn bindingVersion: '0.1.0' + smartylighting/streetlights/1/0/action/{streetlightId}/turn/off: + description: Get notified when a streetlight should be turned off. This should only be handled by 1 subscriber but ensured by request reply. parameters: streetlightId: $ref: './components/parameters.yml#/streetlightId' - subscribe: + publish: operationId: turnOffResponse - description: The response returned by the light controller. + description: The response returned by us to the frontend. message: $ref: './components/messages.yml#/turnOnOffResponse' - publish: + subscribe: operationId: turnOff - description: The turn off request send to the light controller. + description: The turn off request received from the frontend. message: $ref: './components/messages.yml#/turnOnOff' bindings: nats: is: requestReply requestReply: - is: requester + is: replier queue: name: smartylightingTurnOff bindingVersion: '0.1.0' smartylighting/streetlights/1/0/action/{streetlightId}/dim: + description: Get notified when a streetlight should be dimmed. This should only be handled by 1 subscriber but ensured by request reply. parameters: streetlightId: $ref: './components/parameters.yml#/streetlightId' - subscribe: + publish: operationId: dimLightResponse - description: The response returned by the light controller. + description: The response returned by us. message: $ref: './components/messages.yml#/dimLightResponse' - publish: + subscribe: operationId: dimLight - description: The dim light request send to the light controller. + description: The dim light request received from the frontend. message: $ref: './components/messages.yml#/dimLight' bindings: nats: is: requestReply requestReply: - is: requester + is: replier queue: name: smartylightingDim bindingVersion: '0.1.0' diff --git a/test/docs/0.1.0/light-controller.yml b/test/docs/0.1.0/light-controller.yml index ead10b58d..25d903dcb 100644 --- a/test/docs/0.1.0/light-controller.yml +++ b/test/docs/0.1.0/light-controller.yml @@ -1,11 +1,11 @@ asyncapi: '2.0.0' info: - title: Streetlights Nats API for lightning controllers + title: Streetlights Nats API for the frontend version: '1.0.0' description: | The Smartylighting Streetlights API allows you to remotely manage the city lights. - This is for the lighting controllers, which assumed are multiple instances to ensure availability. + This is for the frontend where the lights can be controlled, which assumed are multiple instances to ensure availability. ### Check out its awesome features: @@ -28,87 +28,93 @@ servers: - apiKey: [] defaultContentType: json + channels: + smartylighting/streetlights/1/0/event/*: + description: Topic for which one can subscribe to all measurements regardless of id. + subscribe: + operationId: receiveAllLightMeasurements + message: + $ref: './components/messages.yml#/lightMeasured' + bindings: + $ref: './components/channel-bindings.yml#/smartylightingMeasurement' + smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured: - description: Any measured values will be published through this method. + description: Topic for which one can subscribe to measurements on a specific streetlightId. parameters: streetlightId: $ref: './components/parameters.yml#/streetlightId' - publish: - operationId: publishLightMeasurement + subscribe: + operationId: receiveLightMeasurements message: $ref: './components/messages.yml#/lightMeasured' bindings: $ref: './components/channel-bindings.yml#/smartylightingMeasurement' smartylighting/streetlights/1/0/action/{streetlightId}/turn/on: - description: Get notified when a streetlight should be turned on. This should only be handled by 1 subscriber but ensured by request reply. parameters: streetlightId: $ref: './components/parameters.yml#/streetlightId' publish: - operationId: turnOnResponse - description: The response returned by us to the frontend. - message: - $ref: './components/messages.yml#/turnOnOffResponse' - subscribe: operationId: turnOn - description: The turn on request received from the frontend. + description: The turn on request send to the light controller. message: $ref: './components/messages.yml#/turnOnOff' + subscribe: + operationId: turnOnResponse + description: The response returned by the light controller. + message: + $ref: './components/messages.yml#/turnOnOffResponse' bindings: nats: is: requestReply requestReply: - is: replier + is: requester queue: name: smartylightingTurnOn bindingVersion: '0.1.0' - smartylighting/streetlights/1/0/action/{streetlightId}/turn/off: - description: Get notified when a streetlight should be turned off. This should only be handled by 1 subscriber but ensured by request reply. parameters: streetlightId: $ref: './components/parameters.yml#/streetlightId' - publish: + subscribe: operationId: turnOffResponse - description: The response returned by us to the frontend. + description: The response returned by the light controller. message: $ref: './components/messages.yml#/turnOnOffResponse' - subscribe: + publish: operationId: turnOff - description: The turn off request received from the frontend. + description: The turn off request send to the light controller. message: $ref: './components/messages.yml#/turnOnOff' bindings: nats: is: requestReply requestReply: - is: replier + is: requester queue: name: smartylightingTurnOff bindingVersion: '0.1.0' smartylighting/streetlights/1/0/action/{streetlightId}/dim: - description: Get notified when a streetlight should be dimmed. This should only be handled by 1 subscriber but ensured by request reply. parameters: streetlightId: $ref: './components/parameters.yml#/streetlightId' - publish: + subscribe: operationId: dimLightResponse - description: The response returned by us. + description: The response returned by the light controller. message: $ref: './components/messages.yml#/dimLightResponse' - subscribe: + publish: operationId: dimLight - description: The dim light request received from the frontend. + description: The dim light request send to the light controller. message: $ref: './components/messages.yml#/dimLight' bindings: nats: is: requestReply requestReply: - is: replier + is: requester queue: name: smartylightingDim bindingVersion: '0.1.0' diff --git a/test/expected_comparators/latest/frontend/README.md b/test/expected_comparators/latest/frontend/README.md index fb373e91a..7d8ed191e 100644 --- a/test/expected_comparators/latest/frontend/README.md +++ b/test/expected_comparators/latest/frontend/README.md @@ -1,8 +1,8 @@ -# Streetlights Nats API for the frontend +# Streetlights Nats API for lightning controllers The Smartylighting Streetlights API allows you to remotely manage the city lights. -This is for the frontend where the lights can be controlled, which assumed are multiple instances to ensure availability. +This is for the lighting controllers, which assumed are multiple instances to ensure availability. ### Check out its awesome features: diff --git a/test/expected_comparators/latest/frontend/package.json b/test/expected_comparators/latest/frontend/package.json index dfe709a71..3ffa6ee54 100644 --- a/test/expected_comparators/latest/frontend/package.json +++ b/test/expected_comparators/latest/frontend/package.json @@ -2,38 +2,35 @@ - "name": "streetlights-nats-api-for-the-frontend", - "description": "The Smartylighting Streetlights API allows you to remotely manage the city lights. This is for the frontend where the lights can be controlled, which assumed are multiple instances to ensure availability. ### Check out its awesome features: * Turn a specific streetlight on/off 🌃 * Dim a specific streetlight 😎 * Receive real-time information about environmental lighting conditions 📈 ", + "name": "streetlights-nats-api-for-lightning-controllers", + "description": "The Smartylighting Streetlights API allows you to remotely manage the city lights. This is for the lighting controllers, which assumed are multiple instances to ensure availability. ### Check out its awesome features: * Turn a specific streetlight on/off 🌃 * Dim a specific streetlight 😎 * Receive real-time information about environmental lighting conditions 📈 ", "version": "1.0.0", "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { "watch": "tsc --watch", - "build": "tsc", + "build": "tsc && npm run dopostinstall", "start": "node src/api/index.js", - "postinstall": "link-module-alias", - "test": "mocha -r ts-node/register tests/\*\*/\*.spec.ts" + "dopostinstall": "link-module-alias", + "test": "mocha -r ts-node/register tests/**/*.spec.ts" }, "_moduleAliasIgnoreWarning": true, "_moduleAliases": { - "#messages": "./src/messages", - "#schemas": "./src/schema", - "#channels": "./src/channels", - "#hooks": "./src/hooks" + "#messages": "dist/messages/", + "#schemas": "dist/schema/", + "#channels": "dist/channels/", + "#testchannels": "dist/tests/testclient/testchannels/", + "#hooks": "dist/hooks.js", + "#testclient": "dist/tests/testclient/index.js" }, "dependencies": { "@types/klaw-sync": "^6.0.0", - "@types/uuid": "3.4.5", "@types/node": "13.9.5", "klaw-sync": "6.0.0", "link-module-alias": "^1.2.0", - "msgpack-lite": "^0.1.26", "ts-nats": "1.2.4", - "node-yaml-config": "0.0.5", "typescript": "3.4.3", - "uuid": "3.3.3", - "winston": "3.2.1", - "winston-daily-rotate-file": "3.10.0" + "ts-nkeys":"1.0.16" }, "devDependencies": { "@types/chai": "^4.2.11", diff --git a/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdDim.ts b/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdDim.ts new file mode 100644 index 000000000..cde192c51 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdDim.ts @@ -0,0 +1,70 @@ + +import {default as DimLightResponseMessage} from '#messages/DimLightResponse' +import {default as DimLightMessage} from '#messages/DimLight' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + +export function reply( + onRequest: (err?: NatsError, msg?: DimLightMessage, streetlightId?: string) =>Promise, + onReplyError: (err: NatsError) => void, + nc: Client, + + streetlightId: string + + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(`smartylighting.streetlights.1.0.action.${streetlightId}.dim`,async (err, msg) => { + if (err) { + onRequest(err); + } else { + const unmodifiedChannel = `smartylighting.streetlights.1.0.action.{streetlightId}.dim` + const receivedTopicParameters = { + streetlightId : msg.subject.slice(unmodifiedChannel.split("${streetlightId}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlightId}")[1].length) + } + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived : any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + let requestData = DimLightMessage.toMessage(processedDataReceived); + let responseObject =await onRequest(undefined, requestData, + receivedTopicParameters['streetlightId']); + if (msg.reply) { + try { + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToPublish : any = responseObject; + for(let hook of publishDataHooks){ + dataToPublish = hook(dataToPublish); + } + nc.publish(msg.reply, dataToPublish); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts b/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts new file mode 100644 index 000000000..e501516eb --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts @@ -0,0 +1,70 @@ + +import {default as TurnOnOffResponseMessage} from '#messages/TurnOnOffResponse' +import {default as TurnOnOffMessage} from '#messages/TurnOnOff' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + +export function reply( + onRequest: (err?: NatsError, msg?: TurnOnOffMessage, streetlightId?: string) =>Promise, + onReplyError: (err: NatsError) => void, + nc: Client, + + streetlightId: string + + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(`smartylighting.streetlights.1.0.action.${streetlightId}.turn.off`,async (err, msg) => { + if (err) { + onRequest(err); + } else { + const unmodifiedChannel = `smartylighting.streetlights.1.0.action.{streetlightId}.turn.off` + const receivedTopicParameters = { + streetlightId : msg.subject.slice(unmodifiedChannel.split("${streetlightId}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlightId}")[1].length) + } + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived : any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + let requestData = TurnOnOffMessage.toMessage(processedDataReceived); + let responseObject =await onRequest(undefined, requestData, + receivedTopicParameters['streetlightId']); + if (msg.reply) { + try { + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToPublish : any = responseObject; + for(let hook of publishDataHooks){ + dataToPublish = hook(dataToPublish); + } + nc.publish(msg.reply, dataToPublish); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts b/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts new file mode 100644 index 000000000..236e7c7c9 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts @@ -0,0 +1,70 @@ + +import {default as TurnOnOffResponseMessage} from '#messages/TurnOnOffResponse' +import {default as TurnOnOffMessage} from '#messages/TurnOnOff' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + +export function reply( + onRequest: (err?: NatsError, msg?: TurnOnOffMessage, streetlightId?: string) =>Promise, + onReplyError: (err: NatsError) => void, + nc: Client, + + streetlightId: string + + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(`smartylighting.streetlights.1.0.action.${streetlightId}.turn.on`,async (err, msg) => { + if (err) { + onRequest(err); + } else { + const unmodifiedChannel = `smartylighting.streetlights.1.0.action.{streetlightId}.turn.on` + const receivedTopicParameters = { + streetlightId : msg.subject.slice(unmodifiedChannel.split("${streetlightId}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlightId}")[1].length) + } + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived : any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + let requestData = TurnOnOffMessage.toMessage(processedDataReceived); + let responseObject =await onRequest(undefined, requestData, + receivedTopicParameters['streetlightId']); + if (msg.reply) { + try { + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToPublish : any = responseObject; + for(let hook of publishDataHooks){ + dataToPublish = hook(dataToPublish); + } + nc.publish(msg.reply, dataToPublish); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts b/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts new file mode 100644 index 000000000..f22b47c33 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts @@ -0,0 +1,32 @@ + +import {default as LightMeasuredMessage} from '#messages/LightMeasured' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + + +export function publish( + requestMessage: LightMeasuredMessage, + nc: Client, + + streetlightId: string + + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToPublish : any = requestMessage; + for(let hook of publishDataHooks){ + dataToPublish = hook(dataToPublish); + } + nc.publish(`smartylighting.streetlights.1.0.event.${streetlightId}.lighting.measured`, dataToPublish); + resolve(); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }); +}; + diff --git a/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts deleted file mode 100644 index 1361c0da6..000000000 --- a/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts +++ /dev/null @@ -1,46 +0,0 @@ - -import {default as DimLightMessage} from '../messages/DimLight' -import {default as DimLightResponseMessage} from '../messages/DimLightResponse' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - -export function request( - requestMessage: DimLightMessage, - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - resolve(DimLightResponseMessage.toMessage(processedData)); - } - }, { max: 1 }); - let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var requestData; - for(let hook in publishDataHooks){ - requestData = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/dim', { - - "streetlightId": streetlightId - - }), requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts deleted file mode 100644 index 4f3a2dd9d..000000000 --- a/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts +++ /dev/null @@ -1,46 +0,0 @@ - -import {default as TurnOnOffMessage} from '../messages/TurnOnOff' -import {default as TurnOnOffResponseMessage} from '../messages/TurnOnOffResponse' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - -export function request( - requestMessage: TurnOnOffMessage, - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - resolve(TurnOnOffResponseMessage.toMessage(processedData)); - } - }, { max: 1 }); - let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var requestData; - for(let hook in publishDataHooks){ - requestData = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/off', { - - "streetlightId": streetlightId - - }), requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts deleted file mode 100644 index 4ca6a3341..000000000 --- a/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts +++ /dev/null @@ -1,46 +0,0 @@ - -import {default as TurnOnOffMessage} from '../messages/TurnOnOff' -import {default as TurnOnOffResponseMessage} from '../messages/TurnOnOffResponse' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - -export function request( - requestMessage: TurnOnOffMessage, - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - resolve(TurnOnOffResponseMessage.toMessage(processedData)); - } - }, { max: 1 }); - let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var requestData; - for(let hook in publishDataHooks){ - requestData = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/on', { - - "streetlightId": streetlightId - - }), requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts deleted file mode 100644 index 81100c80c..000000000 --- a/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts +++ /dev/null @@ -1,44 +0,0 @@ - -import {default as LightMeasuredMessage} from '../messages/LightMeasured' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - - -import {getHooks, AvailableHooks} from '#hooks'; -export function subscribe( - onDataCallback : (err?: NatsError, msg?: lightMeasured) => void, - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured', { - - "streetlightId": streetlightId - - }), (err, msg) => { - if(err){ - onDataCallback(err); - }else{ - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let publishedData = new lightMeasured(); - publishedData.copyFrom(processedData); - onDataCallback(undefined, publishedData); - } - }, subscribeOptions); - resolve(subscription); - }catch(e){ - reject(e); - } - }else{ - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event.ts b/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event.ts deleted file mode 100644 index 89313c1f9..000000000 --- a/test/expected_comparators/latest/frontend/src/channels/smartylighting-streetlights-1-0-event.ts +++ /dev/null @@ -1,40 +0,0 @@ - -import {default as LightMeasuredMessage} from '../messages/LightMeasured' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - - -import {getHooks, AvailableHooks} from '#hooks'; -export function subscribe( - onDataCallback : (err?: NatsError, msg?: lightMeasured) => void, - - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/event/*', { - - }), (err, msg) => { - if(err){ - onDataCallback(err); - }else{ - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let publishedData = new lightMeasured(); - publishedData.copyFrom(processedData); - onDataCallback(undefined, publishedData); - } - }, subscribeOptions); - resolve(subscription); - }catch(e){ - reject(e); - } - }else{ - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/frontend/src/channels/utils.ts b/test/expected_comparators/latest/frontend/src/channels/utils.ts deleted file mode 100644 index 8810b700d..000000000 --- a/test/expected_comparators/latest/frontend/src/channels/utils.ts +++ /dev/null @@ -1,11 +0,0 @@ -export function realizeChannelName(channelName: string, parameters: any) { - let returnString = channelName; - returnString = returnString.replace('/', '.'); - for (let parameterName in parameters) { - returnString = returnString.replace( - `{${parameterName}}`, - parameters[parameterName] - ); - } - return returnString; -} diff --git a/test/expected_comparators/latest/frontend/src/hooks.ts b/test/expected_comparators/latest/frontend/src/hooks.ts index 7dfcbfbd9..51e71a158 100644 --- a/test/expected_comparators/latest/frontend/src/hooks.ts +++ b/test/expected_comparators/latest/frontend/src/hooks.ts @@ -1,4 +1,3 @@ -const HOOKS_DIRNAME = './hooks'; import * as fs from 'fs'; import * as path from 'path'; import * as walkSync from 'klaw-sync'; @@ -6,58 +5,56 @@ export enum AvailableHooks { RecievedData = 'RecievedData', BeforeSendingData = 'BeforeSendingData' } -export type RecievedDataHook = () => void; -export type BeforeSendingDataHook = (messageToSend: any) => void; -export var hooks: { - BeforeSendingData: BeforeSendingDataHook[]; - RecievedData: RecievedDataHook[]; -}; - -/** - * Loads the custom hooks. - */ -try { - const hooksPath = path.resolve(HOOKS_DIRNAME); - if (fs.existsSync(hooksPath)) { - const files = walkSync(hooksPath, { nodir: true }); - files.forEach((file: any) => { - require(file.path)((when: AvailableHooks, hook: any) => { - hooks[when].push(hook); - }); - }); +export type RecievedDataHook = (receivedData: any) => string; +export type BeforeSendingDataHook = (messageToSend: any) => string; +export class Hooks { + private static instance: Hooks; + + private hooks: { + BeforeSendingData: BeforeSendingDataHook[]; + RecievedData: RecievedDataHook[]; + }; + private constructor() { + this.hooks = { + BeforeSendingData: [], + RecievedData: [] + } + } + public static getInstance(): Hooks { + if (!Hooks.instance) { + Hooks.instance = new Hooks(); + } + return Hooks.instance; } -} catch (e) { - e.message = `There was a problem registering the hooks: ${e.message}`; - throw e; -} - -/** - * Register a hook for BeforeSendingData - * @param hook - */ -export async function registerBeforeSendingData(hook: BeforeSendingDataHook) { - hooks[AvailableHooks.BeforeSendingData] - ? hooks[AvailableHooks.BeforeSendingData].push(hook) - : [hook]; -} - -/** - * Register a hook for BeforeSendingData - * @param hook - */ -export async function registerRecievedData(hook: RecievedDataHook) { - hooks[AvailableHooks.RecievedData] - ? hooks[AvailableHooks.RecievedData].push(hook) - : [hook]; -} -/** - * Get all the hooks registered at a given hook point/name. - * @param hook to find hooks for - * @returns all hooks - */ -export function getHooks(hook: AvailableHooks): Function[] { - if (!Array.isArray(hooks[hook])) return []; - // Return valid hooks - return hooks[hook]; -} + + + /** + * Register a hook for BeforeSendingData + * @param hook + */ + public async registerBeforeSendingData(hook: BeforeSendingDataHook) { + this.hooks[AvailableHooks.BeforeSendingData] + ? this.hooks[AvailableHooks.BeforeSendingData].push(hook) + : [hook]; + } + + /** + * Register a hook for BeforeSendingData + * @param hook + */ + public async registerRecievedData(hook: RecievedDataHook) { + this.hooks[AvailableHooks.RecievedData] + ? this.hooks[AvailableHooks.RecievedData].push(hook) + : [hook]; + } + + + public getRecievedDataHook(): RecievedDataHook[] { + return this.hooks[AvailableHooks.RecievedData]; + } + + public getBeforeSendingDataHook(): BeforeSendingDataHook[] { + return this.hooks[AvailableHooks.BeforeSendingData]; + } +} \ No newline at end of file diff --git a/test/expected_comparators/latest/frontend/src/index.ts b/test/expected_comparators/latest/frontend/src/index.ts index 8573d5b42..4e24e6775 100644 --- a/test/expected_comparators/latest/frontend/src/index.ts +++ b/test/expected_comparators/latest/frontend/src/index.ts @@ -1,44 +1,152 @@ - -import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; -import * as smartylightingStreetlights10EventChannel from "./channels/Smartylighting/streetlights/1/0/event/*"; -import * as smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel from "./channels/Smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured"; -import * as smartylightingStreetlights10ActionStreetlightIdTurnOnChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/turn/on"; -import * as smartylightingStreetlights10ActionStreetlightIdTurnOffChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/turn/off"; -import * as smartylightingStreetlights10ActionStreetlightIdDimChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/dim"; -import {default as LightMeasuredMessage} from "./messages/LightMeasured"; -import {default as TurnOnOffMessage} from "./messages/TurnOnOff"; -import {default as TurnOnOffResponseMessage} from "./messages/TurnOnOffResponse"; -import {default as DimLightMessage} from "./messages/DimLight"; -import {default as DimLightResponseMessage} from "./messages/DimLightResponse"; - -export default class NatsAsyncApiClient { + +import { + Client, + NatsConnectionOptions, + connect, + Payload, + NatsError, + Subscription, + ServersChangedEvent, + SubEvent, + ServerInfo + } from 'ts-nats'; +import * as smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel from "#testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured"; +import * as smartylightingStreetlights10ActionStreetlightIdTurnOnChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn"; +import * as smartylightingStreetlights10ActionStreetlightIdTurnOffChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff"; +import * as smartylightingStreetlights10ActionStreetlightIdDimChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdDim"; +import {default as LightMeasuredMessage} from "#messages/LightMeasured"; +import {default as TurnOnOffResponseMessage} from "#messages/TurnOnOffResponse"; +import {default as TurnOnOffMessage} from "#messages/TurnOnOff"; +import {default as DimLightResponseMessage} from "#messages/DimLightResponse"; +import {default as DimLightMessage} from "#messages/DimLight"; +import {fromSeed} from 'ts-nkeys'; +import * as events from 'events'; +export enum AvailableEvents { + connectionError = 'connectionError', + permissionError = 'permissionError', + close = 'close', + connect = 'connect', + connecting = 'connecting', + disconnect = 'disconnect', + error = 'error', + pingcount = 'pingcount', + pingtimer = 'pingtimer', + reconnect = 'reconnect', + reconnecting = 'reconnecting', + serversChanged = 'serversChanged', + subscribe = 'subscribe', + unsubscribe = 'unsubscribe', + yield = 'yield' +} +export declare interface NatsAsyncApiTestClient { + on(event: AvailableEvents.connectionError, listener: (error: any) => void): this; + on(event: AvailableEvents.permissionError, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.close, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; + on(event: AvailableEvents.connecting, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.error, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.pingcount, listener: () => void): this; + on(event: AvailableEvents.pingtimer, listener: () => void): this; + on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; + on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; + on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.yield, listener: () => void): this; +} +export class NatsAsyncApiTestClient extends events.EventEmitter{ public jsonClient?: Client; public stringClient?: Client; public binaryClient?: Client; - public options: NatsConnectionOptions; + public options?: NatsConnectionOptions; /** * * @param options options to use, payload is omitted if sat in the AsyncAPI document. */ - constructor(options : NatsConnectionOptions) { - this.options = this.setDefaultOptions(options); - this.connect(); + constructor() { + super(); } /** * Try to connect to the NATS server with the different payloads. */ - private async connect(){ + async connect(options : NatsConnectionOptions){ + this.options = this.setDefaultOptions(options); try{ this.options.payload = Payload.JSON; this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); }catch(e){ - console.error("Could not connect to NATS: " + e) + this.emit(AvailableEvents.connectionError, e) } } + + /** + * Disconnect all clients from the server + */ + async disconnect(){ + this.jsonClient!.close() + } + + private chainEvents(ns: Client){ + ns.on('permissionError', (e: NatsError) => { + this.emit(AvailableEvents.permissionError, e) + }); + ns.on('close', (e: NatsError) => { + this.emit(AvailableEvents.close, e) + }); + ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.connect, connection, serverURL, info) + }); + ns.on('connecting', (serverURL: NatsError) => { + this.emit(AvailableEvents.connecting, serverURL) + }); + ns.on('disconnect', (serverURL: string) => { + this.emit(AvailableEvents.disconnect, serverURL) + }); + ns.on('error', (e: NatsError) => { + this.emit(AvailableEvents.error, e) + }); + ns.on('pingcount', () => { + this.emit(AvailableEvents.pingcount) + }); + ns.on('pingtimer', () => { + this.emit(AvailableEvents.pingtimer) + }); + ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.reconnect, connection, serverURL, info) + }); + ns.on('reconnecting', (serverURL: string) => { + this.emit(AvailableEvents.reconnecting, serverURL) + }); + ns.on('serversChanged', (e: ServersChangedEvent) => { + this.emit(AvailableEvents.serversChanged, e) + }); + ns.on('subscribe', (e: SubEvent) => { + this.emit(AvailableEvents.subscribe, e) + }); + ns.on('unsubscribe', (e: SubEvent) => { + this.emit(AvailableEvents.unsubscribe, e) + }); + ns.on('yield', () => { + this.emit(AvailableEvents.yield) + }); + } + /** + * Try to connect to the NATS server with nkey authentication + */ + async connectWithNkey(options : NatsConnectionOptions, publicNkey: string, seed: string){ + options.nkey = publicNkey; + options.nonceSigner = (nonce: string): Buffer => { + const sk = fromSeed(Buffer.from(seed)); + return sk.sign(Buffer.from(nonce)); + } + await this.connect(options); + } /** * Set the default options based on the AsyncAPI file. * @param options to set @@ -48,54 +156,85 @@ export default class NatsAsyncApiClient { options.encoding = 'utf8'; return options; } - - /** - * Topic for which one can subscribe to all measurements regardless of id. - * @param onDataCallback Called when message recieved. - */ - public subscribeToSmartylightingStreetlights10Event(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage) => void): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10EventChannel.subscribe(onDataCallback, nc); - } - + + /** - * Topic for which one can subscribe to measurements on a specific streetlightId. + * Any measured values will be published through this method. * @param onDataCallback Called when message recieved. */ - public subscribeToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage) => void): Promise { + public subscribeToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage, streetlightId?: string) => void + ,streetlightId: string + ): Promise { const nc: Client = this.jsonClient!; - return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.subscribe(onDataCallback, nc); + if(nc){ + return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.subscribe(onDataCallback, nc + + ,streetlightId + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10EventStreetlightIdLightingMeasured')) + } } - + /** - * + * Get notified when a streetlight should be turned on. This should only be handled by 1 subscriber but ensured by request reply. * @param requestMessage The request message to send. */ - public requestSmartylightingStreetlights10ActionStreetlightIdTurnOn(requestMessage: TurnOnOffMessage): Promise { + public requestSmartylightingStreetlights10ActionStreetlightIdTurnOn(requestMessage: TurnOnOffMessage + + ,streetlightId: string + ): Promise { const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.request(requestMessage, nc); + if(nc){ + return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.request(requestMessage, nc + + ,streetlightId + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdTurnOn')) + } } - + /** - * + * Get notified when a streetlight should be turned off. This should only be handled by 1 subscriber but ensured by request reply. * @param requestMessage The request message to send. */ - public requestSmartylightingStreetlights10ActionStreetlightIdTurnOff(requestMessage: TurnOnOffMessage): Promise { + public requestSmartylightingStreetlights10ActionStreetlightIdTurnOff(requestMessage: TurnOnOffMessage + + ,streetlightId: string + ): Promise { const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.request(requestMessage, nc); + if(nc){ + return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.request(requestMessage, nc + + ,streetlightId + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdTurnOff')) + } } - + /** - * + * Get notified when a streetlight should be dimmed. This should only be handled by 1 subscriber but ensured by request reply. * @param requestMessage The request message to send. */ - public requestSmartylightingStreetlights10ActionStreetlightIdDim(requestMessage: DimLightMessage): Promise { + public requestSmartylightingStreetlights10ActionStreetlightIdDim(requestMessage: DimLightMessage + + ,streetlightId: string + ): Promise { const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdDimChannel.request(requestMessage, nc); + if(nc){ + return smartylightingStreetlights10ActionStreetlightIdDimChannel.request(requestMessage, nc + + ,streetlightId + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdDim')) + } } } diff --git a/test/expected_comparators/latest/frontend/src/messages/DimLight.ts b/test/expected_comparators/latest/frontend/src/messages/DimLight.ts new file mode 100644 index 000000000..019165814 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/messages/DimLight.ts @@ -0,0 +1,29 @@ + +import { default as DimLightPayloadserereSchema } from '#schemas/DimLightPayloadserere'; +import { default as ResponseSchema } from '#schemas/Response'; +export default class DimLight { + + + + dimLightPayloadserere:DimLightPayloadserereSchema; + + + + response:ResponseSchema; + + + constructor( + + ){ + + } + + /** + * Parses a JSON string to an object of DimLight message class. + * @param json any to be parsed as DimLight. + */ + public static toMessage(json: any): DimLight { + return JSON.parse(JSON.stringify(json)); + } + +} diff --git a/test/expected_comparators/latest/light-controller/src/messages/dimLightResponse.ts b/test/expected_comparators/latest/frontend/src/messages/DimLightResponse.ts similarity index 54% rename from test/expected_comparators/latest/light-controller/src/messages/dimLightResponse.ts rename to test/expected_comparators/latest/frontend/src/messages/DimLightResponse.ts index 2e0d9da0e..a9733f541 100644 --- a/test/expected_comparators/latest/light-controller/src/messages/dimLightResponse.ts +++ b/test/expected_comparators/latest/frontend/src/messages/DimLightResponse.ts @@ -1,9 +1,5 @@ - - -import { default as ResponseSchema } from '../schema/Response'; - - +import { default as ResponseSchema } from '#schemas/Response'; export default class DimLightResponse { @@ -21,10 +17,10 @@ export default class DimLightResponse { /** * Parses a JSON string to an object of DimLightResponse message class. - * @param json string to be parsed as DimLightResponse. + * @param json any to be parsed as DimLightResponse. */ - public static toMessage(json: string): DimLightResponse { - return JSON.parse(json); + public static toMessage(json: any): DimLightResponse { + return JSON.parse(JSON.stringify(json)); } } diff --git a/test/expected_comparators/latest/light-controller/src/messages/lightMeasured.ts b/test/expected_comparators/latest/frontend/src/messages/LightMeasured.ts similarity index 58% rename from test/expected_comparators/latest/light-controller/src/messages/lightMeasured.ts rename to test/expected_comparators/latest/frontend/src/messages/LightMeasured.ts index 9e2010e22..39931197c 100644 --- a/test/expected_comparators/latest/light-controller/src/messages/lightMeasured.ts +++ b/test/expected_comparators/latest/frontend/src/messages/LightMeasured.ts @@ -1,9 +1,5 @@ - - -import { default as LightMeasuredPayloadSchema } from '../schema/LightMeasuredPayload'; - - +import { default as LightMeasuredPayloadSchema } from '#schemas/LightMeasuredPayload'; export default class LightMeasured { @@ -21,10 +17,10 @@ export default class LightMeasured { /** * Parses a JSON string to an object of LightMeasured message class. - * @param json string to be parsed as LightMeasured. + * @param json any to be parsed as LightMeasured. */ - public static toMessage(json: string): LightMeasured { - return JSON.parse(json); + public static toMessage(json: any): LightMeasured { + return JSON.parse(JSON.stringify(json)); } } diff --git a/test/expected_comparators/latest/frontend/src/messages/turnOnOff.ts b/test/expected_comparators/latest/frontend/src/messages/TurnOnOff.ts similarity index 57% rename from test/expected_comparators/latest/frontend/src/messages/turnOnOff.ts rename to test/expected_comparators/latest/frontend/src/messages/TurnOnOff.ts index 483922274..5d990599a 100644 --- a/test/expected_comparators/latest/frontend/src/messages/turnOnOff.ts +++ b/test/expected_comparators/latest/frontend/src/messages/TurnOnOff.ts @@ -1,9 +1,5 @@ - - -import { default as TurnOnOffPayloadSchema } from '../schema/TurnOnOffPayload'; - - +import { default as TurnOnOffPayloadSchema } from '#schemas/TurnOnOffPayload'; export default class TurnOnOff { @@ -21,10 +17,10 @@ export default class TurnOnOff { /** * Parses a JSON string to an object of TurnOnOff message class. - * @param json string to be parsed as TurnOnOff. + * @param json any to be parsed as TurnOnOff. */ - public static toMessage(json: string): TurnOnOff { - return JSON.parse(json); + public static toMessage(json: any): TurnOnOff { + return JSON.parse(JSON.stringify(json)); } } diff --git a/test/expected_comparators/latest/light-controller/src/messages/turnOnOffResponse.ts b/test/expected_comparators/latest/frontend/src/messages/TurnOnOffResponse.ts similarity index 54% rename from test/expected_comparators/latest/light-controller/src/messages/turnOnOffResponse.ts rename to test/expected_comparators/latest/frontend/src/messages/TurnOnOffResponse.ts index c25f1a5c5..ba0b02f5e 100644 --- a/test/expected_comparators/latest/light-controller/src/messages/turnOnOffResponse.ts +++ b/test/expected_comparators/latest/frontend/src/messages/TurnOnOffResponse.ts @@ -1,9 +1,5 @@ - - -import { default as ResponseSchema } from '../schema/Response'; - - +import { default as ResponseSchema } from '#schemas/Response'; export default class TurnOnOffResponse { @@ -21,10 +17,10 @@ export default class TurnOnOffResponse { /** * Parses a JSON string to an object of TurnOnOffResponse message class. - * @param json string to be parsed as TurnOnOffResponse. + * @param json any to be parsed as TurnOnOffResponse. */ - public static toMessage(json: string): TurnOnOffResponse { - return JSON.parse(json); + public static toMessage(json: any): TurnOnOffResponse { + return JSON.parse(JSON.stringify(json)); } } diff --git a/test/expected_comparators/latest/frontend/src/messages/dimLight.ts b/test/expected_comparators/latest/frontend/src/messages/dimLight.ts deleted file mode 100644 index 7a8281027..000000000 --- a/test/expected_comparators/latest/frontend/src/messages/dimLight.ts +++ /dev/null @@ -1,45 +0,0 @@ - - - - -import { default as DimLightPayloadserereSchema } from '../schema/DimLightPayloadserere'; - - - -import { default as ResponseSchema } from '../schema/Response'; - - -export default class DimLight { - - - - dimLightPayloadserere:DimLightPayloadserereSchema; - - - - response:ResponseSchema; - - - constructor( - dimLightPayloadserere: DimLightPayloadserereSchema,response: ResponseSchema - ){ - - - - this.dimLightPayloadserere = dimLightPayloadserere; - - - - this.response = response; - - } - - /** - * Parses a JSON string to an object of DimLight message class. - * @param json string to be parsed as DimLight. - */ - public static toMessage(json: string): DimLight { - return JSON.parse(json); - } - -} diff --git a/test/expected_comparators/latest/frontend/src/schema/DimLightPayloadserere.ts b/test/expected_comparators/latest/frontend/src/schema/DimLightPayloadserere.ts new file mode 100644 index 000000000..279439192 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/schema/DimLightPayloadserere.ts @@ -0,0 +1,19 @@ + + + +export default class dimLightPayloadserere { + + + percentage?: Number + sentAt?: string + + + + constructor( + + ){ + + + + } +} diff --git a/test/expected_comparators/latest/light-controller/src/schema/lightMeasuredPayload.ts b/test/expected_comparators/latest/frontend/src/schema/LightMeasuredPayload.ts similarity index 66% rename from test/expected_comparators/latest/light-controller/src/schema/lightMeasuredPayload.ts rename to test/expected_comparators/latest/frontend/src/schema/LightMeasuredPayload.ts index a783f2728..e090e2247 100644 --- a/test/expected_comparators/latest/light-controller/src/schema/lightMeasuredPayload.ts +++ b/test/expected_comparators/latest/frontend/src/schema/LightMeasuredPayload.ts @@ -1,7 +1,6 @@ - export default class lightMeasuredPayload { @@ -10,4 +9,11 @@ export default class lightMeasuredPayload { + constructor( + + ){ + + + + } } diff --git a/test/expected_comparators/latest/light-controller/src/schema/response.ts b/test/expected_comparators/latest/frontend/src/schema/Response.ts similarity index 66% rename from test/expected_comparators/latest/light-controller/src/schema/response.ts rename to test/expected_comparators/latest/frontend/src/schema/Response.ts index 0c80740f4..afc8c5d71 100644 --- a/test/expected_comparators/latest/light-controller/src/schema/response.ts +++ b/test/expected_comparators/latest/frontend/src/schema/Response.ts @@ -1,7 +1,6 @@ - export default class response { @@ -11,4 +10,12 @@ export default class response { + constructor( + + ){ + + + + + } } diff --git a/test/expected_comparators/latest/light-controller/src/schema/turnOnOffPayload.ts b/test/expected_comparators/latest/frontend/src/schema/TurnOnOffPayload.ts similarity index 65% rename from test/expected_comparators/latest/light-controller/src/schema/turnOnOffPayload.ts rename to test/expected_comparators/latest/frontend/src/schema/TurnOnOffPayload.ts index c9ea846aa..f35e771e2 100644 --- a/test/expected_comparators/latest/light-controller/src/schema/turnOnOffPayload.ts +++ b/test/expected_comparators/latest/frontend/src/schema/TurnOnOffPayload.ts @@ -1,7 +1,6 @@ - export default class turnOnOffPayload { @@ -10,4 +9,11 @@ export default class turnOnOffPayload { + constructor( + + ){ + + + + } } diff --git a/test/expected_comparators/latest/frontend/src/schema/anonymous-schema-4.ts b/test/expected_comparators/latest/frontend/src/schema/anonymous-schema-4.ts deleted file mode 100644 index ef2cd616f..000000000 --- a/test/expected_comparators/latest/frontend/src/schema/anonymous-schema-4.ts +++ /dev/null @@ -1,11 +0,0 @@ - - - - -export default class anonymousSchema4 { - - - - - -} diff --git a/test/expected_comparators/latest/frontend/src/schema/anonymous-schema-5.ts b/test/expected_comparators/latest/frontend/src/schema/anonymous-schema-5.ts deleted file mode 100644 index e11ccc78d..000000000 --- a/test/expected_comparators/latest/frontend/src/schema/anonymous-schema-5.ts +++ /dev/null @@ -1,22 +0,0 @@ - - - - -export default class anonymousSchema5 { - - - - percentage?: Number - sentAt?: string - - - - status?: Number - statusMessage?: string - sentAt?: string - - - - - -} diff --git a/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event.ts b/test/expected_comparators/latest/frontend/src/tests/smartylighting-streetlights-1-0-event.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/index.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/index.ts index ecde61413..08d2dd055 100644 --- a/test/expected_comparators/latest/frontend/src/tests/testclient/index.ts +++ b/test/expected_comparators/latest/frontend/src/tests/testclient/index.ts @@ -1,54 +1,247 @@ - + +import { + Client, + NatsConnectionOptions, + connect, + Payload, + NatsError, + Subscription, + ServersChangedEvent, + SubEvent, + ServerInfo + } from 'ts-nats'; +import * as smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel from "#testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured"; +import * as smartylightingStreetlights10ActionStreetlightIdTurnOnChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn"; +import * as smartylightingStreetlights10ActionStreetlightIdTurnOffChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff"; +import * as smartylightingStreetlights10ActionStreetlightIdDimChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdDim"; +import {default as LightMeasuredMessage} from "#messages/LightMeasured"; +import {default as TurnOnOffResponseMessage} from "#messages/TurnOnOffResponse"; +import {default as TurnOnOffMessage} from "#messages/TurnOnOff"; +import {default as DimLightResponseMessage} from "#messages/DimLightResponse"; +import {default as DimLightMessage} from "#messages/DimLight"; +import {fromSeed} from 'ts-nkeys'; +import * as events from 'events'; +export enum AvailableEvents { + connectionError = 'connectionError', + permissionError = 'permissionError', + close = 'close', + connect = 'connect', + connecting = 'connecting', + disconnect = 'disconnect', + error = 'error', + pingcount = 'pingcount', + pingtimer = 'pingtimer', + reconnect = 'reconnect', + reconnecting = 'reconnecting', + serversChanged = 'serversChanged', + subscribe = 'subscribe', + unsubscribe = 'unsubscribe', + yield = 'yield' +} +export declare interface NatsAsyncApiTestClient { + on(event: AvailableEvents.connectionError, listener: (error: any) => void): this; + on(event: AvailableEvents.permissionError, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.close, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; + on(event: AvailableEvents.connecting, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.error, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.pingcount, listener: () => void): this; + on(event: AvailableEvents.pingtimer, listener: () => void): this; + on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; + on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; + on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.yield, listener: () => void): this; +} +export class NatsAsyncApiTestClient extends events.EventEmitter{ + public jsonClient?: Client; + public stringClient?: Client; + public binaryClient?: Client; + public options?: NatsConnectionOptions; + + /** + * + * @param options options to use, payload is omitted if sat in the AsyncAPI document. + */ + constructor() { + super(); + } + /** - * [object Object] - * @param requestMessage The message to publish. - */ - public publishToSmartylightingStreetlights10Event(requestMessage: LightMeasuredMessage): Promise { - const nc: Client = this.jsonClient!; - return smartylightingStreetlights10EventChannel.publish(requestMessage, nc); + * Try to connect to the NATS server with the different payloads. + */ + async connect(options : NatsConnectionOptions){ + this.options = this.setDefaultOptions(options); + try{ + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); + }catch(e){ + this.emit(AvailableEvents.connectionError, e) + } } - + + /** + * Disconnect all clients from the server + */ + async disconnect(){ + this.jsonClient!.close() + } + + private chainEvents(ns: Client){ + ns.on('permissionError', (e: NatsError) => { + this.emit(AvailableEvents.permissionError, e) + }); + ns.on('close', (e: NatsError) => { + this.emit(AvailableEvents.close, e) + }); + ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.connect, connection, serverURL, info) + }); + ns.on('connecting', (serverURL: NatsError) => { + this.emit(AvailableEvents.connecting, serverURL) + }); + ns.on('disconnect', (serverURL: string) => { + this.emit(AvailableEvents.disconnect, serverURL) + }); + ns.on('error', (e: NatsError) => { + this.emit(AvailableEvents.error, e) + }); + ns.on('pingcount', () => { + this.emit(AvailableEvents.pingcount) + }); + ns.on('pingtimer', () => { + this.emit(AvailableEvents.pingtimer) + }); + ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.reconnect, connection, serverURL, info) + }); + ns.on('reconnecting', (serverURL: string) => { + this.emit(AvailableEvents.reconnecting, serverURL) + }); + ns.on('serversChanged', (e: ServersChangedEvent) => { + this.emit(AvailableEvents.serversChanged, e) + }); + ns.on('subscribe', (e: SubEvent) => { + this.emit(AvailableEvents.subscribe, e) + }); + ns.on('unsubscribe', (e: SubEvent) => { + this.emit(AvailableEvents.unsubscribe, e) + }); + ns.on('yield', () => { + this.emit(AvailableEvents.yield) + }); + } /** - * [object Object] + * Try to connect to the NATS server with nkey authentication + */ + async connectWithNkey(options : NatsConnectionOptions, publicNkey: string, seed: string){ + options.nkey = publicNkey; + options.nonceSigner = (nonce: string): Buffer => { + const sk = fromSeed(Buffer.from(seed)); + return sk.sign(Buffer.from(nonce)); + } + await this.connect(options); + } + /** + * Set the default options based on the AsyncAPI file. + * @param options to set + */ + private setDefaultOptions(options: NatsConnectionOptions){ + //If server binding options sat set the options + options.encoding = 'utf8'; + return options; + } + + + + /** + * Any measured values will be published through this method. * @param requestMessage The message to publish. */ - public publishToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(requestMessage: LightMeasuredMessage): Promise { + public publishToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(requestMessage: LightMeasuredMessage + ,streetlightId: string + ): Promise { const nc: Client = this.jsonClient!; - return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.publish(requestMessage, nc); + if(nc){ + return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.publish(requestMessage, nc + + ,streetlightId + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10EventStreetlightIdLightingMeasured')) + } } - + /** - * [object Object] + * Get notified when a streetlight should be turned on. This should only be handled by 1 subscriber but ensured by request reply. * @param onRequest Called when request recieved. * @param onReplyError Called when it was not possible to send the reply. */ - public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOn(onRequest : (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, onReplyError : (err: NatsError) => void): Promise { + public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOn(onRequest : (err?: NatsError, msg?: TurnOnOffMessage, streetlightId?: string) =>Promise, onReplyError : (err: NatsError) => void + + ,streetlightId: string + ): Promise { const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.reply(onRequest, onReplyError, nc); + + if(nc){ + return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.reply(onRequest, onReplyError, nc + + ,streetlightId + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdTurnOn')) + } } - + /** - * [object Object] + * Get notified when a streetlight should be turned off. This should only be handled by 1 subscriber but ensured by request reply. * @param onRequest Called when request recieved. * @param onReplyError Called when it was not possible to send the reply. */ - public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOff(onRequest : (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, onReplyError : (err: NatsError) => void): Promise { + public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOff(onRequest : (err?: NatsError, msg?: TurnOnOffMessage, streetlightId?: string) =>Promise, onReplyError : (err: NatsError) => void + + ,streetlightId: string + ): Promise { const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.reply(onRequest, onReplyError, nc); + + if(nc){ + return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.reply(onRequest, onReplyError, nc + + ,streetlightId + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdTurnOff')) + } } - + /** - * [object Object] + * Get notified when a streetlight should be dimmed. This should only be handled by 1 subscriber but ensured by request reply. * @param onRequest Called when request recieved. * @param onReplyError Called when it was not possible to send the reply. */ - public replyToSmartylightingStreetlights10ActionStreetlightIdDim(onRequest : (err?: NatsError, msg?: DimLightMessage) => DimLightResponseMessage, onReplyError : (err: NatsError) => void): Promise { + public replyToSmartylightingStreetlights10ActionStreetlightIdDim(onRequest : (err?: NatsError, msg?: DimLightMessage, streetlightId?: string) =>Promise, onReplyError : (err: NatsError) => void + + ,streetlightId: string + ): Promise { const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdDimChannel.reply(onRequest, onReplyError, nc); + + if(nc){ + return smartylightingStreetlights10ActionStreetlightIdDimChannel.reply(onRequest, onReplyError, nc + + ,streetlightId + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdDim')) + } } + +} \ No newline at end of file diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdDim.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdDim.ts new file mode 100644 index 000000000..d1226a2e2 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdDim.ts @@ -0,0 +1,45 @@ + +import {default as DimLightResponseMessage} from '#messages/DimLightResponse' +import {default as DimLightMessage} from '#messages/DimLight' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + +export function request( + requestMessage: DimLightMessage, + nc: Client, + + streetlightId: string + + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived : any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + resolve(DimLightResponseMessage.toMessage(processedDataReceived)); + } + }, { max: 1 }); + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var requestData : any = requestMessage; + for(let hook of publishDataHooks){ + requestData = hook(requestData); + } + nc.publish(`smartylighting.streetlights.1.0.action.${streetlightId}.dim`, requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts new file mode 100644 index 000000000..82264c772 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts @@ -0,0 +1,45 @@ + +import {default as TurnOnOffResponseMessage} from '#messages/TurnOnOffResponse' +import {default as TurnOnOffMessage} from '#messages/TurnOnOff' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + +export function request( + requestMessage: TurnOnOffMessage, + nc: Client, + + streetlightId: string + + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived : any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + resolve(TurnOnOffResponseMessage.toMessage(processedDataReceived)); + } + }, { max: 1 }); + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var requestData : any = requestMessage; + for(let hook of publishDataHooks){ + requestData = hook(requestData); + } + nc.publish(`smartylighting.streetlights.1.0.action.${streetlightId}.turn.off`, requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts new file mode 100644 index 000000000..9b8d42c4e --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts @@ -0,0 +1,45 @@ + +import {default as TurnOnOffResponseMessage} from '#messages/TurnOnOffResponse' +import {default as TurnOnOffMessage} from '#messages/TurnOnOff' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + +export function request( + requestMessage: TurnOnOffMessage, + nc: Client, + + streetlightId: string + + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived : any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + resolve(TurnOnOffResponseMessage.toMessage(processedDataReceived)); + } + }, { max: 1 }); + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var requestData : any = requestMessage; + for(let hook of publishDataHooks){ + requestData = hook(requestData); + } + nc.publish(`smartylighting.streetlights.1.0.action.${streetlightId}.turn.on`, requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts new file mode 100644 index 000000000..5b4233d67 --- /dev/null +++ b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts @@ -0,0 +1,42 @@ + +import {default as LightMeasuredMessage} from '#messages/LightMeasured' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + +export function subscribe( + onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage, streetlightId?: string) => void, + nc: Client, + + streetlightId: string + + ): Promise { + return new Promise(async (resolve, reject) => { + try{ + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(`smartylighting.streetlights.1.0.event.${streetlightId}.lighting.measured`, (err, msg) => { + if(err){ + onDataCallback(err); + }else{ + const unmodifiedChannel = `smartylighting.streetlights.1.0.event.{streetlightId}.lighting.measured` + const receivedTopicParameters = { + streetlightId : msg.subject.slice(unmodifiedChannel.split("${streetlightId}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlightId}")[1].length) + } + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived: any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + let publishedData = LightMeasuredMessage.toMessage(processedDataReceived); + onDataCallback(undefined, publishedData, + receivedTopicParameters['streetlightId']); + } + }, subscribeOptions); + resolve(subscription); + }catch(e){ + reject(e); + } + }) +} + + diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts deleted file mode 100644 index f0c9801c9..000000000 --- a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts +++ /dev/null @@ -1,66 +0,0 @@ - -import {default as DimLightMessage} from '../../../messages/DimLight' -import {default as DimLightResponseMessage} from '../../../messages/DimLightResponse' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - -export function reply( - onRequest: (err?: NatsError, msg?: DimLightMessage) => DimLightResponseMessage, - onReplyError: (err: NatsError) => void, - , - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/dim', { - - "streetlightId": streetlightId - - }), (err, msg) => { - if (err) { - onRequest(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let requestData = new DimLightMessage(); - requestData.copyFrom(processedData); - - let responseObject = onRequest(undefined, requestData); - if (msg.reply) { - try { - let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); - nc.publish(msg.reply, requestData); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - console.error(error) - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts deleted file mode 100644 index 4393e85e3..000000000 --- a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts +++ /dev/null @@ -1,66 +0,0 @@ - -import {default as TurnOnOffMessage} from '../../../messages/TurnOnOff' -import {default as TurnOnOffResponseMessage} from '../../../messages/TurnOnOffResponse' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - -export function reply( - onRequest: (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, - onReplyError: (err: NatsError) => void, - , - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/off', { - - "streetlightId": streetlightId - - }), (err, msg) => { - if (err) { - onRequest(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let requestData = new TurnOnOffMessage(); - requestData.copyFrom(processedData); - - let responseObject = onRequest(undefined, requestData); - if (msg.reply) { - try { - let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); - nc.publish(msg.reply, requestData); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - console.error(error) - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts deleted file mode 100644 index 366873ed1..000000000 --- a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts +++ /dev/null @@ -1,66 +0,0 @@ - -import {default as TurnOnOffMessage} from '../../../messages/TurnOnOff' -import {default as TurnOnOffResponseMessage} from '../../../messages/TurnOnOffResponse' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - -export function reply( - onRequest: (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, - onReplyError: (err: NatsError) => void, - , - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/on', { - - "streetlightId": streetlightId - - }), (err, msg) => { - if (err) { - onRequest(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let requestData = new TurnOnOffMessage(); - requestData.copyFrom(processedData); - - let responseObject = onRequest(undefined, requestData); - if (msg.reply) { - try { - let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); - nc.publish(msg.reply, requestData); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - console.error(error) - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts deleted file mode 100644 index dba07ac3e..000000000 --- a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts +++ /dev/null @@ -1,37 +0,0 @@ - -import {default as LightMeasuredMessage} from '../../../messages/LightMeasured' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - - -export function publish( - requestMessage: LightMeasuredMessage, - - streetlightId:string - , - nc?: Client - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var dataToPublish; - for(let hook in publishDataHooks){ - dataToPublish = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured', { - - "streetlightId": streetlightId - - }), dataToPublish); - resolve(); - }catch(e){ - reject(e); - } - }else{ - reject(new Error("Nats client is not connected")); - } - }); -}; - diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event.ts deleted file mode 100644 index 937d72bdb..000000000 --- a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event.ts +++ /dev/null @@ -1,33 +0,0 @@ - -import {default as LightMeasuredMessage} from '../../../messages/LightMeasured' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - - -export function publish( - requestMessage: LightMeasuredMessage, - - nc?: Client - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var dataToPublish; - for(let hook in publishDataHooks){ - dataToPublish = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/event/*', { - - }), dataToPublish); - resolve(); - }catch(e){ - reject(e); - } - }else{ - reject(new Error("Nats client is not connected")); - } - }); -}; - diff --git a/test/expected_comparators/latest/frontend/tsconfig.json b/test/expected_comparators/latest/frontend/tsconfig.json index 9fb047824..b1d6a9fac 100644 --- a/test/expected_comparators/latest/frontend/tsconfig.json +++ b/test/expected_comparators/latest/frontend/tsconfig.json @@ -9,14 +9,17 @@ "preserveConstEnums": true, "sourceMap": true, "outDir": "dist/", - "baseUrl": "./src" /* Base directory to resolve non-absolute module names. */, + "baseUrl": "./src", "paths": { - "#messages": ["messages"], - "#schemas": ["schema"], - "#channels": ["channels"], - "#hooks": ["hooks"] + "#messages/*": ["messages/*"], + "#schemas/*": ["schema/*"], + "#channels/*": ["channels/*"], + "#testchannels/*": ["tests/testclient/testchannels/*"], + "#hooks": ["hooks"], + "#testclient": ["tests/testclient/index"], + "#client": ["index"] } }, - "include": ["src/**/*"], + "include": ["src"], "exclude": ["node_modules", "**/*.spec.ts"] } diff --git a/test/expected_comparators/latest/light-controller/README.md b/test/expected_comparators/latest/light-controller/README.md index 7d8ed191e..fb373e91a 100644 --- a/test/expected_comparators/latest/light-controller/README.md +++ b/test/expected_comparators/latest/light-controller/README.md @@ -1,8 +1,8 @@ -# Streetlights Nats API for lightning controllers +# Streetlights Nats API for the frontend The Smartylighting Streetlights API allows you to remotely manage the city lights. -This is for the lighting controllers, which assumed are multiple instances to ensure availability. +This is for the frontend where the lights can be controlled, which assumed are multiple instances to ensure availability. ### Check out its awesome features: diff --git a/test/expected_comparators/latest/light-controller/package.json b/test/expected_comparators/latest/light-controller/package.json index 7f9bc65a6..ef851e192 100644 --- a/test/expected_comparators/latest/light-controller/package.json +++ b/test/expected_comparators/latest/light-controller/package.json @@ -2,38 +2,35 @@ - "name": "streetlights-nats-api-for-lightning-controllers", - "description": "The Smartylighting Streetlights API allows you to remotely manage the city lights. This is for the lighting controllers, which assumed are multiple instances to ensure availability. ### Check out its awesome features: * Turn a specific streetlight on/off 🌃 * Dim a specific streetlight 😎 * Receive real-time information about environmental lighting conditions 📈 ", + "name": "streetlights-nats-api-for-the-frontend", + "description": "The Smartylighting Streetlights API allows you to remotely manage the city lights. This is for the frontend where the lights can be controlled, which assumed are multiple instances to ensure availability. ### Check out its awesome features: * Turn a specific streetlight on/off 🌃 * Dim a specific streetlight 😎 * Receive real-time information about environmental lighting conditions 📈 ", "version": "1.0.0", "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { "watch": "tsc --watch", - "build": "tsc", + "build": "tsc && npm run dopostinstall", "start": "node src/api/index.js", - "postinstall": "link-module-alias", - "test": "mocha -r ts-node/register tests/\*\*/\*.spec.ts" + "dopostinstall": "link-module-alias", + "test": "mocha -r ts-node/register tests/**/*.spec.ts" }, "_moduleAliasIgnoreWarning": true, "_moduleAliases": { - "#messages": "./src/messages", - "#schemas": "./src/schema", - "#channels": "./src/channels", - "#hooks": "./src/hooks" + "#messages": "dist/messages/", + "#schemas": "dist/schema/", + "#channels": "dist/channels/", + "#testchannels": "dist/tests/testclient/testchannels/", + "#hooks": "dist/hooks.js", + "#testclient": "dist/tests/testclient/index.js" }, "dependencies": { "@types/klaw-sync": "^6.0.0", - "@types/uuid": "3.4.5", "@types/node": "13.9.5", "klaw-sync": "6.0.0", "link-module-alias": "^1.2.0", - "msgpack-lite": "^0.1.26", "ts-nats": "1.2.4", - "node-yaml-config": "0.0.5", "typescript": "3.4.3", - "uuid": "3.3.3", - "winston": "3.2.1", - "winston-daily-rotate-file": "3.10.0" + "ts-nkeys":"1.0.16" }, "devDependencies": { "@types/chai": "^4.2.11", diff --git a/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdDim.ts b/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdDim.ts new file mode 100644 index 000000000..c6c715182 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdDim.ts @@ -0,0 +1,45 @@ + +import {default as DimLightMessage} from '#messages/DimLight' +import {default as DimLightResponseMessage} from '#messages/DimLightResponse' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + +export function request( + requestMessage: DimLightMessage, + nc: Client, + + streetlightId: string + + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived : any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + resolve(DimLightResponseMessage.toMessage(processedDataReceived)); + } + }, { max: 1 }); + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var requestData : any = requestMessage; + for(let hook of publishDataHooks){ + requestData = hook(requestData); + } + nc.publish(`smartylighting.streetlights.1.0.action.${streetlightId}.dim`, requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts b/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts new file mode 100644 index 000000000..5dbd4b06f --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts @@ -0,0 +1,45 @@ + +import {default as TurnOnOffMessage} from '#messages/TurnOnOff' +import {default as TurnOnOffResponseMessage} from '#messages/TurnOnOffResponse' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + +export function request( + requestMessage: TurnOnOffMessage, + nc: Client, + + streetlightId: string + + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived : any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + resolve(TurnOnOffResponseMessage.toMessage(processedDataReceived)); + } + }, { max: 1 }); + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var requestData : any = requestMessage; + for(let hook of publishDataHooks){ + requestData = hook(requestData); + } + nc.publish(`smartylighting.streetlights.1.0.action.${streetlightId}.turn.off`, requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts b/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts new file mode 100644 index 000000000..7a6fb17d6 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts @@ -0,0 +1,45 @@ + +import {default as TurnOnOffMessage} from '#messages/TurnOnOff' +import {default as TurnOnOffResponseMessage} from '#messages/TurnOnOffResponse' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + +export function request( + requestMessage: TurnOnOffMessage, + nc: Client, + + streetlightId: string + + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let inbox = nc.createInbox(); + await nc.subscribe(inbox, (err, msg) => { + if (err) { + reject(err); + } else { + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived : any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + resolve(TurnOnOffResponseMessage.toMessage(processedDataReceived)); + } + }, { max: 1 }); + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var requestData : any = requestMessage; + for(let hook of publishDataHooks){ + requestData = hook(requestData); + } + nc.publish(`smartylighting.streetlights.1.0.action.${streetlightId}.turn.on`, requestData, inbox); + }catch(e){ + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10Event.ts b/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10Event.ts new file mode 100644 index 000000000..3cb901a44 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10Event.ts @@ -0,0 +1,35 @@ + +import {default as LightMeasuredMessage} from '#messages/LightMeasured' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + +export function subscribe( + onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage) => void, + nc: Client, + + ): Promise { + return new Promise(async (resolve, reject) => { + try{ + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(`smartylighting.streetlights.1.0.event.*`, (err, msg) => { + if(err){ + onDataCallback(err); + }else{ + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived: any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + let publishedData = LightMeasuredMessage.toMessage(processedDataReceived); + onDataCallback(undefined, publishedData); + } + }, subscribeOptions); + resolve(subscription); + }catch(e){ + reject(e); + } + }) +} + + diff --git a/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts b/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts new file mode 100644 index 000000000..5b4233d67 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts @@ -0,0 +1,42 @@ + +import {default as LightMeasuredMessage} from '#messages/LightMeasured' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + +export function subscribe( + onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage, streetlightId?: string) => void, + nc: Client, + + streetlightId: string + + ): Promise { + return new Promise(async (resolve, reject) => { + try{ + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(`smartylighting.streetlights.1.0.event.${streetlightId}.lighting.measured`, (err, msg) => { + if(err){ + onDataCallback(err); + }else{ + const unmodifiedChannel = `smartylighting.streetlights.1.0.event.{streetlightId}.lighting.measured` + const receivedTopicParameters = { + streetlightId : msg.subject.slice(unmodifiedChannel.split("${streetlightId}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlightId}")[1].length) + } + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived: any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + let publishedData = LightMeasuredMessage.toMessage(processedDataReceived); + onDataCallback(undefined, publishedData, + receivedTopicParameters['streetlightId']); + } + }, subscribeOptions); + resolve(subscription); + }catch(e){ + reject(e); + } + }) +} + + diff --git a/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts deleted file mode 100644 index 324a21f47..000000000 --- a/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts +++ /dev/null @@ -1,66 +0,0 @@ - -import {default as DimLightResponseMessage} from '../messages/DimLightResponse' -import {default as DimLightMessage} from '../messages/DimLight' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - -export function reply( - onRequest: (err?: NatsError, msg?: DimLightMessage) => DimLightResponseMessage, - onReplyError: (err: NatsError) => void, - , - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/dim', { - - "streetlightId": streetlightId - - }), (err, msg) => { - if (err) { - onRequest(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let requestData = new DimLightMessage(); - requestData.copyFrom(processedData); - - let responseObject = onRequest(undefined, requestData); - if (msg.reply) { - try { - let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); - nc.publish(msg.reply, requestData); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - console.error(error) - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts deleted file mode 100644 index e66e7d710..000000000 --- a/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts +++ /dev/null @@ -1,66 +0,0 @@ - -import {default as TurnOnOffResponseMessage} from '../messages/TurnOnOffResponse' -import {default as TurnOnOffMessage} from '../messages/TurnOnOff' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - -export function reply( - onRequest: (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, - onReplyError: (err: NatsError) => void, - , - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/off', { - - "streetlightId": streetlightId - - }), (err, msg) => { - if (err) { - onRequest(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let requestData = new TurnOnOffMessage(); - requestData.copyFrom(processedData); - - let responseObject = onRequest(undefined, requestData); - if (msg.reply) { - try { - let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); - nc.publish(msg.reply, requestData); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - console.error(error) - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts deleted file mode 100644 index 431746c1d..000000000 --- a/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts +++ /dev/null @@ -1,66 +0,0 @@ - -import {default as TurnOnOffResponseMessage} from '../messages/TurnOnOffResponse' -import {default as TurnOnOffMessage} from '../messages/TurnOnOff' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - -export function reply( - onRequest: (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, - onReplyError: (err: NatsError) => void, - , - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/on', { - - "streetlightId": streetlightId - - }), (err, msg) => { - if (err) { - onRequest(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let requestData = new TurnOnOffMessage(); - requestData.copyFrom(processedData); - - let responseObject = onRequest(undefined, requestData); - if (msg.reply) { - try { - let requestData = utils.beforeResponse(responseObject, Payload.STRING, 'STRING'); - nc.publish(msg.reply, requestData); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - console.error(error) - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts deleted file mode 100644 index d106cccbe..000000000 --- a/test/expected_comparators/latest/light-controller/src/channels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts +++ /dev/null @@ -1,37 +0,0 @@ - -import {default as LightMeasuredMessage} from '../messages/LightMeasured' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {realizeChannelName} from './utils'; -import * as hooks from '#hooks'; - - -export function publish( - requestMessage: LightMeasuredMessage, - - streetlightId:string - , - nc?: Client - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var dataToPublish; - for(let hook in publishDataHooks){ - dataToPublish = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured', { - - "streetlightId": streetlightId - - }), dataToPublish); - resolve(); - }catch(e){ - reject(e); - } - }else{ - reject(new Error("Nats client is not connected")); - } - }); -}; - diff --git a/test/expected_comparators/latest/light-controller/src/channels/utils.ts b/test/expected_comparators/latest/light-controller/src/channels/utils.ts deleted file mode 100644 index 8810b700d..000000000 --- a/test/expected_comparators/latest/light-controller/src/channels/utils.ts +++ /dev/null @@ -1,11 +0,0 @@ -export function realizeChannelName(channelName: string, parameters: any) { - let returnString = channelName; - returnString = returnString.replace('/', '.'); - for (let parameterName in parameters) { - returnString = returnString.replace( - `{${parameterName}}`, - parameters[parameterName] - ); - } - return returnString; -} diff --git a/test/expected_comparators/latest/light-controller/src/hooks.ts b/test/expected_comparators/latest/light-controller/src/hooks.ts index 7dfcbfbd9..51e71a158 100644 --- a/test/expected_comparators/latest/light-controller/src/hooks.ts +++ b/test/expected_comparators/latest/light-controller/src/hooks.ts @@ -1,4 +1,3 @@ -const HOOKS_DIRNAME = './hooks'; import * as fs from 'fs'; import * as path from 'path'; import * as walkSync from 'klaw-sync'; @@ -6,58 +5,56 @@ export enum AvailableHooks { RecievedData = 'RecievedData', BeforeSendingData = 'BeforeSendingData' } -export type RecievedDataHook = () => void; -export type BeforeSendingDataHook = (messageToSend: any) => void; -export var hooks: { - BeforeSendingData: BeforeSendingDataHook[]; - RecievedData: RecievedDataHook[]; -}; - -/** - * Loads the custom hooks. - */ -try { - const hooksPath = path.resolve(HOOKS_DIRNAME); - if (fs.existsSync(hooksPath)) { - const files = walkSync(hooksPath, { nodir: true }); - files.forEach((file: any) => { - require(file.path)((when: AvailableHooks, hook: any) => { - hooks[when].push(hook); - }); - }); +export type RecievedDataHook = (receivedData: any) => string; +export type BeforeSendingDataHook = (messageToSend: any) => string; +export class Hooks { + private static instance: Hooks; + + private hooks: { + BeforeSendingData: BeforeSendingDataHook[]; + RecievedData: RecievedDataHook[]; + }; + private constructor() { + this.hooks = { + BeforeSendingData: [], + RecievedData: [] + } + } + public static getInstance(): Hooks { + if (!Hooks.instance) { + Hooks.instance = new Hooks(); + } + return Hooks.instance; } -} catch (e) { - e.message = `There was a problem registering the hooks: ${e.message}`; - throw e; -} - -/** - * Register a hook for BeforeSendingData - * @param hook - */ -export async function registerBeforeSendingData(hook: BeforeSendingDataHook) { - hooks[AvailableHooks.BeforeSendingData] - ? hooks[AvailableHooks.BeforeSendingData].push(hook) - : [hook]; -} - -/** - * Register a hook for BeforeSendingData - * @param hook - */ -export async function registerRecievedData(hook: RecievedDataHook) { - hooks[AvailableHooks.RecievedData] - ? hooks[AvailableHooks.RecievedData].push(hook) - : [hook]; -} -/** - * Get all the hooks registered at a given hook point/name. - * @param hook to find hooks for - * @returns all hooks - */ -export function getHooks(hook: AvailableHooks): Function[] { - if (!Array.isArray(hooks[hook])) return []; - // Return valid hooks - return hooks[hook]; -} + + + /** + * Register a hook for BeforeSendingData + * @param hook + */ + public async registerBeforeSendingData(hook: BeforeSendingDataHook) { + this.hooks[AvailableHooks.BeforeSendingData] + ? this.hooks[AvailableHooks.BeforeSendingData].push(hook) + : [hook]; + } + + /** + * Register a hook for BeforeSendingData + * @param hook + */ + public async registerRecievedData(hook: RecievedDataHook) { + this.hooks[AvailableHooks.RecievedData] + ? this.hooks[AvailableHooks.RecievedData].push(hook) + : [hook]; + } + + + public getRecievedDataHook(): RecievedDataHook[] { + return this.hooks[AvailableHooks.RecievedData]; + } + + public getBeforeSendingDataHook(): BeforeSendingDataHook[] { + return this.hooks[AvailableHooks.BeforeSendingData]; + } +} \ No newline at end of file diff --git a/test/expected_comparators/latest/light-controller/src/index.ts b/test/expected_comparators/latest/light-controller/src/index.ts index 380fa3473..6f81c6998 100644 --- a/test/expected_comparators/latest/light-controller/src/index.ts +++ b/test/expected_comparators/latest/light-controller/src/index.ts @@ -1,43 +1,153 @@ - -import { Client, NatsConnectionOptions, connect, Payload, NatsError, Subscription } from 'ts-nats'; -import * as smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel from "./channels/Smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured"; -import * as smartylightingStreetlights10ActionStreetlightIdTurnOnChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/turn/on"; -import * as smartylightingStreetlights10ActionStreetlightIdTurnOffChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/turn/off"; -import * as smartylightingStreetlights10ActionStreetlightIdDimChannel from "./channels/Smartylighting/streetlights/1/0/action/{streetlightId}/dim"; -import {default as LightMeasuredMessage} from "./messages/LightMeasured"; -import {default as TurnOnOffResponseMessage} from "./messages/TurnOnOffResponse"; -import {default as TurnOnOffMessage} from "./messages/TurnOnOff"; -import {default as DimLightResponseMessage} from "./messages/DimLightResponse"; -import {default as DimLightMessage} from "./messages/DimLight"; - -export default class NatsAsyncApiClient { + +import { + Client, + NatsConnectionOptions, + connect, + Payload, + NatsError, + Subscription, + ServersChangedEvent, + SubEvent, + ServerInfo + } from 'ts-nats'; +import * as smartylightingStreetlights10EventChannel from "#testchannels/SmartylightingStreetlights10Event"; +import * as smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel from "#testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured"; +import * as smartylightingStreetlights10ActionStreetlightIdTurnOnChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn"; +import * as smartylightingStreetlights10ActionStreetlightIdTurnOffChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff"; +import * as smartylightingStreetlights10ActionStreetlightIdDimChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdDim"; +import {default as LightMeasuredMessage} from "#messages/LightMeasured"; +import {default as TurnOnOffMessage} from "#messages/TurnOnOff"; +import {default as TurnOnOffResponseMessage} from "#messages/TurnOnOffResponse"; +import {default as DimLightMessage} from "#messages/DimLight"; +import {default as DimLightResponseMessage} from "#messages/DimLightResponse"; +import {fromSeed} from 'ts-nkeys'; +import * as events from 'events'; +export enum AvailableEvents { + connectionError = 'connectionError', + permissionError = 'permissionError', + close = 'close', + connect = 'connect', + connecting = 'connecting', + disconnect = 'disconnect', + error = 'error', + pingcount = 'pingcount', + pingtimer = 'pingtimer', + reconnect = 'reconnect', + reconnecting = 'reconnecting', + serversChanged = 'serversChanged', + subscribe = 'subscribe', + unsubscribe = 'unsubscribe', + yield = 'yield' +} +export declare interface NatsAsyncApiTestClient { + on(event: AvailableEvents.connectionError, listener: (error: any) => void): this; + on(event: AvailableEvents.permissionError, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.close, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; + on(event: AvailableEvents.connecting, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.error, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.pingcount, listener: () => void): this; + on(event: AvailableEvents.pingtimer, listener: () => void): this; + on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; + on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; + on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.yield, listener: () => void): this; +} +export class NatsAsyncApiTestClient extends events.EventEmitter{ public jsonClient?: Client; public stringClient?: Client; public binaryClient?: Client; - public options: NatsConnectionOptions; + public options?: NatsConnectionOptions; /** * * @param options options to use, payload is omitted if sat in the AsyncAPI document. */ - constructor(options : NatsConnectionOptions) { - this.options = this.setDefaultOptions(options); - this.connect(); + constructor() { + super(); } /** * Try to connect to the NATS server with the different payloads. */ - private async connect(){ + async connect(options : NatsConnectionOptions){ + this.options = this.setDefaultOptions(options); try{ this.options.payload = Payload.JSON; this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); }catch(e){ - console.error("Could not connect to NATS: " + e) + this.emit(AvailableEvents.connectionError, e) } } + + /** + * Disconnect all clients from the server + */ + async disconnect(){ + this.jsonClient!.close() + } + + private chainEvents(ns: Client){ + ns.on('permissionError', (e: NatsError) => { + this.emit(AvailableEvents.permissionError, e) + }); + ns.on('close', (e: NatsError) => { + this.emit(AvailableEvents.close, e) + }); + ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.connect, connection, serverURL, info) + }); + ns.on('connecting', (serverURL: NatsError) => { + this.emit(AvailableEvents.connecting, serverURL) + }); + ns.on('disconnect', (serverURL: string) => { + this.emit(AvailableEvents.disconnect, serverURL) + }); + ns.on('error', (e: NatsError) => { + this.emit(AvailableEvents.error, e) + }); + ns.on('pingcount', () => { + this.emit(AvailableEvents.pingcount) + }); + ns.on('pingtimer', () => { + this.emit(AvailableEvents.pingtimer) + }); + ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.reconnect, connection, serverURL, info) + }); + ns.on('reconnecting', (serverURL: string) => { + this.emit(AvailableEvents.reconnecting, serverURL) + }); + ns.on('serversChanged', (e: ServersChangedEvent) => { + this.emit(AvailableEvents.serversChanged, e) + }); + ns.on('subscribe', (e: SubEvent) => { + this.emit(AvailableEvents.subscribe, e) + }); + ns.on('unsubscribe', (e: SubEvent) => { + this.emit(AvailableEvents.unsubscribe, e) + }); + ns.on('yield', () => { + this.emit(AvailableEvents.yield) + }); + } + /** + * Try to connect to the NATS server with nkey authentication + */ + async connectWithNkey(options : NatsConnectionOptions, publicNkey: string, seed: string){ + options.nkey = publicNkey; + options.nonceSigner = (nonce: string): Buffer => { + const sk = fromSeed(Buffer.from(seed)); + return sk.sign(Buffer.from(nonce)); + } + await this.connect(options); + } /** * Set the default options based on the AsyncAPI file. * @param options to set @@ -47,47 +157,106 @@ export default class NatsAsyncApiClient { options.encoding = 'utf8'; return options; } - + + + /** - * Any measured values will be published through this method. + * Topic for which one can subscribe to all measurements regardless of id. * @param requestMessage The message to publish. */ - public publishToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(requestMessage: LightMeasuredMessage): Promise { + public publishToSmartylightingStreetlights10Event(requestMessage: LightMeasuredMessage ): Promise { const nc: Client = this.jsonClient!; - return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.publish(requestMessage, nc); + if(nc){ + return smartylightingStreetlights10EventChannel.publish(requestMessage, nc + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10Event')) + } } - + + /** + * Topic for which one can subscribe to measurements on a specific streetlightId. + * @param requestMessage The message to publish. + */ + public publishToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(requestMessage: LightMeasuredMessage + ,streetlightId: string + ): Promise { + const nc: Client = this.jsonClient!; + if(nc){ + return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.publish(requestMessage, nc + + ,streetlightId + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10EventStreetlightIdLightingMeasured')) + } + } + + /** - * Get notified when a streetlight should be turned on. This should only be handled by 1 subscriber but ensured by request reply. + * * @param onRequest Called when request recieved. * @param onReplyError Called when it was not possible to send the reply. */ - public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOn(onRequest : (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, onReplyError : (err: NatsError) => void): Promise { + public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOn(onRequest : (err?: NatsError, msg?: TurnOnOffMessage, streetlightId?: string) =>Promise, onReplyError : (err: NatsError) => void + + ,streetlightId: string + ): Promise { const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.reply(onRequest, onReplyError, nc); + + if(nc){ + return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.reply(onRequest, onReplyError, nc + + ,streetlightId + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdTurnOn')) + } } - + /** - * Get notified when a streetlight should be turned off. This should only be handled by 1 subscriber but ensured by request reply. + * * @param onRequest Called when request recieved. * @param onReplyError Called when it was not possible to send the reply. */ - public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOff(onRequest : (err?: NatsError, msg?: TurnOnOffMessage) => TurnOnOffResponseMessage, onReplyError : (err: NatsError) => void): Promise { + public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOff(onRequest : (err?: NatsError, msg?: TurnOnOffMessage, streetlightId?: string) =>Promise, onReplyError : (err: NatsError) => void + + ,streetlightId: string + ): Promise { const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.reply(onRequest, onReplyError, nc); + + if(nc){ + return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.reply(onRequest, onReplyError, nc + + ,streetlightId + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdTurnOff')) + } } - + /** - * Get notified when a streetlight should be dimmed. This should only be handled by 1 subscriber but ensured by request reply. + * * @param onRequest Called when request recieved. * @param onReplyError Called when it was not possible to send the reply. */ - public replyToSmartylightingStreetlights10ActionStreetlightIdDim(onRequest : (err?: NatsError, msg?: DimLightMessage) => DimLightResponseMessage, onReplyError : (err: NatsError) => void): Promise { + public replyToSmartylightingStreetlights10ActionStreetlightIdDim(onRequest : (err?: NatsError, msg?: DimLightMessage, streetlightId?: string) =>Promise, onReplyError : (err: NatsError) => void + + ,streetlightId: string + ): Promise { const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdDimChannel.reply(onRequest, onReplyError, nc); + + if(nc){ + return smartylightingStreetlights10ActionStreetlightIdDimChannel.reply(onRequest, onReplyError, nc + + ,streetlightId + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdDim')) + } } } diff --git a/test/expected_comparators/latest/light-controller/src/messages/DimLight.ts b/test/expected_comparators/latest/light-controller/src/messages/DimLight.ts new file mode 100644 index 000000000..019165814 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/messages/DimLight.ts @@ -0,0 +1,29 @@ + +import { default as DimLightPayloadserereSchema } from '#schemas/DimLightPayloadserere'; +import { default as ResponseSchema } from '#schemas/Response'; +export default class DimLight { + + + + dimLightPayloadserere:DimLightPayloadserereSchema; + + + + response:ResponseSchema; + + + constructor( + + ){ + + } + + /** + * Parses a JSON string to an object of DimLight message class. + * @param json any to be parsed as DimLight. + */ + public static toMessage(json: any): DimLight { + return JSON.parse(JSON.stringify(json)); + } + +} diff --git a/test/expected_comparators/latest/frontend/src/messages/dimLightResponse.ts b/test/expected_comparators/latest/light-controller/src/messages/DimLightResponse.ts similarity index 54% rename from test/expected_comparators/latest/frontend/src/messages/dimLightResponse.ts rename to test/expected_comparators/latest/light-controller/src/messages/DimLightResponse.ts index 2e0d9da0e..a9733f541 100644 --- a/test/expected_comparators/latest/frontend/src/messages/dimLightResponse.ts +++ b/test/expected_comparators/latest/light-controller/src/messages/DimLightResponse.ts @@ -1,9 +1,5 @@ - - -import { default as ResponseSchema } from '../schema/Response'; - - +import { default as ResponseSchema } from '#schemas/Response'; export default class DimLightResponse { @@ -21,10 +17,10 @@ export default class DimLightResponse { /** * Parses a JSON string to an object of DimLightResponse message class. - * @param json string to be parsed as DimLightResponse. + * @param json any to be parsed as DimLightResponse. */ - public static toMessage(json: string): DimLightResponse { - return JSON.parse(json); + public static toMessage(json: any): DimLightResponse { + return JSON.parse(JSON.stringify(json)); } } diff --git a/test/expected_comparators/latest/frontend/src/messages/lightMeasured.ts b/test/expected_comparators/latest/light-controller/src/messages/LightMeasured.ts similarity index 58% rename from test/expected_comparators/latest/frontend/src/messages/lightMeasured.ts rename to test/expected_comparators/latest/light-controller/src/messages/LightMeasured.ts index 9e2010e22..39931197c 100644 --- a/test/expected_comparators/latest/frontend/src/messages/lightMeasured.ts +++ b/test/expected_comparators/latest/light-controller/src/messages/LightMeasured.ts @@ -1,9 +1,5 @@ - - -import { default as LightMeasuredPayloadSchema } from '../schema/LightMeasuredPayload'; - - +import { default as LightMeasuredPayloadSchema } from '#schemas/LightMeasuredPayload'; export default class LightMeasured { @@ -21,10 +17,10 @@ export default class LightMeasured { /** * Parses a JSON string to an object of LightMeasured message class. - * @param json string to be parsed as LightMeasured. + * @param json any to be parsed as LightMeasured. */ - public static toMessage(json: string): LightMeasured { - return JSON.parse(json); + public static toMessage(json: any): LightMeasured { + return JSON.parse(JSON.stringify(json)); } } diff --git a/test/expected_comparators/latest/light-controller/src/messages/turnOnOff.ts b/test/expected_comparators/latest/light-controller/src/messages/TurnOnOff.ts similarity index 57% rename from test/expected_comparators/latest/light-controller/src/messages/turnOnOff.ts rename to test/expected_comparators/latest/light-controller/src/messages/TurnOnOff.ts index 483922274..5d990599a 100644 --- a/test/expected_comparators/latest/light-controller/src/messages/turnOnOff.ts +++ b/test/expected_comparators/latest/light-controller/src/messages/TurnOnOff.ts @@ -1,9 +1,5 @@ - - -import { default as TurnOnOffPayloadSchema } from '../schema/TurnOnOffPayload'; - - +import { default as TurnOnOffPayloadSchema } from '#schemas/TurnOnOffPayload'; export default class TurnOnOff { @@ -21,10 +17,10 @@ export default class TurnOnOff { /** * Parses a JSON string to an object of TurnOnOff message class. - * @param json string to be parsed as TurnOnOff. + * @param json any to be parsed as TurnOnOff. */ - public static toMessage(json: string): TurnOnOff { - return JSON.parse(json); + public static toMessage(json: any): TurnOnOff { + return JSON.parse(JSON.stringify(json)); } } diff --git a/test/expected_comparators/latest/frontend/src/messages/turnOnOffResponse.ts b/test/expected_comparators/latest/light-controller/src/messages/TurnOnOffResponse.ts similarity index 54% rename from test/expected_comparators/latest/frontend/src/messages/turnOnOffResponse.ts rename to test/expected_comparators/latest/light-controller/src/messages/TurnOnOffResponse.ts index c25f1a5c5..ba0b02f5e 100644 --- a/test/expected_comparators/latest/frontend/src/messages/turnOnOffResponse.ts +++ b/test/expected_comparators/latest/light-controller/src/messages/TurnOnOffResponse.ts @@ -1,9 +1,5 @@ - - -import { default as ResponseSchema } from '../schema/Response'; - - +import { default as ResponseSchema } from '#schemas/Response'; export default class TurnOnOffResponse { @@ -21,10 +17,10 @@ export default class TurnOnOffResponse { /** * Parses a JSON string to an object of TurnOnOffResponse message class. - * @param json string to be parsed as TurnOnOffResponse. + * @param json any to be parsed as TurnOnOffResponse. */ - public static toMessage(json: string): TurnOnOffResponse { - return JSON.parse(json); + public static toMessage(json: any): TurnOnOffResponse { + return JSON.parse(JSON.stringify(json)); } } diff --git a/test/expected_comparators/latest/light-controller/src/messages/dimLight.ts b/test/expected_comparators/latest/light-controller/src/messages/dimLight.ts deleted file mode 100644 index 7a8281027..000000000 --- a/test/expected_comparators/latest/light-controller/src/messages/dimLight.ts +++ /dev/null @@ -1,45 +0,0 @@ - - - - -import { default as DimLightPayloadserereSchema } from '../schema/DimLightPayloadserere'; - - - -import { default as ResponseSchema } from '../schema/Response'; - - -export default class DimLight { - - - - dimLightPayloadserere:DimLightPayloadserereSchema; - - - - response:ResponseSchema; - - - constructor( - dimLightPayloadserere: DimLightPayloadserereSchema,response: ResponseSchema - ){ - - - - this.dimLightPayloadserere = dimLightPayloadserere; - - - - this.response = response; - - } - - /** - * Parses a JSON string to an object of DimLight message class. - * @param json string to be parsed as DimLight. - */ - public static toMessage(json: string): DimLight { - return JSON.parse(json); - } - -} diff --git a/test/expected_comparators/latest/light-controller/src/schema/DimLightPayloadserere.ts b/test/expected_comparators/latest/light-controller/src/schema/DimLightPayloadserere.ts new file mode 100644 index 000000000..279439192 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/schema/DimLightPayloadserere.ts @@ -0,0 +1,19 @@ + + + +export default class dimLightPayloadserere { + + + percentage?: Number + sentAt?: string + + + + constructor( + + ){ + + + + } +} diff --git a/test/expected_comparators/latest/frontend/src/schema/lightMeasuredPayload.ts b/test/expected_comparators/latest/light-controller/src/schema/LightMeasuredPayload.ts similarity index 66% rename from test/expected_comparators/latest/frontend/src/schema/lightMeasuredPayload.ts rename to test/expected_comparators/latest/light-controller/src/schema/LightMeasuredPayload.ts index a783f2728..e090e2247 100644 --- a/test/expected_comparators/latest/frontend/src/schema/lightMeasuredPayload.ts +++ b/test/expected_comparators/latest/light-controller/src/schema/LightMeasuredPayload.ts @@ -1,7 +1,6 @@ - export default class lightMeasuredPayload { @@ -10,4 +9,11 @@ export default class lightMeasuredPayload { + constructor( + + ){ + + + + } } diff --git a/test/expected_comparators/latest/frontend/src/schema/response.ts b/test/expected_comparators/latest/light-controller/src/schema/Response.ts similarity index 66% rename from test/expected_comparators/latest/frontend/src/schema/response.ts rename to test/expected_comparators/latest/light-controller/src/schema/Response.ts index 0c80740f4..afc8c5d71 100644 --- a/test/expected_comparators/latest/frontend/src/schema/response.ts +++ b/test/expected_comparators/latest/light-controller/src/schema/Response.ts @@ -1,7 +1,6 @@ - export default class response { @@ -11,4 +10,12 @@ export default class response { + constructor( + + ){ + + + + + } } diff --git a/test/expected_comparators/latest/frontend/src/schema/turnOnOffPayload.ts b/test/expected_comparators/latest/light-controller/src/schema/TurnOnOffPayload.ts similarity index 65% rename from test/expected_comparators/latest/frontend/src/schema/turnOnOffPayload.ts rename to test/expected_comparators/latest/light-controller/src/schema/TurnOnOffPayload.ts index c9ea846aa..f35e771e2 100644 --- a/test/expected_comparators/latest/frontend/src/schema/turnOnOffPayload.ts +++ b/test/expected_comparators/latest/light-controller/src/schema/TurnOnOffPayload.ts @@ -1,7 +1,6 @@ - export default class turnOnOffPayload { @@ -10,4 +9,11 @@ export default class turnOnOffPayload { + constructor( + + ){ + + + + } } diff --git a/test/expected_comparators/latest/light-controller/src/schema/anonymous-schema-4.ts b/test/expected_comparators/latest/light-controller/src/schema/anonymous-schema-4.ts deleted file mode 100644 index ef2cd616f..000000000 --- a/test/expected_comparators/latest/light-controller/src/schema/anonymous-schema-4.ts +++ /dev/null @@ -1,11 +0,0 @@ - - - - -export default class anonymousSchema4 { - - - - - -} diff --git a/test/expected_comparators/latest/light-controller/src/schema/anonymous-schema-5.ts b/test/expected_comparators/latest/light-controller/src/schema/anonymous-schema-5.ts deleted file mode 100644 index e11ccc78d..000000000 --- a/test/expected_comparators/latest/light-controller/src/schema/anonymous-schema-5.ts +++ /dev/null @@ -1,22 +0,0 @@ - - - - -export default class anonymousSchema5 { - - - - percentage?: Number - sentAt?: string - - - - status?: Number - statusMessage?: string - sentAt?: string - - - - - -} diff --git a/test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/expected_comparators/latest/light-controller/src/tests/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/index.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/index.ts index c7cd13ee6..bc69bdd47 100644 --- a/test/expected_comparators/latest/light-controller/src/tests/testclient/index.ts +++ b/test/expected_comparators/latest/light-controller/src/tests/testclient/index.ts @@ -1,41 +1,257 @@ - + +import { + Client, + NatsConnectionOptions, + connect, + Payload, + NatsError, + Subscription, + ServersChangedEvent, + SubEvent, + ServerInfo + } from 'ts-nats'; +import * as smartylightingStreetlights10EventChannel from "#testchannels/SmartylightingStreetlights10Event"; +import * as smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel from "#testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured"; +import * as smartylightingStreetlights10ActionStreetlightIdTurnOnChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn"; +import * as smartylightingStreetlights10ActionStreetlightIdTurnOffChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff"; +import * as smartylightingStreetlights10ActionStreetlightIdDimChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdDim"; +import {default as LightMeasuredMessage} from "#messages/LightMeasured"; +import {default as TurnOnOffMessage} from "#messages/TurnOnOff"; +import {default as TurnOnOffResponseMessage} from "#messages/TurnOnOffResponse"; +import {default as DimLightMessage} from "#messages/DimLight"; +import {default as DimLightResponseMessage} from "#messages/DimLightResponse"; +import {fromSeed} from 'ts-nkeys'; +import * as events from 'events'; +export enum AvailableEvents { + connectionError = 'connectionError', + permissionError = 'permissionError', + close = 'close', + connect = 'connect', + connecting = 'connecting', + disconnect = 'disconnect', + error = 'error', + pingcount = 'pingcount', + pingtimer = 'pingtimer', + reconnect = 'reconnect', + reconnecting = 'reconnecting', + serversChanged = 'serversChanged', + subscribe = 'subscribe', + unsubscribe = 'unsubscribe', + yield = 'yield' +} +export declare interface NatsAsyncApiTestClient { + on(event: AvailableEvents.connectionError, listener: (error: any) => void): this; + on(event: AvailableEvents.permissionError, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.close, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; + on(event: AvailableEvents.connecting, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.error, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.pingcount, listener: () => void): this; + on(event: AvailableEvents.pingtimer, listener: () => void): this; + on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; + on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; + on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.yield, listener: () => void): this; +} +export class NatsAsyncApiTestClient extends events.EventEmitter{ + public jsonClient?: Client; + public stringClient?: Client; + public binaryClient?: Client; + public options?: NatsConnectionOptions; + + /** + * + * @param options options to use, payload is omitted if sat in the AsyncAPI document. + */ + constructor() { + super(); + } + + /** + * Try to connect to the NATS server with the different payloads. + */ + async connect(options : NatsConnectionOptions){ + this.options = this.setDefaultOptions(options); + try{ + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); + }catch(e){ + this.emit(AvailableEvents.connectionError, e) + } + } + + + /** + * Disconnect all clients from the server + */ + async disconnect(){ + this.jsonClient!.close() + } + + private chainEvents(ns: Client){ + ns.on('permissionError', (e: NatsError) => { + this.emit(AvailableEvents.permissionError, e) + }); + ns.on('close', (e: NatsError) => { + this.emit(AvailableEvents.close, e) + }); + ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.connect, connection, serverURL, info) + }); + ns.on('connecting', (serverURL: NatsError) => { + this.emit(AvailableEvents.connecting, serverURL) + }); + ns.on('disconnect', (serverURL: string) => { + this.emit(AvailableEvents.disconnect, serverURL) + }); + ns.on('error', (e: NatsError) => { + this.emit(AvailableEvents.error, e) + }); + ns.on('pingcount', () => { + this.emit(AvailableEvents.pingcount) + }); + ns.on('pingtimer', () => { + this.emit(AvailableEvents.pingtimer) + }); + ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.reconnect, connection, serverURL, info) + }); + ns.on('reconnecting', (serverURL: string) => { + this.emit(AvailableEvents.reconnecting, serverURL) + }); + ns.on('serversChanged', (e: ServersChangedEvent) => { + this.emit(AvailableEvents.serversChanged, e) + }); + ns.on('subscribe', (e: SubEvent) => { + this.emit(AvailableEvents.subscribe, e) + }); + ns.on('unsubscribe', (e: SubEvent) => { + this.emit(AvailableEvents.unsubscribe, e) + }); + ns.on('yield', () => { + this.emit(AvailableEvents.yield) + }); + } + /** + * Try to connect to the NATS server with nkey authentication + */ + async connectWithNkey(options : NatsConnectionOptions, publicNkey: string, seed: string){ + options.nkey = publicNkey; + options.nonceSigner = (nonce: string): Buffer => { + const sk = fromSeed(Buffer.from(seed)); + return sk.sign(Buffer.from(nonce)); + } + await this.connect(options); + } /** - * [object Object] + * Set the default options based on the AsyncAPI file. + * @param options to set + */ + private setDefaultOptions(options: NatsConnectionOptions){ + //If server binding options sat set the options + options.encoding = 'utf8'; + return options; + } + + + + /** + * Topic for which one can subscribe to all measurements regardless of id. * @param onDataCallback Called when message recieved. */ - public subscribeToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage) => void): Promise { + public subscribeToSmartylightingStreetlights10Event(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage) => void ): Promise { const nc: Client = this.jsonClient!; - return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.subscribe(onDataCallback, nc); + if(nc){ + return smartylightingStreetlights10EventChannel.subscribe(onDataCallback, nc + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10Event')) + } } - + /** - * [object Object] + * Topic for which one can subscribe to measurements on a specific streetlightId. + * @param onDataCallback Called when message recieved. + */ + public subscribeToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage, streetlightId?: string) => void + ,streetlightId: string + ): Promise { + const nc: Client = this.jsonClient!; + if(nc){ + return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.subscribe(onDataCallback, nc + + ,streetlightId + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10EventStreetlightIdLightingMeasured')) + } + } + + + /** + * * @param requestMessage The request message to send. */ - public requestSmartylightingStreetlights10ActionStreetlightIdTurnOn(requestMessage: TurnOnOffMessage): Promise { + public requestSmartylightingStreetlights10ActionStreetlightIdTurnOn(requestMessage: TurnOnOffMessage + + ,streetlightId: string + ): Promise { const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.request(requestMessage, nc); + if(nc){ + return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.request(requestMessage, nc + + ,streetlightId + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdTurnOn')) + } } - + /** - * [object Object] + * * @param requestMessage The request message to send. */ - public requestSmartylightingStreetlights10ActionStreetlightIdTurnOff(requestMessage: TurnOnOffMessage): Promise { + public requestSmartylightingStreetlights10ActionStreetlightIdTurnOff(requestMessage: TurnOnOffMessage + + ,streetlightId: string + ): Promise { const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.request(requestMessage, nc); + if(nc){ + return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.request(requestMessage, nc + + ,streetlightId + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdTurnOff')) + } } - + /** - * [object Object] + * * @param requestMessage The request message to send. */ - public requestSmartylightingStreetlights10ActionStreetlightIdDim(requestMessage: DimLightMessage): Promise { + public requestSmartylightingStreetlights10ActionStreetlightIdDim(requestMessage: DimLightMessage + + ,streetlightId: string + ): Promise { const nc: Client = this.jsonClient!; - return smartylightingStreetlights10ActionStreetlightIdDimChannel.request(requestMessage, nc); + if(nc){ + return smartylightingStreetlights10ActionStreetlightIdDimChannel.request(requestMessage, nc + + ,streetlightId + ); + }else{ + return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdDim')) + } } + +} \ No newline at end of file diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdDim.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdDim.ts new file mode 100644 index 000000000..002a5d646 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdDim.ts @@ -0,0 +1,70 @@ + +import {default as DimLightMessage} from '#messages/DimLight' +import {default as DimLightResponseMessage} from '#messages/DimLightResponse' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + +export function reply( + onRequest: (err?: NatsError, msg?: DimLightMessage, streetlightId?: string) =>Promise, + onReplyError: (err: NatsError) => void, + nc: Client, + + streetlightId: string + + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(`smartylighting.streetlights.1.0.action.${streetlightId}.dim`,async (err, msg) => { + if (err) { + onRequest(err); + } else { + const unmodifiedChannel = `smartylighting.streetlights.1.0.action.{streetlightId}.dim` + const receivedTopicParameters = { + streetlightId : msg.subject.slice(unmodifiedChannel.split("${streetlightId}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlightId}")[1].length) + } + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived : any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + let requestData = DimLightMessage.toMessage(processedDataReceived); + let responseObject =await onRequest(undefined, requestData, + receivedTopicParameters['streetlightId']); + if (msg.reply) { + try { + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToPublish : any = responseObject; + for(let hook of publishDataHooks){ + dataToPublish = hook(dataToPublish); + } + nc.publish(msg.reply, dataToPublish); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts new file mode 100644 index 000000000..72032ae2b --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts @@ -0,0 +1,70 @@ + +import {default as TurnOnOffMessage} from '#messages/TurnOnOff' +import {default as TurnOnOffResponseMessage} from '#messages/TurnOnOffResponse' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + +export function reply( + onRequest: (err?: NatsError, msg?: TurnOnOffMessage, streetlightId?: string) =>Promise, + onReplyError: (err: NatsError) => void, + nc: Client, + + streetlightId: string + + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(`smartylighting.streetlights.1.0.action.${streetlightId}.turn.off`,async (err, msg) => { + if (err) { + onRequest(err); + } else { + const unmodifiedChannel = `smartylighting.streetlights.1.0.action.{streetlightId}.turn.off` + const receivedTopicParameters = { + streetlightId : msg.subject.slice(unmodifiedChannel.split("${streetlightId}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlightId}")[1].length) + } + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived : any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + let requestData = TurnOnOffMessage.toMessage(processedDataReceived); + let responseObject =await onRequest(undefined, requestData, + receivedTopicParameters['streetlightId']); + if (msg.reply) { + try { + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToPublish : any = responseObject; + for(let hook of publishDataHooks){ + dataToPublish = hook(dataToPublish); + } + nc.publish(msg.reply, dataToPublish); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts new file mode 100644 index 000000000..dc3224e15 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts @@ -0,0 +1,70 @@ + +import {default as TurnOnOffMessage} from '#messages/TurnOnOff' +import {default as TurnOnOffResponseMessage} from '#messages/TurnOnOffResponse' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + +export function reply( + onRequest: (err?: NatsError, msg?: TurnOnOffMessage, streetlightId?: string) =>Promise, + onReplyError: (err: NatsError) => void, + nc: Client, + + streetlightId: string + + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try { + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(`smartylighting.streetlights.1.0.action.${streetlightId}.turn.on`,async (err, msg) => { + if (err) { + onRequest(err); + } else { + const unmodifiedChannel = `smartylighting.streetlights.1.0.action.{streetlightId}.turn.on` + const receivedTopicParameters = { + streetlightId : msg.subject.slice(unmodifiedChannel.split("${streetlightId}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlightId}")[1].length) + } + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived : any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + let requestData = TurnOnOffMessage.toMessage(processedDataReceived); + let responseObject =await onRequest(undefined, requestData, + receivedTopicParameters['streetlightId']); + if (msg.reply) { + try { + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToPublish : any = responseObject; + for(let hook of publishDataHooks){ + dataToPublish = hook(dataToPublish); + } + nc.publish(msg.reply, dataToPublish); + } catch (e) { + if (onReplyError) { + onReplyError(e) + } else { + console.error(e) + } + } + } else { + let error = new NatsError('Expected request to need a reply, did not..', '000'); + if (onReplyError) { + onReplyError(error) + } else { + } + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(e); + } + } else { + reject(new Error("Nats client is not connected")); + } + }) +} + + diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10Event.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10Event.ts new file mode 100644 index 000000000..e65ed585c --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10Event.ts @@ -0,0 +1,30 @@ + +import {default as LightMeasuredMessage} from '#messages/LightMeasured' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + + +export function publish( + requestMessage: LightMeasuredMessage, + nc: Client, + + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToPublish : any = requestMessage; + for(let hook of publishDataHooks){ + dataToPublish = hook(dataToPublish); + } + nc.publish(`smartylighting.streetlights.1.0.event.*`, dataToPublish); + resolve(); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }); +}; + diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts new file mode 100644 index 000000000..f22b47c33 --- /dev/null +++ b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts @@ -0,0 +1,32 @@ + +import {default as LightMeasuredMessage} from '#messages/LightMeasured' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import { Hooks } from '#hooks'; + + +export function publish( + requestMessage: LightMeasuredMessage, + nc: Client, + + streetlightId: string + + ): Promise { + return new Promise(async (resolve, reject) => { + if (nc) { + try{ + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToPublish : any = requestMessage; + for(let hook of publishDataHooks){ + dataToPublish = hook(dataToPublish); + } + nc.publish(`smartylighting.streetlights.1.0.event.${streetlightId}.lighting.measured`, dataToPublish); + resolve(); + }catch(e){ + reject(e); + } + }else{ + reject(new Error("Nats client is not connected")); + } + }); +}; + diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts deleted file mode 100644 index 008f5e2b9..000000000 --- a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-dim.ts +++ /dev/null @@ -1,46 +0,0 @@ - -import {default as DimLightResponseMessage} from '../../../messages/DimLightResponse' -import {default as DimLightMessage} from '../../../messages/DimLight' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - -export function request( - requestMessage: DimLightMessage, - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - resolve(DimLightResponseMessage.toMessage(processedData)); - } - }, { max: 1 }); - let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var requestData; - for(let hook in publishDataHooks){ - requestData = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/dim', { - - "streetlightId": streetlightId - - }), requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts deleted file mode 100644 index 91a2eb86a..000000000 --- a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-off.ts +++ /dev/null @@ -1,46 +0,0 @@ - -import {default as TurnOnOffResponseMessage} from '../../../messages/TurnOnOffResponse' -import {default as TurnOnOffMessage} from '../../../messages/TurnOnOff' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - -export function request( - requestMessage: TurnOnOffMessage, - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - resolve(TurnOnOffResponseMessage.toMessage(processedData)); - } - }, { max: 1 }); - let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var requestData; - for(let hook in publishDataHooks){ - requestData = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/off', { - - "streetlightId": streetlightId - - }), requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts deleted file mode 100644 index e69df5569..000000000 --- a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-action-{streetlightId}-turn-on.ts +++ /dev/null @@ -1,46 +0,0 @@ - -import {default as TurnOnOffResponseMessage} from '../../../messages/TurnOnOffResponse' -import {default as TurnOnOffMessage} from '../../../messages/TurnOnOff' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - -export function request( - requestMessage: TurnOnOffMessage, - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - resolve(TurnOnOffResponseMessage.toMessage(processedData)); - } - }, { max: 1 }); - let publishDataHooks = getHooks(AvailableHooks.BeforeSendingData); - let publishDataHooks = hooks.getHooks(AvailableHooks.BeforeSendingData) as hooks.BeforeSendingDataHook[]; - var requestData; - for(let hook in publishDataHooks){ - requestData = hook(requestMessage); - } - nc.publish(realizeChannelName('smartylighting/streetlights/1/0/action/{streetlightId}/turn/on', { - - "streetlightId": streetlightId - - }), requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts deleted file mode 100644 index e36a33357..000000000 --- a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/smartylighting-streetlights-1-0-event-{streetlightId}-lighting-measured.ts +++ /dev/null @@ -1,44 +0,0 @@ - -import {default as LightMeasuredMessage} from '../../../messages/LightMeasured' - -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import * as utils from '../utils'; - - -import {getHooks, AvailableHooks} from '#hooks'; -export function subscribe( - onDataCallback : (err?: NatsError, msg?: lightMeasured) => void, - - streetlightId:string - , - nc?: Client): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(realizeChannelName('smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured', { - - "streetlightId": streetlightId - - }), (err, msg) => { - if(err){ - onDataCallback(err); - }else{ - let processedData = utils.processRecievedData(msg.data, Payload.STRING, 'STRING'); - let publishedData = new lightMeasured(); - publishedData.copyFrom(processedData); - onDataCallback(undefined, publishedData); - } - }, subscribeOptions); - resolve(subscription); - }catch(e){ - reject(e); - } - }else{ - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/light-controller/tsconfig.json b/test/expected_comparators/latest/light-controller/tsconfig.json index 9fb047824..b1d6a9fac 100644 --- a/test/expected_comparators/latest/light-controller/tsconfig.json +++ b/test/expected_comparators/latest/light-controller/tsconfig.json @@ -9,14 +9,17 @@ "preserveConstEnums": true, "sourceMap": true, "outDir": "dist/", - "baseUrl": "./src" /* Base directory to resolve non-absolute module names. */, + "baseUrl": "./src", "paths": { - "#messages": ["messages"], - "#schemas": ["schema"], - "#channels": ["channels"], - "#hooks": ["hooks"] + "#messages/*": ["messages/*"], + "#schemas/*": ["schema/*"], + "#channels/*": ["channels/*"], + "#testchannels/*": ["tests/testclient/testchannels/*"], + "#hooks": ["hooks"], + "#testclient": ["tests/testclient/index"], + "#client": ["index"] } }, - "include": ["src/**/*"], + "include": ["src"], "exclude": ["node_modules", "**/*.spec.ts"] } From fee8cd5d232aeaa3e3afa7aa018658dabeeade2e Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Wed, 27 May 2020 01:55:24 +0200 Subject: [PATCH 051/110] Removed unused dependencies. Updated README.md. --- README.md | 81 ++++++++++++++++++++++++++++++++----- partials/index/Standard.njk | 47 ++++++++++----------- template/package.json.njk | 1 - template/src/hooks.ts | 3 -- 4 files changed, 95 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index ee976654c..ce3cffafd 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,79 @@ -

Typescript NATS template

+

TypeScript/Node.js NATS template

- This is a typescript NATS template for the AsyncAPI generator. + This is a TypeScript/Node.js NATS template for the AsyncAPI generator.

+The template is based on the [nats-ts](https://github.com/nats-io/nats.ts) library and can be used as both a TypeScript and Node.js library. + ## Requirements -* @asyncapi/generator v1.0.0+ +* @asyncapi/generator v1.0.0 + +Install the generator through [npm or run it from docker official installer](https://github.com/asyncapi/generator#install). + +## Example usage +The leading examples are both in TypeScript and in Node.js since this template can be used for both. The example code will be used later in the documentation for to explain the different features. + +### TypeScript + + +### Node.js +Given any AsyncAPI file (`AsyncAPI.yml`) first generate the client with the [AsyncAPI generator](https://github.com/asyncapi/generator) such as + +```bash +ag --install --output ./nats-client ./AsyncAPI.yml @asyncapi/ts-nats-template --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" +``` -Install the generator through [npm or run it from dockerofficial installer](https://github.com/asyncapi/generator) +Afterwards `cd` into the generated folder `nats-client` and run the commands `npm i` and `npm run build`. The generated NATS client is now ready to be used. To use the generated code either create a client wrapper such as the following file: + +```js +const GeneratedClient = require("./nats-client"); +const natsClient = new GeneratedClient.NatsAsyncApiClient(); +async function connect(){ + try{ + await natsClient.connect({url: "nats://demo.nats.io:4222", reconnectTimeWait: 1000, reconnect: true, maxReconnectAttempts: -1}); + }catch(e){ + console.log(e); + } +} +connect(); +module.exports = natsClient +``` + +or use it directly where needed. ## Features +* Supports wildcard channels. AsyncAPI describes the channel path to be defined as [RFC 6570 URI](https://www.asyncapi.com/docs/specifications/2.0.0/#a-name-channelsobject-a-channels-object). So a channel containing a wildcard needs to be defined as `smartylighting/streetlights/*`. This also works with parameters such as `smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured`, ensure to define the type of the parameter as a String if you want to use wildcards. +* Supports [test/mirror client](###test-client) for testing or other useful scenarios. +* This template can be used as a javascript library as well since the generated code works directly in node-js. Has not been tested as a pure javascript library. + +## Available events +[All the events from nats-ts](https://github.com/nats-io/nats.ts#notifications) library are supported. +### TypeScript example +### Node.js example +```js +const GeneratedClient = require("./nats-client"); +const natsClient = new GeneratedClient.NatsAsyncApiClient(); + +//Listen for the permissionError event from the nats-ts library +natsClient.on(Nats.AvailableEvents.permissionError, (e) => { + console.log("permissionError"); + console.log(e); +}); +``` ## Available Parameters -These are the available parameters available when you generate code with the template: +These are the available template parameters: |Parameter|Type|Description| |---|---|---| | generateTestClient | Boolean | Use this parameter to generate the [test client](###test-client). Add the following to the CLI when generating your code `--param "generateTestClient=true"` | promisifyReplyCallback | Boolean | Use this parameter to change from the default regular callback when using the request operation. Add the following to the CLI when generating your code `--param "promisifyReplyCallback=true"` ## Test Client -The test client is like a mirror client. It does everything the opposite, when you define a subscription operation it will generate a subscription operation in the test client. This is opposite to what the specification dictates. This client can be used to create integration tests etc. +The test client is like a mirror client. It does everything the opposite, when you define a subscription operation it will generate a subscription operation in the test client. This is opposite to what the specification dictates. This client can be used to create integration tests or other useful scenarios. ## Supported Content Types -The following payload types are supported, this is limited to the underlying NATS typescript library: +The following payload types are supported, this is limited to the underlying NATS TypeScript library: * For binary payloads use: `binary` content type * For json payloads use: `json` content type @@ -30,10 +81,20 @@ The following payload types are supported, this is limited to the underlying NAT ## Client Hooks -The client support custom hooks used to control the flow of information outside the generated code. The hooks can be used to alter the payload before sending or after recieving any data i.e. encrypt, compress data, etc. +The client support custom hooks used to control the flow of information outside the generated code. The hooks can be used to alter the payload before sending or after recieving any data i.e. encrypt, compress data, etc. It is possible to register as many hooks as you want, however remember that after the first call subsequently calls will include the already changed data and not the original. These are the available hooks: |Hookname|Callback type|Description| |---|---|---| -| BeforeSendingData | (Message: any) => new data | Called before sending any data. -| RecievedData | (recieved data: any) => new data | Called after data is recieved. +| BeforeSendingData | (messageToSend: any) => any | Called before sending any data. +| RecievedData | (receivedData: any) => any | Called after data is recieved. + +### TypeScript example +```ts +import {Hooks, BeforeSendingDataHook} from './nats-client/hooks' +Hooks.getInstance().registerBeforeSendingData((messageToSend: any) => { + return "AlwaysThis"; +}); +``` + +### Node.js example diff --git a/partials/index/Standard.njk b/partials/index/Standard.njk index 7fbe9207a..06076bf54 100644 --- a/partials/index/Standard.njk +++ b/partials/index/Standard.njk @@ -22,7 +22,6 @@ import {default as {{ messageName | pascalCase }}Message} from "#messages/{{ mes import {fromSeed} from 'ts-nkeys'; import * as events from 'events'; export enum AvailableEvents { - connectionError = 'connectionError', permissionError = 'permissionError', close = 'close', connect = 'connect', @@ -39,7 +38,6 @@ export enum AvailableEvents { yield = 'yield' } export declare interface NatsAsyncApiTestClient { - on(event: AvailableEvents.connectionError, listener: (error: any) => void): this; on(event: AvailableEvents.permissionError, listener: (error: NatsError) => void): this; on(event: AvailableEvents.close, listener: (error: NatsError) => void): this; on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; @@ -72,27 +70,30 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ /** * Try to connect to the NATS server with the different payloads. */ - async connect(options : NatsConnectionOptions){ - this.options = this.setDefaultOptions(options); - try{ - {%- if asyncapi | containsBinaryPayload %} - this.options.payload = Payload.BINARY; - this.binaryClient = await connect(this.options); - this.chainEvents(this.binaryClient); - {%- endif %} - {%- if asyncapi | containsStringPayload %} - this.options.payload = Payload.STRING; - this.stringClient = await connect(this.options); - this.chainEvents(this.stringClient); - {%- endif %} - {%- if asyncapi | containsJsonPayload %} - this.options.payload = Payload.JSON; - this.jsonClient = await connect(this.options); - this.chainEvents(this.jsonClient); - {%- endif %} - }catch(e){ - this.emit(AvailableEvents.connectionError, e) - } + connect(options : NatsConnectionOptions): Promise{ + return new Promise(async (resolve: () => void, reject: (error: any) => void) => { + this.options = this.setDefaultOptions(options); + try{ + {%- if asyncapi | containsBinaryPayload %} + this.options.payload = Payload.BINARY; + this.binaryClient = await connect(this.options); + this.chainEvents(this.binaryClient); + {%- endif %} + {%- if asyncapi | containsStringPayload %} + this.options.payload = Payload.STRING; + this.stringClient = await connect(this.options); + this.chainEvents(this.stringClient); + {%- endif %} + {%- if asyncapi | containsJsonPayload %} + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); + {%- endif %} + resolve(); + }catch(e){ + reject(e); + } + }) } diff --git a/template/package.json.njk b/template/package.json.njk index 3028d223e..fee3fa37f 100644 --- a/template/package.json.njk +++ b/template/package.json.njk @@ -37,7 +37,6 @@ "dependencies": { "@types/klaw-sync": "^6.0.0", "@types/node": "13.9.5", - "klaw-sync": "6.0.0", "link-module-alias": "^1.2.0", "ts-nats": "1.2.4", "typescript": "3.4.3", diff --git a/template/src/hooks.ts b/template/src/hooks.ts index 51e71a158..321b9085c 100644 --- a/template/src/hooks.ts +++ b/template/src/hooks.ts @@ -1,6 +1,3 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as walkSync from 'klaw-sync'; export enum AvailableHooks { RecievedData = 'RecievedData', BeforeSendingData = 'BeforeSendingData' From dd12977b267dd0541efc173d8158494e89200953 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sun, 28 Jun 2020 20:03:03 +0200 Subject: [PATCH 052/110] Added defualt parameter values to the template. --- package.json | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 6ba04d427..6c1100b56 100644 --- a/package.json +++ b/package.json @@ -26,18 +26,24 @@ "mocha": "^7.1.1" }, "generator": { - "supportedProtocols": ["nats"], + "supportedProtocols": [ + "nats" + ], "parameters": { - "generateTestClient": { - "description": "Generate the test client", - "required": false - }, - "promisifyReplyCallback": { - "description": "Use promises as callbacks for reply operation", - "required": false - } + "generateTestClient": { + "description": "Generate the test client", + "default": "false", + "required": false + }, + "promisifyReplyCallback": { + "description": "Use promises as callbacks for reply operation", + "default": "false", + "required": false + } }, "generator": ">=0.50.0 <2.0.0", - "filters": [ "@asyncapi/generator-filters"] + "filters": [ + "@asyncapi/generator-filters" + ] } } From fb92331b7b3a318a4a0663299bb99fd62c7f3230 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sun, 28 Jun 2020 20:03:51 +0200 Subject: [PATCH 053/110] Added custom NatsTypescriptTemplateError. --- README.md | 2 +- filters/all.js | 9 +- partials/channel/Publish.njk | 27 ++-- partials/channel/Reply.njk | 122 +++++++++--------- partials/channel/Request.njk | 51 ++++---- partials/channel/Subscribe.njk | 43 +++--- partials/index/Publish.njk | 2 +- partials/index/Reply.njk | 4 +- partials/index/Request.njk | 2 +- partials/index/Standard.njk | 20 +-- partials/index/Subscribe.njk | 4 +- template/package.json.njk | 3 +- template/src/NatsTypescriptTemplateError.ts | 70 ++++++++++ template/src/channels/$$channel$$.ts.njk | 13 +- template/src/tests/testclient/index.ts.njk | 8 +- .../testchannels/$$channel$$.ts.njk | 9 +- template/tsconfig.json | 3 +- 17 files changed, 238 insertions(+), 154 deletions(-) create mode 100644 template/src/NatsTypescriptTemplateError.ts diff --git a/README.md b/README.md index ce3cffafd..da560b4cc 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ The following payload types are supported, this is limited to the underlying NAT ## Client Hooks -The client support custom hooks used to control the flow of information outside the generated code. The hooks can be used to alter the payload before sending or after recieving any data i.e. encrypt, compress data, etc. It is possible to register as many hooks as you want, however remember that after the first call subsequently calls will include the already changed data and not the original. +The generated client support custom hooks used to control the flow of information outside the generated code. The hooks can be used to alter the payload before sending or after recieving any data i.e. encrypt, compress data, etc. It is possible to register as many hooks as you want, however remember that after the first call subsequently calls will include the already changed data and not the original. Also when using these hooks you are responsible for complying with the content type for the message being changed. These are the available hooks: |Hookname|Callback type|Description| diff --git a/filters/all.js b/filters/all.js index 22e797332..a277488bc 100644 --- a/filters/all.js +++ b/filters/all.js @@ -1,6 +1,7 @@ const filter = module.exports; const _ = require('lodash'); + /** * Figure out if our message content type or default content type matches a given payload. * @param {*} messageContentType to check @@ -99,7 +100,6 @@ function pascalCase(string) { - filter.firstLowerCase = string => { return _.lowerFirst(string); } @@ -109,6 +109,13 @@ filter.firstUpperCase = string => { filter.pascalCase = string => { return pascalCase(string); } +filter.kebabCase = string => { + return _.kebabCase(string); +} + +filter.camelCase = string => { + return camelCase(string); +} diff --git a/partials/channel/Publish.njk b/partials/channel/Publish.njk index b26c2b6f0..8a214c5f4 100644 --- a/partials/channel/Publish.njk +++ b/partials/channel/Publish.njk @@ -9,20 +9,21 @@ export function publish( {% endif %} ): Promise { return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var dataToPublish : any = requestMessage; - for(let hook of publishDataHooks){ - dataToPublish = hook(dataToPublish); - } - nc.publish({{channelParameters | realizeChannelName(channelName)}}, dataToPublish); - resolve(); - }catch(e){ - reject(e); + try{ + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToPublish : any = requestMessage; + for(let hook of publishDataHooks){ + dataToPublish = hook(dataToPublish); } - }else{ - reject(new Error("Nats client is not connected")); + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + return; + } + try{ + nc.publish({{channelParameters | realizeChannelName(channelName)}}, dataToPublish); + resolve(); + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); } }); }; diff --git a/partials/channel/Reply.njk b/partials/channel/Reply.njk index adb5ca5c8..19a5342e0 100644 --- a/partials/channel/Reply.njk +++ b/partials/channel/Reply.njk @@ -1,86 +1,80 @@ {% macro reply(channelName, channelParameters, subscribtionMessage, publishMessage, server, params) %} export function reply( - onRequest: (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => + onRequest: (err?: NatsTypescriptTemplateError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{publishMessage.uid() | pascalCase}}Message{%-if params.promisifyReplyCallback | length %}>{%- endif %}, - onReplyError: (err: NatsError) => void, + onReplyError: (err: NatsTypescriptTemplateError) => void, nc: Client, {% if channelParameters | length %} {{channelParameters | realizeParametersForChannel}} {% endif %} ): Promise { return new Promise(async (resolve, reject) => { - if (nc) { - try { - let subscribeOptions: SubscriptionOptions = {}; - {%- if subscribtionMessage | hasNatsBindings %} - {%- if subscribtionMessage.bindings().nats().queue() | length %} - //If queue - subscribeOptions.queue = '{{subscribtionMessage.bindings().nats().queue().name()}}'; - {%- endif %} - {%- if subscribtionMessage.bindings().nats().unsubAfter() | length %} - //If unsubafter - subscribeOptions.max = {{subscribtionMessage.bindings().nats().unsubAfter()}}; - {%- endif %} - {%- endif %} + try { + let subscribeOptions: SubscriptionOptions = {}; + {%- if subscribtionMessage | hasNatsBindings %} + {%- if subscribtionMessage.bindings().nats().queue() | length %} + //If queue + subscribeOptions.queue = '{{subscribtionMessage.bindings().nats().queue().name()}}'; + {%- endif %} + {%- if subscribtionMessage.bindings().nats().unsubAfter() | length %} + //If unsubafter + subscribeOptions.max = {{subscribtionMessage.bindings().nats().unsubAfter()}}; + {%- endif %} + {%- endif %} - let subscription = nc.subscribe({{channelParameters | realizeChannelName(channelName)}}, {%- if params.promisifyReplyCallback | length %}async{%- endif %} (err, msg) => { - if (err) { - onRequest(err); - } else { - {%- if channelParameters | length %} - const unmodifiedChannel = {{channelName | realizeChannelNameWithoutParameters}} - const receivedTopicParameters = { - {%- set counter = 1 %} - {%- for parameterName, parameter in channelParameters %} - {{parameterName}} : msg.subject.slice(unmodifiedChannel.split("${{'{'+ parameterName+ '}'}}")[0].length, msg.subject.length-unmodifiedChannel.split("${{'{'+parameterName+'}'}}")[1].length){%- if counter < (channelParameters | length) %},{%- endif %} - {%- set counter = counter+1 %} - {%- endfor %} - } - {%- endif %} + let subscription = nc.subscribe({{channelParameters | realizeChannelName(channelName)}}, {%- if params.promisifyReplyCallback | length %}async{%- endif %} (err, msg) => { + if (err) { + onRequest(err); + } else { + {%- if channelParameters | length %} + const unmodifiedChannel = {{channelName | realizeChannelNameWithoutParameters}} + const receivedTopicParameters = { + {%- set counter = 1 %} + {%- for parameterName, parameter in channelParameters %} + {{parameterName}} : msg.subject.slice(unmodifiedChannel.split("${{'{'+ parameterName+ '}'}}")[0].length, msg.subject.length-unmodifiedChannel.split("${{'{'+parameterName+'}'}}")[1].length){%- if counter < (channelParameters | length) %},{%- endif %} + {%- set counter = counter+1 %} + {%- endfor %} + } + {%- endif %} + try { let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); var processedDataReceived : any = msg.data; for(let hook of receivedDataHooks){ processedDataReceived = hook(processedDataReceived); } - let requestData = {{subscribtionMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); - let responseObject = {%-if params.promisifyReplyCallback | length %}await{%- endif %} onRequest(undefined, requestData{% if channelParameters | length %}, - {%- set counter = 1 %} - {%- for parameterName, parameter in channelParameters %} - receivedTopicParameters['{{parameterName}}']{%- if counter < (channelParameters | length) %},{%- endif %} - {%- set counter = counter+1 %} - {%- endfor %} - {%- endif %}); - if (msg.reply) { - try { - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var dataToPublish : any = responseObject; - for(let hook of publishDataHooks){ - dataToPublish = hook(dataToPublish); - } - nc.publish(msg.reply, dataToPublish); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { + } catch (e) { + onReplyError(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)) + return; + } + let requestData = {{subscribtionMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); + let responseObject = {%-if params.promisifyReplyCallback | length %}await{%- endif %} onRequest(undefined, requestData{% if channelParameters | length %}, + {%- set counter = 1 %} + {%- for parameterName, parameter in channelParameters %} + receivedTopicParameters['{{parameterName}}']{%- if counter < (channelParameters | length) %},{%- endif %} + {%- set counter = counter+1 %} + {%- endfor %} + {%- endif %}); + if (msg.reply) { + try { + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToPublish : any = responseObject; + for(let hook of publishDataHooks){ + dataToPublish = hook(dataToPublish); } + nc.publish(msg.reply, dataToPublish); + } catch (e) { + onReplyError(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)) } + } else { + let error = new NatsTypescriptTemplateError('Expected request to need a reply, did not..', '000'); + onReplyError(error) } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); } }) } diff --git a/partials/channel/Request.njk b/partials/channel/Request.njk index 451f77b03..31fc81dbb 100644 --- a/partials/channel/Request.njk +++ b/partials/channel/Request.njk @@ -8,32 +8,33 @@ export function request( {% endif %} ): Promise<{{subscribtionMessage.uid() | pascalCase}}Message> { return new Promise<{{subscribtionMessage.uid() | pascalCase}}Message>(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived : any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - resolve({{subscribtionMessage.uid() | pascalCase}}Message.toMessage(processedDataReceived)); - } - }, { max: 1 }); - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var requestData : any = requestMessage; - for(let hook of publishDataHooks){ - requestData = hook(requestData); - } - nc.publish({{channelParameters | realizeChannelName(channelName)}}, requestData, inbox); - }catch(e){ - reject(e); + try { + let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var requestData : any = requestMessage; + for(let hook of publishDataHooks){ + requestData = hook(requestData); } - } else { - reject(new Error("Nats client is not connected")); + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + return; + } + let msg; + try { + msg = await nc.request({{channelParameters | realizeChannelName(channelName)}}, undefined, requestData) + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); + return; + } + try{ + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived: any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + let publishedData = {{subscribtionMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); + resolve(publishedData); + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); } }) } diff --git a/partials/channel/Subscribe.njk b/partials/channel/Subscribe.njk index 4643ca2e2..81ef579b8 100644 --- a/partials/channel/Subscribe.njk +++ b/partials/channel/Subscribe.njk @@ -1,29 +1,29 @@ {% macro subscribe(channelName, channelParameters, subscribtionMessage, server) %} export function subscribe( - onDataCallback : (err?: NatsError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void, + onDataCallback : (err?: NatsTypescriptTemplateError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void, nc: Client, {% if channelParameters | length %} {{channelParameters | realizeParametersForChannel}} {% endif %} ): Promise { return new Promise(async (resolve, reject) => { - try{ - let subscribeOptions: SubscriptionOptions = {}; - {%- if subscribtionMessage | hasNatsBindings %} - {%- if subscribtionMessage.bindings().nats().queue() | length %} - //If queue - subscribeOptions.queue = '{{subscribtionMessage.bindings().nats().queue().name()}}'; - {%- endif %} - {%- if subscribtionMessage.bindings().nats().unsubAfter() | length %} - //If unsubafter - subscribeOptions.max = {{subscribtionMessage.bindings().nats().unsubAfter()}}; - {%- endif %} - {%- endif %} + let subscribeOptions: SubscriptionOptions = {}; + {%- if subscribtionMessage | hasNatsBindings %} + {%- if subscribtionMessage.bindings().nats().queue() | length %} + //If queue + subscribeOptions.queue = '{{subscribtionMessage.bindings().nats().queue().name()}}'; + {%- endif %} + {%- if subscribtionMessage.bindings().nats().unsubAfter() | length %} + //If unsubafter + subscribeOptions.max = {{subscribtionMessage.bindings().nats().unsubAfter()}}; + {%- endif %} + {%- endif %} + try{ let subscription = nc.subscribe({{channelParameters | realizeChannelName(channelName)}}, (err, msg) => { if(err){ - onDataCallback(err); + onDataCallback(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, err)); }else{ {%- if channelParameters | length %} const unmodifiedChannel = {{channelName | realizeChannelNameWithoutParameters}} @@ -35,10 +35,15 @@ export function subscribe( {%- endfor %} } {%- endif %} - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived: any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); + try{ + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived: any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + return; } let publishedData = {{subscribtionMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); onDataCallback(undefined, publishedData{% if channelParameters | length %}, @@ -52,7 +57,7 @@ export function subscribe( }, subscribeOptions); resolve(subscription); }catch(e){ - reject(e); + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); } }) } diff --git a/partials/index/Publish.njk b/partials/index/Publish.njk index 4e6468ec9..0f8dfd36f 100644 --- a/partials/index/Publish.njk +++ b/partials/index/Publish.njk @@ -22,7 +22,7 @@ ,{{channelParameters | realizeParametersForChannelWithoutType}} {% endif %}); }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel {{ channelName | camelCase }}')) + return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); } } {% endmacro %} diff --git a/partials/index/Reply.njk b/partials/index/Reply.njk index f79034fcf..1e7d184e7 100644 --- a/partials/index/Reply.njk +++ b/partials/index/Reply.njk @@ -5,7 +5,7 @@ * @param onRequest Called when request recieved. * @param onReplyError Called when it was not possible to send the reply. */ - public replyTo{{channelName | pascalCase }}(onRequest : (err?: NatsError, msg?: {{ subscribeMessage.uid() | pascalCase }}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{ publishMessage.uid() | pascalCase }}Message{%- if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError : (err: NatsError) => void + public replyTo{{channelName | pascalCase }}(onRequest : (err?: NatsTypescriptTemplateError, msg?: {{ subscribeMessage.uid() | pascalCase }}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{ publishMessage.uid() | pascalCase }}Message{%- if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError : (err: NatsTypescriptTemplateError) => void {% if channelParameters | length %} ,{{channelParameters | realizeParametersForChannel}} {% endif %}): Promise { @@ -25,7 +25,7 @@ ,{{channelParameters | realizeParametersForChannelWithoutType}} {% endif %}); }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel {{ channelName | camelCase }}')) + return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); } } {% endmacro %} diff --git a/partials/index/Request.njk b/partials/index/Request.njk index a2c98f429..3503a5f54 100644 --- a/partials/index/Request.njk +++ b/partials/index/Request.njk @@ -23,7 +23,7 @@ ,{{channelParameters | realizeParametersForChannelWithoutType}} {% endif %}); }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel {{ channelName | camelCase }}')) + return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); } } {% endmacro %} diff --git a/partials/index/Standard.njk b/partials/index/Standard.njk index 06076bf54..3c5590ede 100644 --- a/partials/index/Standard.njk +++ b/partials/index/Standard.njk @@ -12,6 +12,8 @@ import { ServerInfo } from 'ts-nats'; +import {ErrorCode, NatsTypescriptTemplateError} from '#NatsTypescriptTemplateError'; +export {ErrorCode, NatsTypescriptTemplateError} {%- for channelName, _ in asyncapi.channels() %} import * as {{ channelName | camelCase }}Channel from "#testchannels/{{ channelName | pascalCase | firstUpperCase }}"; {%- endfor %} @@ -38,12 +40,12 @@ export enum AvailableEvents { yield = 'yield' } export declare interface NatsAsyncApiTestClient { - on(event: AvailableEvents.permissionError, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.close, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.permissionError, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.close, listener: (error: NatsTypescriptTemplateError) => void): this; on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; - on(event: AvailableEvents.connecting, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.connecting, listener: (error: NatsTypescriptTemplateError) => void): this; on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; - on(event: AvailableEvents.error, listener: (error: NatsError) => void): this; + on(event: AvailableEvents.error, listener: (error: NatsTypescriptTemplateError) => void): this; on(event: AvailableEvents.pingcount, listener: () => void): this; on(event: AvailableEvents.pingtimer, listener: () => void): this; on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; @@ -91,7 +93,7 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ {%- endif %} resolve(); }catch(e){ - reject(e); + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); } }) } @@ -114,22 +116,22 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ private chainEvents(ns: Client){ ns.on('permissionError', (e: NatsError) => { - this.emit(AvailableEvents.permissionError, e) + this.emit(AvailableEvents.permissionError, NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)) }); ns.on('close', (e: NatsError) => { - this.emit(AvailableEvents.close, e) + this.emit(AvailableEvents.close, NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)) }); ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { this.emit(AvailableEvents.connect, connection, serverURL, info) }); - ns.on('connecting', (serverURL: NatsError) => { + ns.on('connecting', (serverURL: string) => { this.emit(AvailableEvents.connecting, serverURL) }); ns.on('disconnect', (serverURL: string) => { this.emit(AvailableEvents.disconnect, serverURL) }); ns.on('error', (e: NatsError) => { - this.emit(AvailableEvents.error, e) + this.emit(AvailableEvents.error, NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)) }); ns.on('pingcount', () => { this.emit(AvailableEvents.pingcount) diff --git a/partials/index/Subscribe.njk b/partials/index/Subscribe.njk index fa50ef4e3..81b9b6c3a 100644 --- a/partials/index/Subscribe.njk +++ b/partials/index/Subscribe.njk @@ -4,7 +4,7 @@ * {{messageDescription}} * @param onDataCallback Called when message recieved. */ - public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsError, msg?: {{ message.uid() | pascalCase }}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void {% if channelParameters | length %} + public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsTypescriptTemplateError, msg?: {{ message.uid() | pascalCase }}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void {% if channelParameters | length %} ,{{channelParameters | realizeParametersForChannel}} {% endif %}): Promise { {%- if message.contentType() | isBinaryPayload(defaultContentType) %} @@ -22,7 +22,7 @@ ,{{channelParameters | realizeParametersForChannelWithoutType}} {% endif %}); }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel {{ channelName | camelCase }}')) + return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); } } {% endmacro %} diff --git a/template/package.json.njk b/template/package.json.njk index fee3fa37f..99c087d16 100644 --- a/template/package.json.njk +++ b/template/package.json.njk @@ -32,7 +32,8 @@ "#channels": "dist/channels/", "#testchannels": "dist/tests/testclient/testchannels/", "#hooks": "dist/hooks.js", - "#testclient": "dist/tests/testclient/index.js" + "#testclient": "dist/tests/testclient/index.js", + "#NatsTypescriptTemplateError": "dist/NatsTypescriptTemplateError.js" }, "dependencies": { "@types/klaw-sync": "^6.0.0", diff --git a/template/src/NatsTypescriptTemplateError.ts b/template/src/NatsTypescriptTemplateError.ts new file mode 100644 index 000000000..07ad37c3e --- /dev/null +++ b/template/src/NatsTypescriptTemplateError.ts @@ -0,0 +1,70 @@ + +import * as util from 'util'; + +export enum ErrorCode { + NOT_CONNECTED = 'NOT_CONNECTED', + INTERNAL_NATS_TS_ERROR = 'INTERNAL_NATS_TS_ERROR', + HOOK_ERROR = 'HOOK_ERROR' +} + +/** @internal **/ +export class Messages { + static messages = new Messages(); + messages: { [key: string]: string } = {}; + + private constructor() { + this.messages[ErrorCode.NOT_CONNECTED] = 'The client is not connected'; + this.messages[ErrorCode.INTERNAL_NATS_TS_ERROR] = 'An error occured while trying to use the Nats Typescript library'; + this.messages[ErrorCode.HOOK_ERROR] = 'An error occured while trying to call one of the hooks.'; + } + + static getMessage(s: string): string { + return Messages.messages.getMessage(s); + } + + getMessage(s: string): string { + let v = this.messages[s]; + if (!v) { + v = s; + } + return v; + } +} +export class NatsTypescriptTemplateError implements Error { + + name: string; + message: string; + code: string; + chainedError?: Error; + + /** + * @param {String} message + * @param {String} code + * @param {Error} [chainedError] + * @constructor + * + * @api private + * @internal + */ + constructor(message: string, code: string, chainedError?: Error) { + Error.captureStackTrace(this, this.constructor); + this.name = 'NatsTypescriptTemplateError'; + this.message = message; + this.code = code; + this.chainedError = chainedError; + + util.inherits(NatsTypescriptTemplateError, Error); + } + + /** + * @param code + * @param chainedError + * @api private + * @internal + */ + static errorForCode(code: string, chainedError?: Error): NatsTypescriptTemplateError { + let m = Messages.getMessage(code); + return new NatsTypescriptTemplateError(m, code, chainedError); + } +} + diff --git a/template/src/channels/$$channel$$.ts.njk b/template/src/channels/$$channel$$.ts.njk index cfa587e23..ef8e4483e 100644 --- a/template/src/channels/$$channel$$.ts.njk +++ b/template/src/channels/$$channel$$.ts.njk @@ -10,21 +10,22 @@ import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '#messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' {%- endif %} import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {ErrorCode, NatsTypescriptTemplateError} from '#NatsTypescriptTemplateError'; import { Hooks } from '#hooks'; {%- if channel | isRequestReply %} - {%- if channel | isRequester %} - {{ request(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} - {%- endif %} {%- if channel | isReplier %} - {{ reply(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), params) }} + {{ reply(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server), params) }} + {%- endif %} + {%- if channel | isRequester %} + {{ request(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server)) }} {%- endif %} {%- endif %} {%- if channel | isPubsub %} {%- if channel.hasSubscribe() %} - {{ subscribe(channelName, channel.parameters(), channel.subscribe().message(0), asyncapi.server(params.server)) }} + {{ publish(channelName, channel.parameters(), channel.subscribe().message(0), asyncapi.server(params.server)) }} {%- endif %} {%- if channel.hasPublish() %} - {{ publish(channelName, channel.parameters(), channel.publish().message(0), asyncapi.server(params.server)) }} + {{ subscribe(channelName, channel.parameters(), channel.publish().message(0), asyncapi.server(params.server)) }} {%- endif %} {%- endif %} diff --git a/template/src/tests/testclient/index.ts.njk b/template/src/tests/testclient/index.ts.njk index 41a1e78e0..eeb3f558f 100644 --- a/template/src/tests/testclient/index.ts.njk +++ b/template/src/tests/testclient/index.ts.njk @@ -8,19 +8,19 @@ {%- for channelName, channel in asyncapi.channels() %} {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{request(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters())}} + {{ request(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- if channel | isReplier %} - {{reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters(), params)}} + {{ reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters(), params)}} {%- endif %} {%- endif %} {%- if channel | isPubsub %} {%- if channel.hasSubscribe() %} - {{subscribe(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.description(), channel.parameters())}} + {{ subscribe(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- if channel.hasPublish() %} - {{publish(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.description(), channel.parameters())}} + {{ publish(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- endif %} {%- endfor %} diff --git a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk index a76dc230f..f6f645253 100644 --- a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk +++ b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk @@ -10,23 +10,24 @@ import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '#messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' {%- endif %} import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {ErrorCode, NatsTypescriptTemplateError} from '#NatsTypescriptTemplateError'; import { Hooks } from '#hooks'; {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{ reply(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server), params) }} + {{ request(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} {%- endif %} {%- if channel | isReplier %} - {{ request(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server)) }} + {{ reply(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), params) }} {%- endif %} {%- endif %} {%- if channel | isPubsub %} {%- if channel.hasSubscribe() %} - {{ publish(channelName, channel.parameters(), channel.subscribe().message(0), asyncapi.server(params.server)) }} + {{ subscribe(channelName, channel.parameters(), channel.subscribe().message(0), asyncapi.server(params.server)) }} {%- endif %} {%- if channel.hasPublish() %} - {{ subscribe(channelName, channel.parameters(), channel.publish().message(0), asyncapi.server(params.server)) }} + {{ publish(channelName, channel.parameters(), channel.publish().message(0), asyncapi.server(params.server)) }} {%- endif %} {%- endif %} diff --git a/template/tsconfig.json b/template/tsconfig.json index b1d6a9fac..b09ff54de 100644 --- a/template/tsconfig.json +++ b/template/tsconfig.json @@ -17,7 +17,8 @@ "#testchannels/*": ["tests/testclient/testchannels/*"], "#hooks": ["hooks"], "#testclient": ["tests/testclient/index"], - "#client": ["index"] + "#client": ["index"], + "#NatsTypescriptTemplateError": ["NatsTypescriptTemplateError"] } }, "include": ["src"], From ccde01254a5ac0ee0986b84b587f695a7fe8abc1 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 29 Jun 2020 21:21:52 +0200 Subject: [PATCH 054/110] Fixed some problems with the generation. --- partials/channel/Reply.njk | 2 +- partials/index/Reply.njk | 7 +- partials/index/Standard.njk | 97 ++++++++----------- template/README.md.njk | 1 - template/src/channels/$$channel$$.ts.njk | 8 +- template/src/index.ts.njk | 70 ++++++++++++- template/src/tests/testclient/index.ts.njk | 65 ++++++++++++- .../testchannels/$$channel$$.ts.njk | 4 +- 8 files changed, 181 insertions(+), 73 deletions(-) diff --git a/partials/channel/Reply.njk b/partials/channel/Reply.njk index 19a5342e0..266c1fc14 100644 --- a/partials/channel/Reply.njk +++ b/partials/channel/Reply.njk @@ -32,7 +32,7 @@ export function reply( const receivedTopicParameters = { {%- set counter = 1 %} {%- for parameterName, parameter in channelParameters %} - {{parameterName}} : msg.subject.slice(unmodifiedChannel.split("${{'{'+ parameterName+ '}'}}")[0].length, msg.subject.length-unmodifiedChannel.split("${{'{'+parameterName+'}'}}")[1].length){%- if counter < (channelParameters | length) %},{%- endif %} + {{parameterName}} : msg.subject.slice(unmodifiedChannel.split("{{'{'+ parameterName+ '}'}}")[0].length, msg.subject.length-unmodifiedChannel.split("{{'{'+parameterName+'}'}}")[1].length){%- if counter < (channelParameters | length) %},{%- endif %} {%- set counter = counter+1 %} {%- endfor %} } diff --git a/partials/index/Reply.njk b/partials/index/Reply.njk index 1e7d184e7..143f71172 100644 --- a/partials/index/Reply.njk +++ b/partials/index/Reply.njk @@ -5,7 +5,12 @@ * @param onRequest Called when request recieved. * @param onReplyError Called when it was not possible to send the reply. */ - public replyTo{{channelName | pascalCase }}(onRequest : (err?: NatsTypescriptTemplateError, msg?: {{ subscribeMessage.uid() | pascalCase }}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{ publishMessage.uid() | pascalCase }}Message{%- if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError : (err: NatsTypescriptTemplateError) => void + public replyTo{{channelName | pascalCase }}( + onRequest : ( + err?: NatsTypescriptTemplateError, + msg?: {{ subscribeMessage.uid() | pascalCase }}Message + {%- if channelParameters | length %},{{channelParameters | realizeParametersForChannel(false)}}{% endif %} + ) => {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{ publishMessage.uid() | pascalCase }}Message{%- if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError : (err: NatsTypescriptTemplateError) => void {% if channelParameters | length %} ,{{channelParameters | realizeParametersForChannel}} {% endif %}): Promise { diff --git a/partials/index/Standard.njk b/partials/index/Standard.njk index 3c5590ede..4fc196a0a 100644 --- a/partials/index/Standard.njk +++ b/partials/index/Standard.njk @@ -1,61 +1,6 @@ {% macro standard(asyncapi) %} -import { - Client, - NatsConnectionOptions, - connect, - Payload, - NatsError, - Subscription, - ServersChangedEvent, - SubEvent, - ServerInfo - } from 'ts-nats'; -import {ErrorCode, NatsTypescriptTemplateError} from '#NatsTypescriptTemplateError'; -export {ErrorCode, NatsTypescriptTemplateError} -{%- for channelName, _ in asyncapi.channels() %} -import * as {{ channelName | camelCase }}Channel from "#testchannels/{{ channelName | pascalCase | firstUpperCase }}"; -{%- endfor %} - -{%- for messageName, _ in asyncapi.allMessages() %} -import {default as {{ messageName | pascalCase }}Message} from "#messages/{{ messageName | pascalCase }}"; -{%- endfor %} -import {fromSeed} from 'ts-nkeys'; -import * as events from 'events'; -export enum AvailableEvents { - permissionError = 'permissionError', - close = 'close', - connect = 'connect', - connecting = 'connecting', - disconnect = 'disconnect', - error = 'error', - pingcount = 'pingcount', - pingtimer = 'pingtimer', - reconnect = 'reconnect', - reconnecting = 'reconnecting', - serversChanged = 'serversChanged', - subscribe = 'subscribe', - unsubscribe = 'unsubscribe', - yield = 'yield' -} -export declare interface NatsAsyncApiTestClient { - on(event: AvailableEvents.permissionError, listener: (error: NatsTypescriptTemplateError) => void): this; - on(event: AvailableEvents.close, listener: (error: NatsTypescriptTemplateError) => void): this; - on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; - on(event: AvailableEvents.connecting, listener: (error: NatsTypescriptTemplateError) => void): this; - on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; - on(event: AvailableEvents.error, listener: (error: NatsTypescriptTemplateError) => void): this; - on(event: AvailableEvents.pingcount, listener: () => void): this; - on(event: AvailableEvents.pingtimer, listener: () => void): this; - on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; - on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; - on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; - on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; - on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; - on(event: AvailableEvents.yield, listener: () => void): this; -} -export class NatsAsyncApiTestClient extends events.EventEmitter{ public jsonClient?: Client; public stringClient?: Client; public binaryClient?: Client; @@ -68,7 +13,6 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ constructor() { super(); } - /** * Try to connect to the NATS server with the different payloads. */ @@ -158,10 +102,47 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ this.emit(AvailableEvents.yield) }); } + + /** + * Try to connect to the NATS server with user credentials + */ + async connectWithUserCreds(userCreds: string, options?: NatsConnectionOptions){ + if(!options){ + options = {}; + } + options.userCreds = userCreds; + await this.connect(options); + } + /** + * Try to connect to the NATS server with user and password + */ + async connectWithUserPass(user: string, pass: string, options?: NatsConnectionOptions){ + if(!options){ + options = {}; + } + options.user = user; + options.pass = pass; + await this.connect(options); + } + + /** + * Try to connect to the NATS server which has no authentication + */ + async connectToHost(host: string, options?: NatsConnectionOptions){ + if(!options){ + options = {}; + } + options.servers = [host]; + await this.connect(options); + } + /** * Try to connect to the NATS server with nkey authentication */ - async connectWithNkey(options : NatsConnectionOptions, publicNkey: string, seed: string){ + async connectWithNkey(publicNkey: string, seed: string, options?: NatsConnectionOptions){ + if(!options){ + options = {}; + } options.nkey = publicNkey; options.nonceSigner = (nonce: string): Buffer => { const sk = fromSeed(Buffer.from(seed)); @@ -169,6 +150,7 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ } await this.connect(options); } + /** * Set the default options based on the AsyncAPI file. * @param options to set @@ -178,5 +160,4 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ options.encoding = 'utf8'; return options; } - {% endmacro %} \ No newline at end of file diff --git a/template/README.md.njk b/template/README.md.njk index 54c11a905..c17b3c819 100644 --- a/template/README.md.njk +++ b/template/README.md.njk @@ -3,6 +3,5 @@ {{ asyncapi.info().description() | safe }} - Available nats encodings: https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings diff --git a/template/src/channels/$$channel$$.ts.njk b/template/src/channels/$$channel$$.ts.njk index ef8e4483e..394b7af97 100644 --- a/template/src/channels/$$channel$$.ts.njk +++ b/template/src/channels/$$channel$$.ts.njk @@ -13,11 +13,11 @@ import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 't import {ErrorCode, NatsTypescriptTemplateError} from '#NatsTypescriptTemplateError'; import { Hooks } from '#hooks'; {%- if channel | isRequestReply %} - {%- if channel | isReplier %} - {{ reply(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server), params) }} - {%- endif %} {%- if channel | isRequester %} - {{ request(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server)) }} + {{ request(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} + {%- endif %} + {%- if channel | isReplier %} + {{ reply(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), params) }} {%- endif %} {%- endif %} diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index 078a4cd89..8bac9d041 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -4,15 +4,79 @@ {%- from "../../partials/index/Request.njk" import request %} {%- from "../../partials/index/Subscribe.njk" import subscribe %} {%- from "../../partials/index/Standard.njk" import standard %} - {{standard(asyncapi)}} + + +import {fromSeed} from 'ts-nkeys'; +import {AvailableHooks, RecievedDataHook, BeforeSendingDataHook, Hooks} from '#hooks'; +export {AvailableHooks, RecievedDataHook, BeforeSendingDataHook, Hooks} +import * as TestClient from '#testclient'; +export {% raw %}{{% endraw %} TestClient {% raw %}}{% endraw %}; +import {ErrorCode, NatsTypescriptTemplateError} from '#NatsTypescriptTemplateError'; +export {ErrorCode, NatsTypescriptTemplateError} +import { + Client, + NatsConnectionOptions, + connect, + Payload, + NatsError, + Subscription, + ServersChangedEvent, + SubEvent, + ServerInfo + } from 'ts-nats'; + +{%- for channelName, _ in asyncapi.channels() %} +import * as {{ channelName | camelCase }}Channel from "#channels/{{ channelName | pascalCase | firstUpperCase }}"; +export {% raw %}{{% endraw %}{{ channelName | camelCase }}Channel}; +{%- endfor %} + +{%- for messageName, _ in asyncapi.allMessages() %} +import {default as {{ messageName | pascalCase }}Message} from "#messages/{{ messageName | pascalCase }}"; +export {% raw %}{{% endraw %}{{ messageName | pascalCase }}Message}; +{%- endfor %} +import * as events from 'events'; +export enum AvailableEvents { + permissionError = 'permissionError', + close = 'close', + connect = 'connect', + connecting = 'connecting', + disconnect = 'disconnect', + error = 'error', + pingcount = 'pingcount', + pingtimer = 'pingtimer', + reconnect = 'reconnect', + reconnecting = 'reconnecting', + serversChanged = 'serversChanged', + subscribe = 'subscribe', + unsubscribe = 'unsubscribe', + yield = 'yield' +} +export declare interface NatsAsyncApiClient { + on(event: AvailableEvents.permissionError, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.close, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; + on(event: AvailableEvents.connecting, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.error, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.pingcount, listener: () => void): this; + on(event: AvailableEvents.pingtimer, listener: () => void): this; + on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; + on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; + on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.yield, listener: () => void): this; +} +export class NatsAsyncApiClient extends events.EventEmitter{ + {{standard(asyncapi)}} {%- for channelName, channel in asyncapi.channels() %} {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{reply(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters(), params)}} + {{request(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- if channel | isReplier %} - {{request(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters())}} + {{reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters(), params)}} {%- endif %} {%- endif %} diff --git a/template/src/tests/testclient/index.ts.njk b/template/src/tests/testclient/index.ts.njk index eeb3f558f..d20a54e9a 100644 --- a/template/src/tests/testclient/index.ts.njk +++ b/template/src/tests/testclient/index.ts.njk @@ -3,15 +3,74 @@ {%- from "../../../../partials/index/Reply.njk" import reply %} {%- from "../../../../partials/index/Request.njk" import request %} {%- from "../../../../partials/index/Subscribe.njk" import subscribe %} -{%- from "../../../../partials/index/Standard.njk" import standard %} +{%- from "../../partials/index/Standard.njk" import standard %} + +import {fromSeed} from 'ts-nkeys'; +import {ErrorCode, NatsTypescriptTemplateError} from '#NatsTypescriptTemplateError'; +import { + Client, + NatsConnectionOptions, + connect, + Payload, + NatsError, + Subscription, + ServersChangedEvent, + SubEvent, + ServerInfo + } from 'ts-nats'; + +{%- for channelName, _ in asyncapi.channels() %} +import * as {{ channelName | camelCase }}Channel from "#testchannels/{{ channelName | pascalCase | firstUpperCase }}"; +export {% raw %}{{% endraw %}{{ channelName | camelCase }}Channel}; +{%- endfor %} + +{%- for messageName, _ in asyncapi.allMessages() %} +import {default as {{ messageName | pascalCase }}Message} from "#messages/{{ messageName | pascalCase }}"; +export {% raw %}{{% endraw %}{{ messageName | pascalCase }}Message}; +{%- endfor %} +import * as events from 'events'; +export enum AvailableEvents { + permissionError = 'permissionError', + close = 'close', + connect = 'connect', + connecting = 'connecting', + disconnect = 'disconnect', + error = 'error', + pingcount = 'pingcount', + pingtimer = 'pingtimer', + reconnect = 'reconnect', + reconnecting = 'reconnecting', + serversChanged = 'serversChanged', + subscribe = 'subscribe', + unsubscribe = 'unsubscribe', + yield = 'yield' +} +export declare interface NatsAsyncApiTestClient { + on(event: AvailableEvents.permissionError, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.close, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; + on(event: AvailableEvents.connecting, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.error, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.pingcount, listener: () => void): this; + on(event: AvailableEvents.pingtimer, listener: () => void): this; + on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; + on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; + on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.yield, listener: () => void): this; +} +export class NatsAsyncApiTestClient extends events.EventEmitter{ + {{standard(asyncapi)}} {%- for channelName, channel in asyncapi.channels() %} {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{ request(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters())}} + {{ reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters(), params)}} {%- endif %} {%- if channel | isReplier %} - {{ reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters(), params)}} + {{ request(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- endif %} diff --git a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk index f6f645253..f72c10e77 100644 --- a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk +++ b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk @@ -16,10 +16,10 @@ import { Hooks } from '#hooks'; {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{ request(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} + {{ reply(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), params) }} {%- endif %} {%- if channel | isReplier %} - {{ reply(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), params) }} + {{ request(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} {%- endif %} {%- endif %} From 1fde7f23da4f2471cfffd1d7fb2d1ee452ccd10d Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 2 Jul 2020 01:29:19 +0200 Subject: [PATCH 055/110] Added export of schemas. Changed to correct operations. --- filters/all.js | 5 +++++ partials/channel/Reply.njk | 16 ++++++++-------- partials/channel/Request.njk | 8 ++++---- partials/index/Reply.njk | 10 +++++----- partials/index/Request.njk | 10 +++++----- template/src/index.ts.njk | 7 +++++++ template/src/tests/testclient/index.ts.njk | 9 ++++++++- 7 files changed, 42 insertions(+), 23 deletions(-) diff --git a/filters/all.js b/filters/all.js index a277488bc..ae1e9ee2f 100644 --- a/filters/all.js +++ b/filters/all.js @@ -145,6 +145,11 @@ function toTsType(jsonSchemaType, property) { } filter.toTsType = toTsType +filter.objectSchema = (asyncapi) => { + const objectMap = {}; + asyncapi.allSchemas().forEach((schema, schemaId) => { if (schema.type() === 'object') objectMap[schemaId] = schema; }); + return objectMap; +} filter.realizeChannelName = (parameters, channelName) => { let returnString = '\`' + channelName + '\`'; returnString = returnString.replace(/\//g, `.`); diff --git a/partials/channel/Reply.njk b/partials/channel/Reply.njk index 266c1fc14..e4fe1d8d5 100644 --- a/partials/channel/Reply.njk +++ b/partials/channel/Reply.njk @@ -1,8 +1,8 @@ {% macro reply(channelName, channelParameters, subscribtionMessage, publishMessage, server, params) %} export function reply( - onRequest: (err?: NatsTypescriptTemplateError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => - {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{publishMessage.uid() | pascalCase}}Message{%-if params.promisifyReplyCallback | length %}>{%- endif %}, + onRequest: (err?: NatsTypescriptTemplateError, msg?: {{publishMessage.uid() | pascalCase}}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => + {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{subscribtionMessage.uid() | pascalCase}}Message{%-if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError: (err: NatsTypescriptTemplateError) => void, nc: Client, {% if channelParameters | length %} @@ -12,14 +12,14 @@ export function reply( return new Promise(async (resolve, reject) => { try { let subscribeOptions: SubscriptionOptions = {}; - {%- if subscribtionMessage | hasNatsBindings %} - {%- if subscribtionMessage.bindings().nats().queue() | length %} + {%- if publishMessage | hasNatsBindings %} + {%- if publishMessage.bindings().nats().queue() | length %} //If queue - subscribeOptions.queue = '{{subscribtionMessage.bindings().nats().queue().name()}}'; + subscribeOptions.queue = '{{publishMessage.bindings().nats().queue().name()}}'; {%- endif %} - {%- if subscribtionMessage.bindings().nats().unsubAfter() | length %} + {%- if publishMessage.bindings().nats().unsubAfter() | length %} //If unsubafter - subscribeOptions.max = {{subscribtionMessage.bindings().nats().unsubAfter()}}; + subscribeOptions.max = {{publishMessage.bindings().nats().unsubAfter()}}; {%- endif %} {%- endif %} @@ -47,7 +47,7 @@ export function reply( onReplyError(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)) return; } - let requestData = {{subscribtionMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); + let requestData = {{publishMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); let responseObject = {%-if params.promisifyReplyCallback | length %}await{%- endif %} onRequest(undefined, requestData{% if channelParameters | length %}, {%- set counter = 1 %} {%- for parameterName, parameter in channelParameters %} diff --git a/partials/channel/Request.njk b/partials/channel/Request.njk index 31fc81dbb..c846429da 100644 --- a/partials/channel/Request.njk +++ b/partials/channel/Request.njk @@ -1,13 +1,13 @@ {% macro request(channelName, channelParameters, publishMessage, subscribtionMessage, server) %} export function request( - requestMessage: {{publishMessage.uid() | pascalCase}}Message, + requestMessage: {{subscribtionMessage.uid() | pascalCase}}Message, nc: Client, {% if channelParameters | length %} {{channelParameters | realizeParametersForChannel}} {% endif %} - ): Promise<{{subscribtionMessage.uid() | pascalCase}}Message> { - return new Promise<{{subscribtionMessage.uid() | pascalCase}}Message>(async (resolve, reject) => { + ): Promise<{{publishMessage.uid() | pascalCase}}Message> { + return new Promise<{{publishMessage.uid() | pascalCase}}Message>(async (resolve, reject) => { try { let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); var requestData : any = requestMessage; @@ -31,7 +31,7 @@ export function request( for(let hook of receivedDataHooks){ processedDataReceived = hook(processedDataReceived); } - let publishedData = {{subscribtionMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); + let publishedData = {{publishMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); resolve(publishedData); }catch(e){ reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); diff --git a/partials/index/Reply.njk b/partials/index/Reply.njk index 143f71172..d25edb18f 100644 --- a/partials/index/Reply.njk +++ b/partials/index/Reply.njk @@ -8,19 +8,19 @@ public replyTo{{channelName | pascalCase }}( onRequest : ( err?: NatsTypescriptTemplateError, - msg?: {{ subscribeMessage.uid() | pascalCase }}Message + msg?: {{ publishMessage.uid() | pascalCase }}Message {%- if channelParameters | length %},{{channelParameters | realizeParametersForChannel(false)}}{% endif %} - ) => {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{ publishMessage.uid() | pascalCase }}Message{%- if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError : (err: NatsTypescriptTemplateError) => void + ) => {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{ subscribeMessage.uid() | pascalCase }}Message{%- if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError : (err: NatsTypescriptTemplateError) => void {% if channelParameters | length %} ,{{channelParameters | realizeParametersForChannel}} {% endif %}): Promise { - {%- if subscribeMessage.contentType() | isBinaryPayload(defaultContentType) %} + {%- if publishMessage.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; {%- endif %} - {%- if subscribeMessage.contentType() | isStringPayload(defaultContentType) %} + {%- if publishMessage.contentType() | isStringPayload(defaultContentType) %} const nc: Client = this.stringClient!; {%- endif %} - {%- if subscribeMessage.contentType() | isJsonPayload(defaultContentType) %} + {%- if publishMessage.contentType() | isJsonPayload(defaultContentType) %} const nc: Client = this.jsonClient!; {%- endif %} diff --git a/partials/index/Request.njk b/partials/index/Request.njk index 3503a5f54..cda451102 100644 --- a/partials/index/Request.njk +++ b/partials/index/Request.njk @@ -4,17 +4,17 @@ * {{messageDescription}} * @param requestMessage The request message to send. */ - public request{{channelName | pascalCase }}(requestMessage: {{ publishMessage.uid() | pascalCase }}Message + public request{{channelName | pascalCase }}(requestMessage: {{ subscribeMessage.uid() | pascalCase }}Message {% if channelParameters | length %} ,{{channelParameters | realizeParametersForChannel}} - {% endif %}): Promise<{{ subscribeMessage.uid() | pascalCase }}Message> { - {%- if publishMessage.contentType() | isBinaryPayload(defaultContentType) %} + {% endif %}): Promise<{{ publishMessage.uid() | pascalCase }}Message> { + {%- if subscribeMessage.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; {%- endif %} - {%- if publishMessage.contentType() | isStringPayload(defaultContentType) %} + {%- if subscribeMessage.contentType() | isStringPayload(defaultContentType) %} const nc: Client = this.stringClient!; {%- endif %} - {%- if publishMessage.contentType() | isJsonPayload(defaultContentType) %} + {%- if subscribeMessage.contentType() | isJsonPayload(defaultContentType) %} const nc: Client = this.jsonClient!; {%- endif %} if(nc){ diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index 8bac9d041..c7d4c61cb 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -35,6 +35,13 @@ export {% raw %}{{% endraw %}{{ channelName | camelCase }}Channel}; import {default as {{ messageName | pascalCase }}Message} from "#messages/{{ messageName | pascalCase }}"; export {% raw %}{{% endraw %}{{ messageName | pascalCase }}Message}; {%- endfor %} + +{%- for schemaId, _ in (asyncapi | objectSchema) %} +import {default as {{ schemaId | pascalCase }}Schema} from "#schemas/{{ schemaId | pascalCase }}"; +export {% raw %}{{% endraw %}{{ schemaId | pascalCase }}Schema }; +{%- endfor %} + + import * as events from 'events'; export enum AvailableEvents { permissionError = 'permissionError', diff --git a/template/src/tests/testclient/index.ts.njk b/template/src/tests/testclient/index.ts.njk index d20a54e9a..682d932a9 100644 --- a/template/src/tests/testclient/index.ts.njk +++ b/template/src/tests/testclient/index.ts.njk @@ -3,7 +3,7 @@ {%- from "../../../../partials/index/Reply.njk" import reply %} {%- from "../../../../partials/index/Request.njk" import request %} {%- from "../../../../partials/index/Subscribe.njk" import subscribe %} -{%- from "../../partials/index/Standard.njk" import standard %} +{%- from "../../../../partials/index/Standard.njk" import standard %} import {fromSeed} from 'ts-nkeys'; import {ErrorCode, NatsTypescriptTemplateError} from '#NatsTypescriptTemplateError'; @@ -28,6 +28,13 @@ export {% raw %}{{% endraw %}{{ channelName | camelCase }}Channel}; import {default as {{ messageName | pascalCase }}Message} from "#messages/{{ messageName | pascalCase }}"; export {% raw %}{{% endraw %}{{ messageName | pascalCase }}Message}; {%- endfor %} + +{%- for schemaId, _ in (asyncapi | objectSchema) %} +import {default as {{ schemaId | pascalCase }}Schema} from "#schemas/{{ schemaId | pascalCase }}"; +export {% raw %}{{% endraw %}{{ schemaId | pascalCase }}Schema }; +{%- endfor %} + + import * as events from 'events'; export enum AvailableEvents { permissionError = 'permissionError', From 45279743ee55ce1d38a2344d2d30db18e67a3f7b Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 2 Jul 2020 13:01:31 +0200 Subject: [PATCH 056/110] Ensure that property names are used as is. --- filters/all.js | 2 +- template/src/schema/$$objectSchema$$.ts.njk | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/filters/all.js b/filters/all.js index ae1e9ee2f..828254912 100644 --- a/filters/all.js +++ b/filters/all.js @@ -289,7 +289,7 @@ filter.schemaConstructorParameters = schema => { if (schema.properties() && schema.required()) { for(const [propertyName, property] of Object.entries(schema.properties())){ if(property.required()){ - returnString += `${camelCase(propertyName)}: ${toTsType(property.type(), property)},`; + returnString += `${propertyName}: ${toTsType(property.type(), property)},`; } } } diff --git a/template/src/schema/$$objectSchema$$.ts.njk b/template/src/schema/$$objectSchema$$.ts.njk index 527d6527f..b44f46ca9 100644 --- a/template/src/schema/$$objectSchema$$.ts.njk +++ b/template/src/schema/$$objectSchema$$.ts.njk @@ -18,7 +18,7 @@ {%- if schema.type() == "object" %} {%- for propertyName, property in schema.properties() %} - {{ propertyName | camelCase}}{% if not required or not property.required() %}?{% endif %}: {{ property.type() | toTsType(property) }} + {{ propertyName}}{% if not required or not property.required() %}?{% endif %}: {{ property.type() | toTsType(property) }} {%- endfor %} {%- elif schema.type() | length %} type: {{ schema.type() | toTsType }} @@ -54,7 +54,7 @@ {%- endmacro %} {%- macro setProperty(propertyName) %} - this.{{propertyName | camelCase}} = {{propertyName | camelCase}}; + this.{{propertyName}} = {{propertyName}}; {% endmacro %} From 9cca1fc9d7268f6818828805ee2082d553b7aa0f Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Tue, 7 Jul 2020 03:31:12 +0200 Subject: [PATCH 057/110] Removed the use of module alias, since this is not a finale module. --- filters/all.js | 6 +++--- hooks/filename-change.js | 1 - template/package.json.njk | 14 +------------- template/src/channels/$$channel$$.ts.njk | 8 ++++---- template/src/index.ts.njk | 12 ++++++------ .../{schema => schemas}/$$objectSchema$$.ts.njk | 0 template/src/tests/testclient/index.ts.njk | 8 ++++---- .../testclient/testchannels/$$channel$$.ts.njk | 8 ++++---- template/tsconfig.json | 12 +----------- 9 files changed, 23 insertions(+), 46 deletions(-) rename template/src/{schema => schemas}/$$objectSchema$$.ts.njk (100%) diff --git a/filters/all.js b/filters/all.js index 828254912..9efcafe90 100644 --- a/filters/all.js +++ b/filters/all.js @@ -138,9 +138,9 @@ function toTsType(jsonSchemaType, property) { if(property){ return property.uid() + 'Schema'; }else{ - return 'UndefinedObject'; + return 'any'; } - default: return 'Undefined'; + default: return 'any'; } } filter.toTsType = toTsType @@ -233,7 +233,7 @@ function genericImports(schema, imports) { } } if (schema.type() && schema.type() === "object"){ - imports[schema.uid()] = `import { default as ${pascalCase(schema.uid())}Schema } from '#schemas/${pascalCase(schema.uid())}';` + imports[schema.uid()] = `import { default as ${pascalCase(schema.uid())}Schema } from '../schemas/${pascalCase(schema.uid())}';` } return imports; } diff --git a/hooks/filename-change.js b/hooks/filename-change.js index 3b9ba8c05..deb5df816 100644 --- a/hooks/filename-change.js +++ b/hooks/filename-change.js @@ -4,7 +4,6 @@ module.exports = { 'setFileTemplateName': (generator, hookArguments) => { const currentFilename = hookArguments.originalFilename; let newFilename = filters.pascalCase(currentFilename) - return newFilename } }; \ No newline at end of file diff --git a/template/package.json.njk b/template/package.json.njk index 99c087d16..ddab3fde8 100644 --- a/template/package.json.njk +++ b/template/package.json.njk @@ -20,25 +20,13 @@ "types": "dist/index.d.ts", "scripts": { "watch": "tsc --watch", - "build": "tsc && npm run dopostinstall", + "build": "tsc", "start": "node src/api/index.js", - "dopostinstall": "link-module-alias", "test": "mocha -r ts-node/register tests/**/*.spec.ts" }, - "_moduleAliasIgnoreWarning": true, - "_moduleAliases": { - "#messages": "dist/messages/", - "#schemas": "dist/schema/", - "#channels": "dist/channels/", - "#testchannels": "dist/tests/testclient/testchannels/", - "#hooks": "dist/hooks.js", - "#testclient": "dist/tests/testclient/index.js", - "#NatsTypescriptTemplateError": "dist/NatsTypescriptTemplateError.js" - }, "dependencies": { "@types/klaw-sync": "^6.0.0", "@types/node": "13.9.5", - "link-module-alias": "^1.2.0", "ts-nats": "1.2.4", "typescript": "3.4.3", "ts-nkeys":"1.0.16" diff --git a/template/src/channels/$$channel$$.ts.njk b/template/src/channels/$$channel$$.ts.njk index 394b7af97..163c7043d 100644 --- a/template/src/channels/$$channel$$.ts.njk +++ b/template/src/channels/$$channel$$.ts.njk @@ -4,14 +4,14 @@ {%- from "../../../partials/channel/Request.njk" import request %} {%- from "../../../partials/channel/Subscribe.njk" import subscribe %} {%- if channel.hasPublish() %} -import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '#messages/{{ channel.publish().message(0).uid() | pascalCase}}' +import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '../messages/{{ channel.publish().message(0).uid() | pascalCase}}' {%- endif %} {%- if channel.hasSubscribe() %} -import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '#messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' +import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '../messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' {%- endif %} import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {ErrorCode, NatsTypescriptTemplateError} from '#NatsTypescriptTemplateError'; -import { Hooks } from '#hooks'; +import {ErrorCode, NatsTypescriptTemplateError} from '../NatsTypescriptTemplateError'; +import { Hooks } from '../hooks'; {%- if channel | isRequestReply %} {%- if channel | isRequester %} {{ request(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index c7d4c61cb..d359c9132 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -8,11 +8,11 @@ import {fromSeed} from 'ts-nkeys'; -import {AvailableHooks, RecievedDataHook, BeforeSendingDataHook, Hooks} from '#hooks'; +import {AvailableHooks, RecievedDataHook, BeforeSendingDataHook, Hooks} from './hooks'; export {AvailableHooks, RecievedDataHook, BeforeSendingDataHook, Hooks} -import * as TestClient from '#testclient'; +import * as TestClient from './tests/testclient/'; export {% raw %}{{% endraw %} TestClient {% raw %}}{% endraw %}; -import {ErrorCode, NatsTypescriptTemplateError} from '#NatsTypescriptTemplateError'; +import {ErrorCode, NatsTypescriptTemplateError} from './NatsTypescriptTemplateError'; export {ErrorCode, NatsTypescriptTemplateError} import { Client, @@ -27,17 +27,17 @@ import { } from 'ts-nats'; {%- for channelName, _ in asyncapi.channels() %} -import * as {{ channelName | camelCase }}Channel from "#channels/{{ channelName | pascalCase | firstUpperCase }}"; +import * as {{ channelName | camelCase }}Channel from "./channels/{{ channelName | pascalCase | firstUpperCase }}"; export {% raw %}{{% endraw %}{{ channelName | camelCase }}Channel}; {%- endfor %} {%- for messageName, _ in asyncapi.allMessages() %} -import {default as {{ messageName | pascalCase }}Message} from "#messages/{{ messageName | pascalCase }}"; +import {default as {{ messageName | pascalCase }}Message} from "./messages/{{ messageName | pascalCase }}"; export {% raw %}{{% endraw %}{{ messageName | pascalCase }}Message}; {%- endfor %} {%- for schemaId, _ in (asyncapi | objectSchema) %} -import {default as {{ schemaId | pascalCase }}Schema} from "#schemas/{{ schemaId | pascalCase }}"; +import {default as {{ schemaId | pascalCase }}Schema} from "./schemas/{{ schemaId | pascalCase }}"; export {% raw %}{{% endraw %}{{ schemaId | pascalCase }}Schema }; {%- endfor %} diff --git a/template/src/schema/$$objectSchema$$.ts.njk b/template/src/schemas/$$objectSchema$$.ts.njk similarity index 100% rename from template/src/schema/$$objectSchema$$.ts.njk rename to template/src/schemas/$$objectSchema$$.ts.njk diff --git a/template/src/tests/testclient/index.ts.njk b/template/src/tests/testclient/index.ts.njk index 682d932a9..25897f6c1 100644 --- a/template/src/tests/testclient/index.ts.njk +++ b/template/src/tests/testclient/index.ts.njk @@ -6,7 +6,7 @@ {%- from "../../../../partials/index/Standard.njk" import standard %} import {fromSeed} from 'ts-nkeys'; -import {ErrorCode, NatsTypescriptTemplateError} from '#NatsTypescriptTemplateError'; +import {ErrorCode, NatsTypescriptTemplateError} from '../../NatsTypescriptTemplateError'; import { Client, NatsConnectionOptions, @@ -20,17 +20,17 @@ import { } from 'ts-nats'; {%- for channelName, _ in asyncapi.channels() %} -import * as {{ channelName | camelCase }}Channel from "#testchannels/{{ channelName | pascalCase | firstUpperCase }}"; +import * as {{ channelName | camelCase }}Channel from "./testchannels/{{ channelName | pascalCase | firstUpperCase }}"; export {% raw %}{{% endraw %}{{ channelName | camelCase }}Channel}; {%- endfor %} {%- for messageName, _ in asyncapi.allMessages() %} -import {default as {{ messageName | pascalCase }}Message} from "#messages/{{ messageName | pascalCase }}"; +import {default as {{ messageName | pascalCase }}Message} from "../../messages/{{ messageName | pascalCase }}"; export {% raw %}{{% endraw %}{{ messageName | pascalCase }}Message}; {%- endfor %} {%- for schemaId, _ in (asyncapi | objectSchema) %} -import {default as {{ schemaId | pascalCase }}Schema} from "#schemas/{{ schemaId | pascalCase }}"; +import {default as {{ schemaId | pascalCase }}Schema} from "../../schemas/{{ schemaId | pascalCase }}"; export {% raw %}{{% endraw %}{{ schemaId | pascalCase }}Schema }; {%- endfor %} diff --git a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk index f72c10e77..bf87779d0 100644 --- a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk +++ b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk @@ -4,14 +4,14 @@ {%- from "../../../../../partials/channel/Request.njk" import request %} {%- from "../../../../../partials/channel/Subscribe.njk" import subscribe %} {%- if channel.hasPublish() %} -import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '#messages/{{ channel.publish().message(0).uid() | pascalCase}}' +import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '../../../messages/{{ channel.publish().message(0).uid() | pascalCase}}' {%- endif %} {%- if channel.hasSubscribe() %} -import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '#messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' +import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '../../../messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' {%- endif %} import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import {ErrorCode, NatsTypescriptTemplateError} from '#NatsTypescriptTemplateError'; -import { Hooks } from '#hooks'; +import {ErrorCode, NatsTypescriptTemplateError} from '../../../NatsTypescriptTemplateError'; +import { Hooks } from '../../../hooks'; {%- if channel | isRequestReply %} diff --git a/template/tsconfig.json b/template/tsconfig.json index b09ff54de..75097457a 100644 --- a/template/tsconfig.json +++ b/template/tsconfig.json @@ -9,17 +9,7 @@ "preserveConstEnums": true, "sourceMap": true, "outDir": "dist/", - "baseUrl": "./src", - "paths": { - "#messages/*": ["messages/*"], - "#schemas/*": ["schema/*"], - "#channels/*": ["channels/*"], - "#testchannels/*": ["tests/testclient/testchannels/*"], - "#hooks": ["hooks"], - "#testclient": ["tests/testclient/index"], - "#client": ["index"], - "#NatsTypescriptTemplateError": ["NatsTypescriptTemplateError"] - } + "baseUrl": "./src" }, "include": ["src"], "exclude": ["node_modules", "**/*.spec.ts"] From 78c13162b3242c2fa5b5a9bccae6e2b46eca4dd8 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 16 Jul 2020 03:48:53 +0200 Subject: [PATCH 058/110] WIP quicktype integration. --- filters/all.js | 4 +- hooks/quicktype-schema.js | 37 ++ package-lock.json | 533 +++++++++++++++++- package.json | 4 +- partials/channel/Publish.njk | 2 +- partials/channel/Reply.njk | 6 +- partials/channel/Request.njk | 8 +- partials/channel/Subscribe.njk | 4 +- partials/index/Publish.njk | 2 +- partials/index/Reply.njk | 4 +- partials/index/Request.njk | 4 +- partials/index/Standard.njk | 43 +- partials/index/Subscribe.njk | 2 +- template/src/channels/$$channel$$.ts.njk | 8 +- template/src/index.ts.njk | 13 +- template/src/messages/$$message$$.ts.njk | 63 --- template/src/schemas/$$objectSchema$$.ts.njk | 74 --- template/src/tests/testclient/index.ts.njk | 12 +- .../testchannels/$$channel$$.ts.njk | 8 +- 19 files changed, 633 insertions(+), 198 deletions(-) create mode 100644 hooks/quicktype-schema.js delete mode 100644 template/src/messages/$$message$$.ts.njk delete mode 100644 template/src/schemas/$$objectSchema$$.ts.njk diff --git a/filters/all.js b/filters/all.js index 9efcafe90..58285abbc 100644 --- a/filters/all.js +++ b/filters/all.js @@ -28,7 +28,9 @@ filter.isJsonPayload = (messageContentType, defaultContentType) => { return containsPayload(messageContentType, defaultContentType, 'json'); } - +filter.messageHasNotNullPayload = (messagePayload) => { + return messagePayload.type()+"" != "null"; +} /** * Figure out if a payload is located in the document. diff --git a/hooks/quicktype-schema.js b/hooks/quicktype-schema.js new file mode 100644 index 000000000..58554076b --- /dev/null +++ b/hooks/quicktype-schema.js @@ -0,0 +1,37 @@ +const fs = require('fs'); +const Path = require('path'); +const filters = require("../filters/all") +const { quicktype, InputData, JSONSchemaInput, JSONSchemaStore } = require("quicktype-core"); +async function genSchema(schemaPath, schemaName, jsonSchema){ + const schemaString = JSON.stringify(jsonSchema.json()); + const schemaInput = new JSONSchemaInput(new JSONSchemaStore()); + await schemaInput.addSource({ name: schemaName, schema: schemaString }); + const inputData = new InputData(); + inputData.addInput(schemaInput) + //const { lines } = await quicktype({ lang: "java", inputData, rendererOptions: { 'justTypes': 'true', 'packageName': schemaName} }); + const { lines } = await quicktype({ lang: "typescript", inputData }); + fs.writeFileSync(schemaPath, lines.join("\n")); +} +module.exports = { + 'generate:after': async (generator) => { + const allMessages = generator.asyncapi.allMessages(); + for (let [messageId, message] of allMessages) { + const payloadSchema = message.payload(); + if(payloadSchema.type()+"" != "null"){ + const filepath = Path.join(generator.targetDir, "src/messages/", filters.pascalCase(messageId)+".ts"); + await genSchema(filepath, messageId, message.payload()); + } + } + // const allSchemas = generator.asyncapi.allSchemas(); + // const objectMap = {}; + // allSchemas.forEach((schema, schemaId) => { if (schema.type() === 'object') objectMap[schemaId] = schema; }); + // for (const schema in allMessages) { + // if (objectMap.hasOwnProperty(schemaName)) { + // const schema = objectMap[schemaName]; + // const filepath = Path.join(generator.targetDir, "src/messages/", schemaName+".ts"); + // console.log(filepath); + // await genSchema(filepath, schemaName, schema); + // } + // } + } +}; diff --git a/package-lock.json b/package-lock.json index cecc509c4..aa1e8e788 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,20 @@ "openapi-sampler": "^1.0.0-beta.15" } }, + "@mark.probst/unicode-properties": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@mark.probst/unicode-properties/-/unicode-properties-1.1.0.tgz", + "integrity": "sha512-7AQsO0hMmpqDledV7AhBuSYqYPFsKP9PaltMecX9nlnsyFxqtsqUg9/pvB2L/jxvskrDrNkdKYz2KTbQznCtng==", + "requires": { + "brfs": "^1.4.0", + "unicode-trie": "^0.3.0" + } + }, + "acorn": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==" + }, "ansi-colors": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", @@ -90,6 +104,22 @@ "fill-range": "^7.0.1" } }, + "brfs": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/brfs/-/brfs-1.6.1.tgz", + "integrity": "sha512-OfZpABRQQf+Xsmju8XE9bDjs+uU4vLREGolP7bDgcpsI17QREyZ4Bl+2KLxxx1kCgA0fAIhKQBaBYh+PEcCqYQ==", + "requires": { + "quote-stream": "^1.0.1", + "resolve": "^1.1.5", + "static-module": "^2.2.0", + "through2": "^2.0.0" + } + }, + "browser-or-node": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-1.3.0.tgz", + "integrity": "sha512-0F2z/VSnLbmEeBcUrSuDH5l0HxTXdQQzLjkmBR4cYfvg1zJrKSlmIZFqyFR8oX0NrwPhy3c3HQ6i3OxMbew4Tg==" + }, "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -102,6 +132,11 @@ "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", "dev": true }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -205,6 +240,11 @@ } } }, + "collection-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collection-utils/-/collection-utils-1.0.1.tgz", + "integrity": "sha512-LA2YTIlR7biSpXkKYwwuzGjwL5rjWEZVOSnvdUc7gObvWe4WkjxOpfrdhoP7Hs09YWDVfg0Mal9BpAqLfVEzQg==" + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -232,6 +272,30 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -256,6 +320,11 @@ "type-detect": "^4.0.0" } }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -303,12 +372,28 @@ } } }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "requires": { + "readable-stream": "^2.0.2" + } + }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "requires": { + "iconv-lite": "^0.6.2" + } + }, "entities": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", @@ -349,11 +434,62 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, + "escodegen": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", + "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + } + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "falafel": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.2.4.tgz", + "integrity": "sha512-0HXjo8XASWRmsS0X1EkhwEMZaD3Qvp7FfURwjLKjG1ghfRm/MGZl2r4cWUTv41KdNghTw4OUMmVtdGQp3+H+uQ==", + "requires": { + "acorn": "^7.1.1", + "foreach": "^2.0.5", + "isarray": "^2.0.1", + "object-keys": "^1.0.6" + }, + "dependencies": { + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + } + } + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "filename-reserved-regex": { "version": "2.0.0", @@ -418,8 +554,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "get-caller-file": { "version": "2.0.5", @@ -472,7 +607,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -495,6 +629,14 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -508,8 +650,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "is-binary-path": { "version": "2.1.0", @@ -574,6 +715,11 @@ "has": "^1.0.3" } }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, "is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", @@ -583,12 +729,36 @@ "has-symbols": "^1.0.1" } }, + "is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + } + }, + "js-base64": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.3.tgz", + "integrity": "sha512-fiUvdfCaAXoQTHdKMgTvg6IkecXDcVz6V5rlftUTclF9IKBjMizvSdQaCl/z/6TApDeby5NL+axYou3i0mu1Pg==" + }, "js-yaml": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", @@ -607,6 +777,15 @@ "foreach": "^2.0.4" } }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, "linkify-it": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", @@ -639,6 +818,14 @@ "chalk": "^2.4.2" } }, + "magic-string": { + "version": "0.22.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", + "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", + "requires": { + "vlq": "^0.2.2" + } + }, "markdown-it": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", @@ -656,6 +843,21 @@ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" }, + "merge-source-map": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz", + "integrity": "sha1-pd5GU42uhNQRTMXqArR3KmNGcB8=", + "requires": { + "source-map": "^0.5.6" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -668,8 +870,7 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "mkdirp": { "version": "0.5.3", @@ -728,6 +929,15 @@ "semver": "^5.7.0" } }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -743,8 +953,7 @@ "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, "object.assign": { "version": "4.1.0", @@ -785,6 +994,19 @@ "json-pointer": "^0.6.0" } }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, "p-limit": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", @@ -809,6 +1031,11 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -821,6 +1048,11 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, "pathval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", @@ -833,6 +1065,85 @@ "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", "dev": true }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==" + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "quicktype-core": { + "version": "6.0.66", + "resolved": "https://registry.npmjs.org/quicktype-core/-/quicktype-core-6.0.66.tgz", + "integrity": "sha512-eSvyyqm/zwAdIIzzNlQtc6AwdqvqGtxTDT23idnAG29yCNzU2K2ZXHaKTi5kwxDdbgHn0QBJPNBVWBzKSbryjg==", + "requires": { + "@mark.probst/unicode-properties": "~1.1.0", + "browser-or-node": "^1.2.1", + "collection-utils": "^1.0.1", + "isomorphic-fetch": "^2.2.1", + "js-base64": "^2.4.3", + "pako": "^1.0.6", + "pluralize": "^7.0.0", + "readable-stream": "2.3.0", + "urijs": "^1.19.1", + "wordwrap": "^1.0.0", + "yaml": "^1.5.0" + } + }, + "quote-stream": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/quote-stream/-/quote-stream-1.0.2.tgz", + "integrity": "sha1-hJY/jJwmuULhU/7rU6rnRlK34LI=", + "requires": { + "buffer-equal": "0.0.1", + "minimist": "^1.1.3", + "through2": "^2.0.0" + }, + "dependencies": { + "buffer-equal": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", + "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=" + } + } + }, + "readable-stream": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.0.tgz", + "integrity": "sha512-c7KMXGd4b48nN3OJ1U9qOsn6pXNzf6kLd3kdZCkg2sxAcoiufInqF0XckwEnlrcwuaYwonlNK8GQUIOC/WC7sg==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "safe-buffer": "~5.1.0", + "string_decoder": "~1.0.0", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "readdirp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", @@ -854,6 +1165,24 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -866,11 +1195,86 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "shallow-copy": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz", + "integrity": "sha1-QV9CcC1z2BAzApLMXuhurhoRoXA=" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "static-eval": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.0.tgz", + "integrity": "sha512-agtxZ/kWSsCkI5E4QifRwsaPs0P0JmZV6dkLz6ILYfFYQGn+5plctanRN+IC8dJRiFkyXHrwEE3W9Wmx67uDbw==", + "requires": { + "escodegen": "^1.11.1" + }, + "dependencies": { + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + } + } + }, + "static-module": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/static-module/-/static-module-2.2.5.tgz", + "integrity": "sha512-D8vv82E/Kpmz3TXHKG8PPsCPg+RAX6cbCOyvjM6x04qZtQ47EtJFVwRsdov3n5d6/6ynrOY9XB4JkaZwB2xoRQ==", + "requires": { + "concat-stream": "~1.6.0", + "convert-source-map": "^1.5.1", + "duplexer2": "~0.1.4", + "escodegen": "~1.9.0", + "falafel": "^2.1.0", + "has": "^1.0.1", + "magic-string": "^0.22.4", + "merge-source-map": "1.0.4", + "object-inspect": "~1.4.0", + "quote-stream": "~1.0.2", + "readable-stream": "~2.3.3", + "shallow-copy": "~0.0.1", + "static-eval": "^2.0.0", + "through2": "~2.0.3" + }, + "dependencies": { + "object-inspect": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.4.1.tgz", + "integrity": "sha512-wqdhLpfCUbEsoEwl3FXwGyv8ief1k/1aUdIPCqVnupM6e8l63BEJdiF/0swtn04/8p05tG/T0FrpTlfwvljOdw==" + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + } + } + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -923,6 +1327,14 @@ "es-abstract": "^1.17.5" } }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -955,6 +1367,36 @@ "has-flag": "^3.0.0" } }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + } + } + }, + "tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==" + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -972,17 +1414,66 @@ "escape-string-regexp": "^1.0.2" } }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, "uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" }, + "unicode-trie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-0.3.1.tgz", + "integrity": "sha1-1nHd3YkQGgi6w3tqUWEBBgIFIIU=", + "requires": { + "pako": "^0.2.5", + "tiny-inflate": "^1.0.0" + }, + "dependencies": { + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=" + } + } + }, + "urijs": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.2.tgz", + "integrity": "sha512-s/UIq9ap4JPZ7H1EB5ULo/aOUbWqfDi7FKzMC2Nz+0Si8GiT1rIEaprt8hy3Vy2Ex2aJPpOQv4P4DuOZ+K1c6w==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "vlq": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", + "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==" + }, + "whatwg-fetch": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.2.0.tgz", + "integrity": "sha512-SdGPoQMMnzVYThUbSrEvqTlkvC1Ux27NehaJ/GUHBfNrh5Mjg+1/uRyFMwVnxO2MrikMWvWAqUGgQOfVU4hT7w==" + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -1007,6 +1498,16 @@ "string-width": "^1.0.2 || 2" } }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, "wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", @@ -1052,12 +1553,22 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==" + }, "yargs": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", diff --git a/package.json b/package.json index 6c1100b56..32562aa02 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,9 @@ "dependencies": { "filenamify": "^4.1.0", "lodash": "^4.17.15", - "@asyncapi/generator-filters": "^1.0.0" + "@asyncapi/generator-filters": "^1.0.0", + "quicktype-core": "6.0.66", + "is-url": "1.2.4" }, "devDependencies": { "chai": "^4.2.0", diff --git a/partials/channel/Publish.njk b/partials/channel/Publish.njk index 8a214c5f4..ab0025c1c 100644 --- a/partials/channel/Publish.njk +++ b/partials/channel/Publish.njk @@ -2,7 +2,7 @@ {% macro publish(channelName, channelParameters, publishMessage, server) %} export function publish( - requestMessage: {{publishMessage.uid() | pascalCase}}Message, + requestMessage: {{publishMessage.uid() | pascalCase}}Message.{{publishMessage.uid() | pascalCase}}, nc: Client, {% if channelParameters | length %} {{channelParameters | realizeParametersForChannel}} diff --git a/partials/channel/Reply.njk b/partials/channel/Reply.njk index e4fe1d8d5..16076da21 100644 --- a/partials/channel/Reply.njk +++ b/partials/channel/Reply.njk @@ -1,8 +1,8 @@ {% macro reply(channelName, channelParameters, subscribtionMessage, publishMessage, server, params) %} export function reply( - onRequest: (err?: NatsTypescriptTemplateError, msg?: {{publishMessage.uid() | pascalCase}}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => - {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{subscribtionMessage.uid() | pascalCase}}Message{%-if params.promisifyReplyCallback | length %}>{%- endif %}, + onRequest: (err?: NatsTypescriptTemplateError, msg?: {{publishMessage.uid() | pascalCase}}Message.{{publishMessage.uid() | pascalCase}}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => + {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{subscribtionMessage.uid() | pascalCase}}Message.{{subscribtionMessage.uid() | pascalCase}}{%-if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError: (err: NatsTypescriptTemplateError) => void, nc: Client, {% if channelParameters | length %} @@ -47,7 +47,7 @@ export function reply( onReplyError(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)) return; } - let requestData = {{publishMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); + let requestData = {{publishMessage.name() | pascalCase}}Message.Convert.to{{publishMessage.name() | pascalCase}}(processedDataReceived); let responseObject = {%-if params.promisifyReplyCallback | length %}await{%- endif %} onRequest(undefined, requestData{% if channelParameters | length %}, {%- set counter = 1 %} {%- for parameterName, parameter in channelParameters %} diff --git a/partials/channel/Request.njk b/partials/channel/Request.njk index c846429da..3f0510799 100644 --- a/partials/channel/Request.njk +++ b/partials/channel/Request.njk @@ -1,13 +1,13 @@ {% macro request(channelName, channelParameters, publishMessage, subscribtionMessage, server) %} export function request( - requestMessage: {{subscribtionMessage.uid() | pascalCase}}Message, + requestMessage: {{subscribtionMessage.uid() | pascalCase}}Message.{{subscribtionMessage.uid() | pascalCase}}, nc: Client, {% if channelParameters | length %} {{channelParameters | realizeParametersForChannel}} {% endif %} - ): Promise<{{publishMessage.uid() | pascalCase}}Message> { - return new Promise<{{publishMessage.uid() | pascalCase}}Message>(async (resolve, reject) => { + ): Promise<{{publishMessage.uid() | pascalCase}}Message.{{publishMessage.uid() | pascalCase}}> { + return new Promise(async (resolve, reject) => { try { let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); var requestData : any = requestMessage; @@ -31,7 +31,7 @@ export function request( for(let hook of receivedDataHooks){ processedDataReceived = hook(processedDataReceived); } - let publishedData = {{publishMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); + let publishedData = {{publishMessage.name() | pascalCase}}Message.Convert.to{{publishMessage.name() | pascalCase}}(processedDataReceived); resolve(publishedData); }catch(e){ reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); diff --git a/partials/channel/Subscribe.njk b/partials/channel/Subscribe.njk index 81ef579b8..49b28e913 100644 --- a/partials/channel/Subscribe.njk +++ b/partials/channel/Subscribe.njk @@ -1,7 +1,7 @@ {% macro subscribe(channelName, channelParameters, subscribtionMessage, server) %} export function subscribe( - onDataCallback : (err?: NatsTypescriptTemplateError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void, + onDataCallback : (err?: NatsTypescriptTemplateError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message.{{subscribtionMessage.uid() | pascalCase}}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void, nc: Client, {% if channelParameters | length %} {{channelParameters | realizeParametersForChannel}} @@ -45,7 +45,7 @@ export function subscribe( reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); return; } - let publishedData = {{subscribtionMessage.name() | pascalCase}}Message.toMessage(processedDataReceived); + let publishedData = {{subscribtionMessage.name() | pascalCase}}Message.Convert.to{{subscribtionMessage.name() | pascalCase}}(processedDataReceived); onDataCallback(undefined, publishedData{% if channelParameters | length %}, {%- set counter = 1 %} {%- for parameterName, parameter in channelParameters %} diff --git a/partials/index/Publish.njk b/partials/index/Publish.njk index 0f8dfd36f..7dc675e27 100644 --- a/partials/index/Publish.njk +++ b/partials/index/Publish.njk @@ -4,7 +4,7 @@ * {{messageDescription}} * @param requestMessage The message to publish. */ - public publishTo{{channelName | pascalCase }}(requestMessage: {{ message.uid() | pascalCase }}Message {% if channelParameters | length %} + public publishTo{{channelName | pascalCase }}(requestMessage: {{ message.uid() | pascalCase }}Message.{{ message.uid() | pascalCase }} {% if channelParameters | length %} ,{{channelParameters | realizeParametersForChannel}} {% endif %}): Promise { {%- if message.contentType() | isBinaryPayload(defaultContentType) %} diff --git a/partials/index/Reply.njk b/partials/index/Reply.njk index d25edb18f..b09dab545 100644 --- a/partials/index/Reply.njk +++ b/partials/index/Reply.njk @@ -8,9 +8,9 @@ public replyTo{{channelName | pascalCase }}( onRequest : ( err?: NatsTypescriptTemplateError, - msg?: {{ publishMessage.uid() | pascalCase }}Message + msg?: {{ publishMessage.uid() | pascalCase }}Message.{{ publishMessage.uid() | pascalCase }} {%- if channelParameters | length %},{{channelParameters | realizeParametersForChannel(false)}}{% endif %} - ) => {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{ subscribeMessage.uid() | pascalCase }}Message{%- if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError : (err: NatsTypescriptTemplateError) => void + ) => {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{ subscribeMessage.uid() | pascalCase }}Message.{{ subscribeMessage.uid() | pascalCase }}{%- if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError : (err: NatsTypescriptTemplateError) => void {% if channelParameters | length %} ,{{channelParameters | realizeParametersForChannel}} {% endif %}): Promise { diff --git a/partials/index/Request.njk b/partials/index/Request.njk index cda451102..9a929dfcb 100644 --- a/partials/index/Request.njk +++ b/partials/index/Request.njk @@ -4,10 +4,10 @@ * {{messageDescription}} * @param requestMessage The request message to send. */ - public request{{channelName | pascalCase }}(requestMessage: {{ subscribeMessage.uid() | pascalCase }}Message + public request{{channelName | pascalCase }}(requestMessage: {{ subscribeMessage.uid() | pascalCase }}Message.{{ subscribeMessage.uid() | pascalCase }} {% if channelParameters | length %} ,{{channelParameters | realizeParametersForChannel}} - {% endif %}): Promise<{{ publishMessage.uid() | pascalCase }}Message> { + {% endif %}): Promise<{{ publishMessage.uid() | pascalCase }}Message.{{ publishMessage.uid() | pascalCase }}> { {%- if subscribeMessage.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; {%- endif %} diff --git a/partials/index/Standard.njk b/partials/index/Standard.njk index 4fc196a0a..022fcd38e 100644 --- a/partials/index/Standard.njk +++ b/partials/index/Standard.njk @@ -108,9 +108,12 @@ */ async connectWithUserCreds(userCreds: string, options?: NatsConnectionOptions){ if(!options){ - options = {}; + options = { + userCreds: userCreds + }; + }else{ + options.userCreds = userCreds; } - options.userCreds = userCreds; await this.connect(options); } /** @@ -118,10 +121,14 @@ */ async connectWithUserPass(user: string, pass: string, options?: NatsConnectionOptions){ if(!options){ - options = {}; + options = { + user: user, + pass: pass + }; + }else{ + options.user = user; + options.pass = pass; } - options.user = user; - options.pass = pass; await this.connect(options); } @@ -130,9 +137,12 @@ */ async connectToHost(host: string, options?: NatsConnectionOptions){ if(!options){ - options = {}; + options = { + servers: [host] + }; + }else{ + options.servers = [host]; } - options.servers = [host]; await this.connect(options); } @@ -141,12 +151,19 @@ */ async connectWithNkey(publicNkey: string, seed: string, options?: NatsConnectionOptions){ if(!options){ - options = {}; - } - options.nkey = publicNkey; - options.nonceSigner = (nonce: string): Buffer => { - const sk = fromSeed(Buffer.from(seed)); - return sk.sign(Buffer.from(nonce)); + options = { + nkey: publicNkey, + nonceSigner: (nonce: string): Buffer => { + const sk = fromSeed(Buffer.from(seed)); + return sk.sign(Buffer.from(nonce)); + } + }; + }else{ + options.nkey = publicNkey; + options.nonceSigner = (nonce: string): Buffer => { + const sk = fromSeed(Buffer.from(seed)); + return sk.sign(Buffer.from(nonce)); + } } await this.connect(options); } diff --git a/partials/index/Subscribe.njk b/partials/index/Subscribe.njk index 81b9b6c3a..26c73024e 100644 --- a/partials/index/Subscribe.njk +++ b/partials/index/Subscribe.njk @@ -4,7 +4,7 @@ * {{messageDescription}} * @param onDataCallback Called when message recieved. */ - public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsTypescriptTemplateError, msg?: {{ message.uid() | pascalCase }}Message{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void {% if channelParameters | length %} + public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsTypescriptTemplateError, msg?: {{ message.uid() | pascalCase }}Message.{{ message.uid() | pascalCase }}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void {% if channelParameters | length %} ,{{channelParameters | realizeParametersForChannel}} {% endif %}): Promise { {%- if message.contentType() | isBinaryPayload(defaultContentType) %} diff --git a/template/src/channels/$$channel$$.ts.njk b/template/src/channels/$$channel$$.ts.njk index 163c7043d..651d5adbb 100644 --- a/template/src/channels/$$channel$$.ts.njk +++ b/template/src/channels/$$channel$$.ts.njk @@ -4,10 +4,14 @@ {%- from "../../../partials/channel/Request.njk" import request %} {%- from "../../../partials/channel/Subscribe.njk" import subscribe %} {%- if channel.hasPublish() %} -import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '../messages/{{ channel.publish().message(0).uid() | pascalCase}}' +{%- if channel.publish().message(0).payload() | messageHasNotNullPayload %} +import * as {{ channel.publish().message(0).uid() | pascalCase }}Message from '../messages/{{ channel.publish().message(0).uid() | pascalCase}}' +{%- endif %} {%- endif %} {%- if channel.hasSubscribe() %} -import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '../messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' +{%- if channel.subscribe().message(0).payload() | messageHasNotNullPayload %} +import * as {{ channel.subscribe().message(0).uid() | pascalCase }}Message from '../messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' +{%- endif %} {%- endif %} import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; import {ErrorCode, NatsTypescriptTemplateError} from '../NatsTypescriptTemplateError'; diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index d359c9132..f64a641f8 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -26,19 +26,16 @@ import { ServerInfo } from 'ts-nats'; -{%- for channelName, _ in asyncapi.channels() %} +{%- for channelName, message in asyncapi.channels() %} import * as {{ channelName | camelCase }}Channel from "./channels/{{ channelName | pascalCase | firstUpperCase }}"; export {% raw %}{{% endraw %}{{ channelName | camelCase }}Channel}; {%- endfor %} -{%- for messageName, _ in asyncapi.allMessages() %} -import {default as {{ messageName | pascalCase }}Message} from "./messages/{{ messageName | pascalCase }}"; +{%- for messageName, message in asyncapi.allMessages() %} +{%- if message.payload() | messageHasNotNullPayload %} +import * as {{ messageName | pascalCase }}Message from "./messages/{{ messageName | pascalCase }}"; export {% raw %}{{% endraw %}{{ messageName | pascalCase }}Message}; -{%- endfor %} - -{%- for schemaId, _ in (asyncapi | objectSchema) %} -import {default as {{ schemaId | pascalCase }}Schema} from "./schemas/{{ schemaId | pascalCase }}"; -export {% raw %}{{% endraw %}{{ schemaId | pascalCase }}Schema }; +{%- endif %} {%- endfor %} diff --git a/template/src/messages/$$message$$.ts.njk b/template/src/messages/$$message$$.ts.njk deleted file mode 100644 index ab4d7ed4e..000000000 --- a/template/src/messages/$$message$$.ts.njk +++ /dev/null @@ -1,63 +0,0 @@ -{%- macro initProperties(schema, required=true) %} - {%- if schema.allOf() | length %} - {%- for allOfSchema in schema.allOf() %} - {{initProperties(allOfSchema)}} - {%- endfor %} - {%- endif %} - {%- if schema.oneOf() | length %} - oneOf:{{schema.oneOf() | oneOfSchemaType}} - {%- endif %} - {%- if schema.anyOf() | length %} - {%- for anyOfSchema in schema.anyOf() %} - {{initProperties(anyOfSchema, false)}} - {%- endfor %} - {%- endif %} - - {%- if schema.type() == "object" %} - {{initProperty(schema.uid(), schema.uid())}} - {%- elif schema.type() | length%} - type: {{ schema.type() | toTsType }} - {%- endif %} -{%- endmacro %} -{%- macro setConstructorProperties(schema) %} - {%- if schema.allOf() | length %} - {%- for allOfSchema in schema.allOf() %} - {{setConstructorProperties(allOfSchema)}} - {%- endfor %} - {%- endif %} - - {%- if schema.type() == "object" %} - {{setProperty(schema.uid())}} - {%- elif schema.type() | length %} - {{setProperty("type")}} - {%- endif %} -{%- endmacro %} -{%- macro initProperty(propertyName, propertyType) %} - {{propertyName | camelCase}}:{{propertyType | pascalCase}}Schema; -{% endmacro %} - -{%- macro setProperty(propertyName) %} - this.{{propertyName | camelCase}} = {{propertyName | camelCase}}; -{% endmacro %} - -{%- for _, import in (message.payload() | genericImports) %} -{{import | safe }} -{%- endfor %} -export default class {{ message.name() | pascalCase}} { - {{ initProperties(message.payload()) }} - - constructor( - {{message.payload() | messageConstructorParameters}} - ){ - {{setConstructorProperties(message.payload())}} - } - - /** - * Parses a JSON string to an object of {{ message.name() | pascalCase}} message class. - * @param json any to be parsed as {{ message.name() | pascalCase}}. - */ - public static toMessage(json: any): {{ message.name() | pascalCase }} { - return JSON.parse(JSON.stringify(json)); - } - -} diff --git a/template/src/schemas/$$objectSchema$$.ts.njk b/template/src/schemas/$$objectSchema$$.ts.njk deleted file mode 100644 index b44f46ca9..000000000 --- a/template/src/schemas/$$objectSchema$$.ts.njk +++ /dev/null @@ -1,74 +0,0 @@ - -{% macro initProperties(schema, required=true) %} - {%- if schema.allOf() | length %} - {%- for allOfSchema in schema.allOf() %} - {{initProperties(allOfSchema)}} - {%- endfor %} - {%- endif %} - - {%- if schema.oneOf() | length %} - test:{{schema.oneOf() | oneOfSchemaType}} - {%- endif %} - - {%- if schema.anyOf() | length %} - {%- for oneOfSchema in schema.anyOf() %} - {{initProperties(oneOfSchema, false)}} - {%- endfor %} - {%- endif %} - - {%- if schema.type() == "object" %} - {%- for propertyName, property in schema.properties() %} - {{ propertyName}}{% if not required or not property.required() %}?{% endif %}: {{ property.type() | toTsType(property) }} - {%- endfor %} - {%- elif schema.type() | length %} - type: {{ schema.type() | toTsType }} - {%- endif %} - -{% endmacro %} - -{%- macro setConstructorProperties(schema) %} - {%- if schema.allOf() | length %} - {%- for allOfSchema in schema.allOf() %} - {{setConstructorProperties(allOfSchema)}} - {%- endfor %} - {%- endif %} - {%- if schema.oneOf() | length %} - {{setProperty("oneOf")}} - {%- endif %} - {%- if schema.anyOf() | length %} - {%- for anyOfSchema in schema.anyOf() %} - {{setConstructorProperties(anyOfSchema)}} - {%- endfor %} - {%- endif %} - - {%- if schema.type() == "object" %} - {%- for propertyName, property in schema.properties() %} - {% if property.required() %} - {{setProperty(propertyName)}} - {%- endif %} - {%- endfor %} - {%- elif schema.type() | length %} - {{setProperty("type")}} - {%- endif %} - -{%- endmacro %} - -{%- macro setProperty(propertyName) %} - this.{{propertyName}} = {{propertyName}}; -{% endmacro %} - - -{%- for _, import in (schema | schemaImports) %} -{{import | safe }} -{%- endfor %} - -export default class {{ schema.uid() | camelCase }} { - - {{ initProperties(schema) }} - - constructor( - {{schema | schemaConstructorParameters}} - ){ - {{setConstructorProperties(schema)}} - } -} diff --git a/template/src/tests/testclient/index.ts.njk b/template/src/tests/testclient/index.ts.njk index 25897f6c1..84851f1c7 100644 --- a/template/src/tests/testclient/index.ts.njk +++ b/template/src/tests/testclient/index.ts.njk @@ -19,20 +19,18 @@ import { ServerInfo } from 'ts-nats'; -{%- for channelName, _ in asyncapi.channels() %} +{%- for channelName, message in asyncapi.channels() %} import * as {{ channelName | camelCase }}Channel from "./testchannels/{{ channelName | pascalCase | firstUpperCase }}"; export {% raw %}{{% endraw %}{{ channelName | camelCase }}Channel}; {%- endfor %} -{%- for messageName, _ in asyncapi.allMessages() %} -import {default as {{ messageName | pascalCase }}Message} from "../../messages/{{ messageName | pascalCase }}"; +{%- for messageName, message in asyncapi.allMessages() %} +{%- if message.payload() | messageHasNotNullPayload %} +import * as {{ messageName | pascalCase }}Message from "../../messages/{{ messageName | pascalCase }}"; export {% raw %}{{% endraw %}{{ messageName | pascalCase }}Message}; +{%- endif %} {%- endfor %} -{%- for schemaId, _ in (asyncapi | objectSchema) %} -import {default as {{ schemaId | pascalCase }}Schema} from "../../schemas/{{ schemaId | pascalCase }}"; -export {% raw %}{{% endraw %}{{ schemaId | pascalCase }}Schema }; -{%- endfor %} import * as events from 'events'; diff --git a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk index bf87779d0..0e811dfa1 100644 --- a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk +++ b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk @@ -4,10 +4,14 @@ {%- from "../../../../../partials/channel/Request.njk" import request %} {%- from "../../../../../partials/channel/Subscribe.njk" import subscribe %} {%- if channel.hasPublish() %} -import {default as {{ channel.publish().message(0).uid() | pascalCase }}Message} from '../../../messages/{{ channel.publish().message(0).uid() | pascalCase}}' +{%- if channel.publish().message(0).payload() | messageHasNotNullPayload %} +import * as {{ channel.publish().message(0).uid() | pascalCase }}Message from '../../../messages/{{ channel.publish().message(0).uid() | pascalCase}}'; +{%- endif %} {%- endif %} {%- if channel.hasSubscribe() %} -import {default as {{ channel.subscribe().message(0).uid() | pascalCase }}Message} from '../../../messages/{{ channel.subscribe().message(0).uid() | pascalCase}}' +{%- if channel.subscribe().message(0).payload() | messageHasNotNullPayload %} +import * as {{ channel.subscribe().message(0).uid() | pascalCase }}Message from '../../../messages/{{ channel.subscribe().message(0).uid() | pascalCase}}'; +{%- endif %} {%- endif %} import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; import {ErrorCode, NatsTypescriptTemplateError} from '../../../NatsTypescriptTemplateError'; From c03193cad37aaff719dd8ca872afe032820ad408 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sun, 19 Jul 2020 02:04:22 +0200 Subject: [PATCH 059/110] Finished integrating quicktype so it supports null types. --- filters/all.js | 10 +++++ partials/channel/OnReceivingData.njk | 18 ++++++++ partials/channel/OnSendingData.njk | 13 ++++++ partials/channel/Publish.njk | 21 ++++------ partials/channel/Reply.njk | 62 ++++++++++++++-------------- partials/channel/Request.njk | 45 +++++++++----------- partials/channel/Subscribe.njk | 12 +++++- partials/index/Publish.njk | 2 +- partials/index/Reply.njk | 4 +- partials/index/Request.njk | 4 +- partials/index/Subscribe.njk | 2 +- 11 files changed, 118 insertions(+), 75 deletions(-) create mode 100644 partials/channel/OnReceivingData.njk create mode 100644 partials/channel/OnSendingData.njk diff --git a/filters/all.js b/filters/all.js index 58285abbc..7c7e67d00 100644 --- a/filters/all.js +++ b/filters/all.js @@ -31,6 +31,16 @@ filter.isJsonPayload = (messageContentType, defaultContentType) => { filter.messageHasNotNullPayload = (messagePayload) => { return messagePayload.type()+"" != "null"; } +/** + * Because quicktype cant handle null provide custom message type. + */ +filter.getMessageType = (message) => { + if(message.payload().type()+"" == "null"){ + return "null"; + }else{ + return `${this.pascalCase(message.uid())}Message.${this.pascalCase(message.uid())}`; + } +} /** * Figure out if a payload is located in the document. diff --git a/partials/channel/OnReceivingData.njk b/partials/channel/OnReceivingData.njk new file mode 100644 index 000000000..a7ab51016 --- /dev/null +++ b/partials/channel/OnReceivingData.njk @@ -0,0 +1,18 @@ + +{% macro OnReceivingData(promisfyErrors) %} +try { + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var receivedData : any = msg.data; + for(let hook of receivedDataHooks){ + receivedData = hook(receivedData); + } +} catch (e) { + {%- if promisfyErrors == true %} + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + return; + {%- else %} + onReplyError(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)) + return; + {%- endif %} +} +{% endmacro %} diff --git a/partials/channel/OnSendingData.njk b/partials/channel/OnSendingData.njk new file mode 100644 index 000000000..774d21a1d --- /dev/null +++ b/partials/channel/OnSendingData.njk @@ -0,0 +1,13 @@ + +{% macro OnSendingData() %} +try{ + let beforeSendingHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToSend : any = message; + for(let hook of beforeSendingHooks){ + dataToSend = hook(dataToSend); + } +}catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + return; +} +{% endmacro %} diff --git a/partials/channel/Publish.njk b/partials/channel/Publish.njk index ab0025c1c..7091701fa 100644 --- a/partials/channel/Publish.njk +++ b/partials/channel/Publish.njk @@ -1,8 +1,8 @@ +{%- from "./OnSendingData.njk" import OnSendingData %} {% macro publish(channelName, channelParameters, publishMessage, server) %} - export function publish( - requestMessage: {{publishMessage.uid() | pascalCase}}Message.{{publishMessage.uid() | pascalCase}}, + message: {{publishMessage | getMessageType}}, nc: Client, {% if channelParameters | length %} {{channelParameters | realizeParametersForChannel}} @@ -10,17 +10,12 @@ export function publish( ): Promise { return new Promise(async (resolve, reject) => { try{ - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var dataToPublish : any = requestMessage; - for(let hook of publishDataHooks){ - dataToPublish = hook(dataToPublish); - } - }catch(e){ - reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); - return; - } - try{ - nc.publish({{channelParameters | realizeChannelName(channelName)}}, dataToPublish); + {%- if publishMessage.payload() | messageHasNotNullPayload %} + {{OnSendingData()}} + nc.publish({{channelParameters | realizeChannelName(channelName)}}, dataToSend); + {%- else %} + nc.publish({{channelParameters | realizeChannelName(channelName)}}, null); + {%- endif %} resolve(); }catch(e){ reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); diff --git a/partials/channel/Reply.njk b/partials/channel/Reply.njk index 16076da21..dad640a35 100644 --- a/partials/channel/Reply.njk +++ b/partials/channel/Reply.njk @@ -1,8 +1,10 @@ -{% macro reply(channelName, channelParameters, subscribtionMessage, publishMessage, server, params) %} +{%- from "./OnSendingData.njk" import OnSendingData %} +{%- from "./OnReceivingData.njk" import OnReceivingData %} +{% macro reply(channelName, channelParameters, replyMessage, recieveMessage, server, params) %} export function reply( - onRequest: (err?: NatsTypescriptTemplateError, msg?: {{publishMessage.uid() | pascalCase}}Message.{{publishMessage.uid() | pascalCase}}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => - {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{subscribtionMessage.uid() | pascalCase}}Message.{{subscribtionMessage.uid() | pascalCase}}{%-if params.promisifyReplyCallback | length %}>{%- endif %}, + onRequest: (err?: NatsTypescriptTemplateError, msg?: {{recieveMessage | getMessageType}}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => + {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{replyMessage | getMessageType}}{%-if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError: (err: NatsTypescriptTemplateError) => void, nc: Client, {% if channelParameters | length %} @@ -12,14 +14,14 @@ export function reply( return new Promise(async (resolve, reject) => { try { let subscribeOptions: SubscriptionOptions = {}; - {%- if publishMessage | hasNatsBindings %} - {%- if publishMessage.bindings().nats().queue() | length %} + {%- if recieveMessage | hasNatsBindings %} + {%- if recieveMessage.bindings().nats().queue() | length %} //If queue - subscribeOptions.queue = '{{publishMessage.bindings().nats().queue().name()}}'; + subscribeOptions.queue = '{{recieveMessage.bindings().nats().queue().name()}}'; {%- endif %} - {%- if publishMessage.bindings().nats().unsubAfter() | length %} + {%- if recieveMessage.bindings().nats().unsubAfter() | length %} //If unsubafter - subscribeOptions.max = {{publishMessage.bindings().nats().unsubAfter()}}; + subscribeOptions.max = {{recieveMessage.bindings().nats().unsubAfter()}}; {%- endif %} {%- endif %} @@ -37,38 +39,38 @@ export function reply( {%- endfor %} } {%- endif %} - try { - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived : any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - } catch (e) { - onReplyError(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)) - return; - } - let requestData = {{publishMessage.name() | pascalCase}}Message.Convert.to{{publishMessage.name() | pascalCase}}(processedDataReceived); - let responseObject = {%-if params.promisifyReplyCallback | length %}await{%- endif %} onRequest(undefined, requestData{% if channelParameters | length %}, + + {%- if recieveMessage.payload() | messageHasNotNullPayload %} + {{OnReceivingData(false)}} + let requestData = {{recieveMessage.name() | pascalCase}}Message.Convert.to{{recieveMessage.name() | pascalCase}}(receivedData); + let message = {%-if params.promisifyReplyCallback | length %}await{%- endif %} onRequest(undefined, requestData{% if channelParameters | length %}, + {%- set counter = 1 %} + {%- for parameterName, parameter in channelParameters %} + receivedTopicParameters['{{parameterName}}']{%- if counter < (channelParameters | length) %},{%- endif %} + {%- set counter = counter+1 %} + {%- endfor %} + {%- endif %}); + {%- else %} + let message = {%-if params.promisifyReplyCallback | length %}await{%- endif %} onRequest(undefined, null{% if channelParameters | length %}, {%- set counter = 1 %} {%- for parameterName, parameter in channelParameters %} receivedTopicParameters['{{parameterName}}']{%- if counter < (channelParameters | length) %},{%- endif %} {%- set counter = counter+1 %} {%- endfor %} {%- endif %}); + {%- endif %} + if (msg.reply) { - try { - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var dataToPublish : any = responseObject; - for(let hook of publishDataHooks){ - dataToPublish = hook(dataToPublish); - } - nc.publish(msg.reply, dataToPublish); - } catch (e) { - onReplyError(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)) - } + {%- if replyMessage.payload() | messageHasNotNullPayload %} + {{OnSendingData()}} + nc.publish({{channelParameters | realizeChannelName(channelName)}}, dataToSend); + {%- else %} + nc.publish({{channelParameters | realizeChannelName(channelName)}}, null); + {%- endif %} } else { let error = new NatsTypescriptTemplateError('Expected request to need a reply, did not..', '000'); onReplyError(error) + return; } } }, subscribeOptions); diff --git a/partials/channel/Request.njk b/partials/channel/Request.njk index 3f0510799..9c32105c3 100644 --- a/partials/channel/Request.njk +++ b/partials/channel/Request.njk @@ -1,41 +1,36 @@ -{% macro request(channelName, channelParameters, publishMessage, subscribtionMessage, server) %} +{%- from "./OnSendingData.njk" import OnSendingData %} +{%- from "./OnReceivingData.njk" import OnReceivingData %} +{% macro request(channelName, channelParameters, recieveMessage, requestMessage, server) %} export function request( - requestMessage: {{subscribtionMessage.uid() | pascalCase}}Message.{{subscribtionMessage.uid() | pascalCase}}, + message: {{requestMessage | getMessageType}}, nc: Client, {% if channelParameters | length %} {{channelParameters | realizeParametersForChannel}} {% endif %} - ): Promise<{{publishMessage.uid() | pascalCase}}Message.{{publishMessage.uid() | pascalCase}}> { + ): Promise<{{recieveMessage | getMessageType}}> { return new Promise(async (resolve, reject) => { - try { - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var requestData : any = requestMessage; - for(let hook of publishDataHooks){ - requestData = hook(requestData); - } - }catch(e){ - reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); - return; - } + let msg; try { - msg = await nc.request({{channelParameters | realizeChannelName(channelName)}}, undefined, requestData) + {%- if requestMessage.payload() | messageHasNotNullPayload %} + {{OnSendingData()}} + msg = await nc.request({{channelParameters | realizeChannelName(channelName)}}, undefined, dataToSend) + {%- else %} + msg = await nc.request({{channelParameters | realizeChannelName(channelName)}}, undefined, null) + {%- endif %} }catch(e){ reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); return; } - try{ - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived: any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - let publishedData = {{publishMessage.name() | pascalCase}}Message.Convert.to{{publishMessage.name() | pascalCase}}(processedDataReceived); - resolve(publishedData); - }catch(e){ - reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); - } + + {%- if recieveMessage.payload() | messageHasNotNullPayload %} + {{OnReceivingData(true)}} + let recievedData = {{recieveMessage.name() | pascalCase}}Message.Convert.to{{recieveMessage.name() | pascalCase}}(receivedData); + resolve(recievedData); + {%- else %} + resolve(null); + {%- endif %} }) } diff --git a/partials/channel/Subscribe.njk b/partials/channel/Subscribe.njk index 49b28e913..872eeaf26 100644 --- a/partials/channel/Subscribe.njk +++ b/partials/channel/Subscribe.njk @@ -1,7 +1,7 @@ {% macro subscribe(channelName, channelParameters, subscribtionMessage, server) %} export function subscribe( - onDataCallback : (err?: NatsTypescriptTemplateError, msg?: {{subscribtionMessage.uid() | pascalCase}}Message.{{subscribtionMessage.uid() | pascalCase}}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void, + onDataCallback : (err?: NatsTypescriptTemplateError, msg?: {{subscribtionMessage | getMessageType}}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void, nc: Client, {% if channelParameters | length %} {{channelParameters | realizeParametersForChannel}} @@ -35,6 +35,7 @@ export function subscribe( {%- endfor %} } {%- endif %} + {%- if subscribtionMessage.payload() | messageHasNotNullPayload %} try{ let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); var processedDataReceived: any = msg.data; @@ -53,6 +54,15 @@ export function subscribe( {%- set counter = counter+1 %} {%- endfor %} {%- endif %}); + {%- else %} + onDataCallback(undefined, null{% if channelParameters | length %}, + {%- set counter = 1 %} + {%- for parameterName, parameter in channelParameters %} + receivedTopicParameters['{{parameterName}}']{%- if counter < (channelParameters | length) %},{%- endif %} + {%- set counter = counter+1 %} + {%- endfor %} + {%- endif %}); + {%- endif %} } }, subscribeOptions); resolve(subscription); diff --git a/partials/index/Publish.njk b/partials/index/Publish.njk index 7dc675e27..62c9909bd 100644 --- a/partials/index/Publish.njk +++ b/partials/index/Publish.njk @@ -4,7 +4,7 @@ * {{messageDescription}} * @param requestMessage The message to publish. */ - public publishTo{{channelName | pascalCase }}(requestMessage: {{ message.uid() | pascalCase }}Message.{{ message.uid() | pascalCase }} {% if channelParameters | length %} + public publishTo{{channelName | pascalCase }}(requestMessage: {{message | getMessageType}} {% if channelParameters | length %} ,{{channelParameters | realizeParametersForChannel}} {% endif %}): Promise { {%- if message.contentType() | isBinaryPayload(defaultContentType) %} diff --git a/partials/index/Reply.njk b/partials/index/Reply.njk index b09dab545..33be3ba3d 100644 --- a/partials/index/Reply.njk +++ b/partials/index/Reply.njk @@ -8,9 +8,9 @@ public replyTo{{channelName | pascalCase }}( onRequest : ( err?: NatsTypescriptTemplateError, - msg?: {{ publishMessage.uid() | pascalCase }}Message.{{ publishMessage.uid() | pascalCase }} + msg?: {{publishMessage | getMessageType}} {%- if channelParameters | length %},{{channelParameters | realizeParametersForChannel(false)}}{% endif %} - ) => {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{ subscribeMessage.uid() | pascalCase }}Message.{{ subscribeMessage.uid() | pascalCase }}{%- if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError : (err: NatsTypescriptTemplateError) => void + ) => {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{subscribeMessage | getMessageType}}{%- if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError : (err: NatsTypescriptTemplateError) => void {% if channelParameters | length %} ,{{channelParameters | realizeParametersForChannel}} {% endif %}): Promise { diff --git a/partials/index/Request.njk b/partials/index/Request.njk index 9a929dfcb..39d17bbf1 100644 --- a/partials/index/Request.njk +++ b/partials/index/Request.njk @@ -4,10 +4,10 @@ * {{messageDescription}} * @param requestMessage The request message to send. */ - public request{{channelName | pascalCase }}(requestMessage: {{ subscribeMessage.uid() | pascalCase }}Message.{{ subscribeMessage.uid() | pascalCase }} + public request{{channelName | pascalCase }}(requestMessage:{{subscribeMessage | getMessageType}} {% if channelParameters | length %} ,{{channelParameters | realizeParametersForChannel}} - {% endif %}): Promise<{{ publishMessage.uid() | pascalCase }}Message.{{ publishMessage.uid() | pascalCase }}> { + {% endif %}): Promise<{{publishMessage | getMessageType}}> { {%- if subscribeMessage.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; {%- endif %} diff --git a/partials/index/Subscribe.njk b/partials/index/Subscribe.njk index 26c73024e..65453ae9a 100644 --- a/partials/index/Subscribe.njk +++ b/partials/index/Subscribe.njk @@ -4,7 +4,7 @@ * {{messageDescription}} * @param onDataCallback Called when message recieved. */ - public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsTypescriptTemplateError, msg?: {{ message.uid() | pascalCase }}Message.{{ message.uid() | pascalCase }}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void {% if channelParameters | length %} + public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsTypescriptTemplateError, msg?: {{message | getMessageType}}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void {% if channelParameters | length %} ,{{channelParameters | realizeParametersForChannel}} {% endif %}): Promise { {%- if message.contentType() | isBinaryPayload(defaultContentType) %} From 09bd60aac80b54da5fadf79afce7668eb315bb0f Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 20 Jul 2020 14:08:07 +0200 Subject: [PATCH 060/110] Fixed runtime errors for connection options. --- partials/index/Standard.njk | 59 ++++++++++++------------------------- 1 file changed, 19 insertions(+), 40 deletions(-) diff --git a/partials/index/Standard.njk b/partials/index/Standard.njk index 022fcd38e..d075eb34d 100644 --- a/partials/index/Standard.njk +++ b/partials/index/Standard.njk @@ -107,65 +107,44 @@ * Try to connect to the NATS server with user credentials */ async connectWithUserCreds(userCreds: string, options?: NatsConnectionOptions){ - if(!options){ - options = { - userCreds: userCreds - }; - }else{ - options.userCreds = userCreds; - } - await this.connect(options); + await this.connect({ + userCreds: userCreds, + ... options + }); } /** * Try to connect to the NATS server with user and password */ async connectWithUserPass(user: string, pass: string, options?: NatsConnectionOptions){ - if(!options){ - options = { - user: user, - pass: pass - }; - }else{ - options.user = user; - options.pass = pass; - } - await this.connect(options); + await this.connect({ + user: user, + pass: pass, + ... options + }); } /** * Try to connect to the NATS server which has no authentication */ async connectToHost(host: string, options?: NatsConnectionOptions){ - if(!options){ - options = { - servers: [host] - }; - }else{ - options.servers = [host]; - } - await this.connect(options); + await this.connect({ + servers: [host], + ... options + }); } /** * Try to connect to the NATS server with nkey authentication */ async connectWithNkey(publicNkey: string, seed: string, options?: NatsConnectionOptions){ - if(!options){ - options = { - nkey: publicNkey, - nonceSigner: (nonce: string): Buffer => { - const sk = fromSeed(Buffer.from(seed)); - return sk.sign(Buffer.from(nonce)); - } - }; - }else{ - options.nkey = publicNkey; - options.nonceSigner = (nonce: string): Buffer => { + await this.connect({ + nkey: publicNkey, + nonceSigner: (nonce: string): Buffer => { const sk = fromSeed(Buffer.from(seed)); return sk.sign(Buffer.from(nonce)); - } - } - await this.connect(options); + }, + ... options + }); } /** From d8c82aa408b02bd3cb7a3855edd11c3d83612d2e Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Tue, 21 Jul 2020 03:23:45 +0200 Subject: [PATCH 061/110] Fixed messages was not generated when messages directory did not exist. --- hooks/quicktype-schema.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hooks/quicktype-schema.js b/hooks/quicktype-schema.js index 58554076b..106ccc4aa 100644 --- a/hooks/quicktype-schema.js +++ b/hooks/quicktype-schema.js @@ -10,7 +10,10 @@ async function genSchema(schemaPath, schemaName, jsonSchema){ inputData.addInput(schemaInput) //const { lines } = await quicktype({ lang: "java", inputData, rendererOptions: { 'justTypes': 'true', 'packageName': schemaName} }); const { lines } = await quicktype({ lang: "typescript", inputData }); - fs.writeFileSync(schemaPath, lines.join("\n")); + await fs.promises.mkdir(schemaPath, { recursive: true }).catch(console.error); + fs.mkdirSync(schemaPath, { recursive: true }); + fs.writeFileSync(Path.join(schemaPath, filters.pascalCase(schemaName)+".ts"), lines.join("\n")); + } module.exports = { 'generate:after': async (generator) => { @@ -18,7 +21,7 @@ module.exports = { for (let [messageId, message] of allMessages) { const payloadSchema = message.payload(); if(payloadSchema.type()+"" != "null"){ - const filepath = Path.join(generator.targetDir, "src/messages/", filters.pascalCase(messageId)+".ts"); + const filepath = Path.join(generator.targetDir, "src/messages/"); await genSchema(filepath, messageId, message.payload()); } } From b7720625d9026f648d4a0c89fa658ed766b2d6d9 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 23 Jul 2020 01:52:17 +0200 Subject: [PATCH 062/110] Refactoring and removing dead code. --- filters/all.js | 169 +------------------------------------ hooks/filename-change.js | 3 + hooks/quicktype-schema.js | 26 +++--- hooks/remove-test-files.js | 12 ++- hooks/rename-njk.js | 9 ++ 5 files changed, 37 insertions(+), 182 deletions(-) diff --git a/filters/all.js b/filters/all.js index 7c7e67d00..787ad509b 100644 --- a/filters/all.js +++ b/filters/all.js @@ -103,18 +103,6 @@ function pascalCase(string) { return string.charAt(0).toUpperCase() + string.slice(1); } - - - - - - - - - -filter.firstLowerCase = string => { - return _.lowerFirst(string); -} filter.firstUpperCase = string => { return string.charAt(0).toUpperCase() + string.slice(1); } @@ -129,14 +117,6 @@ filter.camelCase = string => { return camelCase(string); } - - - - - - - - function toTsType(jsonSchemaType, property) { switch (jsonSchemaType.toLowerCase()) { case 'string': @@ -155,13 +135,7 @@ function toTsType(jsonSchemaType, property) { default: return 'any'; } } -filter.toTsType = toTsType -filter.objectSchema = (asyncapi) => { - const objectMap = {}; - asyncapi.allSchemas().forEach((schema, schemaId) => { if (schema.type() === 'object') objectMap[schemaId] = schema; }); - return objectMap; -} filter.realizeChannelName = (parameters, channelName) => { let returnString = '\`' + channelName + '\`'; returnString = returnString.replace(/\//g, `.`); @@ -173,6 +147,7 @@ filter.realizeChannelName = (parameters, channelName) => { filter.realizeChannelNameWithoutParameters = (channelName) => { return toNatsChannel(channelName, null) } + function toNatsChannel(channelName, parameters){ let returnString = '\`' + channelName + '\`'; returnString = returnString.replace(/\//g, `.`); @@ -206,149 +181,7 @@ filter.realizeParametersForChannel = (parameters, required = true) => { } return returnString; } -filter.messageConstructorParameters = schema => { - let returnString = ''; - if (schema.allOf()) { - schema.allOf().forEach(element => { - returnString += `${camelCase(element.uid())}: ${pascalCase( - element.uid() - )}Schema,`; - }); - } - if (schema.uid() && schema.type() === "object") { - returnString += `${camelCase(schema.uid())}: ${pascalCase( - schema.uid() - )}Schema,`; - } - if (returnString.length > 1) { - returnString = returnString.slice(0, -1); - } - return returnString; -} -function genericImports(schema, imports) { - if(!imports){ - imports = {} - } - if (schema.allOf()) { - for(var allOf of schema.allOf()){ - imports = genericImports(allOf, imports); - } - } - if (schema.oneOf()) { - for(var oneOf of schema.oneOf()){ - imports = genericImports(oneOf, imports); - } - } - if (schema.anyOf()) { - for(var anyOf of schema.anyOf()){ - imports = genericImports(anyOf, imports); - } - } - if (schema.type() && schema.type() === "object"){ - imports[schema.uid()] = `import { default as ${pascalCase(schema.uid())}Schema } from '../schemas/${pascalCase(schema.uid())}';` - } - return imports; -} -function schemaImports(schema, imports) { - if(!imports){ - imports = {} - } - if (schema.allOf()) { - for(var allOf of schema.allOf()){ - imports = schemaImports(allOf, imports) - } - } - if (schema.oneOf()) { - for(var oneOf of schema.oneOf()){ - imports = schemaImports(oneOf, imports) - } - } - if (schema.anyOf()) { - for(var anyOf of schema.anyOf()){ - imports = schemaImports(anyOf, imports) - } - } - if (schema.properties()){ - for(const [_, property] of Object.entries(schema.properties())){ - imports = genericImports(property, imports) - } - } - return imports; -} -filter.genericImports = genericImports; -filter.schemaImports = schemaImports; -filter.schemaConstructorParameters = schema => { - let returnString = ''; - if (schema.allOf()) { - schema.allOf().forEach(element => { - returnString += `${camelCase(element.uid())}: ${pascalCase( - element.uid() - )},`; - }); - } - if (schema.oneOf()) { - returnString += `oneOf: ${getTypeFromOneOf(schema.oneOf())},`; - } - if (schema.anyOf()) { - schema.anyOf().forEach(element => { - returnString += `${camelCase(element.uid())}: ${pascalCase( - element.uid() - )},`; - }); - } - if (schema.type() && schema.type() === "object"){ - if (schema.properties() && schema.required()) { - for(const [propertyName, property] of Object.entries(schema.properties())){ - if(property.required()){ - returnString += `${propertyName}: ${toTsType(property.type(), property)},`; - } - } - } - }else if(schema.type()){ - returnString += `type: ${toTsType(schema.type())},`; - } - if (returnString.length > 1) { - returnString = returnString.slice(0, -1); - } - return returnString; -} - - - -function getTypeFromOneOf(oneFromSchema) { - let type = ''; - - if (oneFromSchema.oneOf().length > 0) { - type += `${getTypeFromOneOf(oneFromSchema.oneOf())}Schema`; - } - - for (var i = 0; i < oneOfSchema.length; i++) { - let schema = oneOfSchema[i]; - if (type !== '') { - type += '|'; - } - if (oneOfSchema.length == i + 1) { - type += schema.uid(); - } else { - type += schema.uid() + '|'; - } - } - return type; -} -filter.oneOfSchemaType = getTypeFromOneOf -filter.fileName = string => { - return _.camelCase(string); -} -filter.tsPayload = server => { - return 'STRING'; -} -filter.print = obj => { - console.log(JSON.stringify(obj, null, 4)) -} -filter.tsEncoding = server => { - return 'STRING'; -} filter.isPubsub = channel => { const tempChannel = channel._json; if (tempChannel.bindings && tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'pubsub') { diff --git a/hooks/filename-change.js b/hooks/filename-change.js index deb5df816..187daa0a2 100644 --- a/hooks/filename-change.js +++ b/hooks/filename-change.js @@ -1,5 +1,8 @@ const filters = require("../filters/all") +/** + * Change the filenames of templates files to match the rest. + */ module.exports = { 'setFileTemplateName': (generator, hookArguments) => { const currentFilename = hookArguments.originalFilename; diff --git a/hooks/quicktype-schema.js b/hooks/quicktype-schema.js index 106ccc4aa..1f568b95a 100644 --- a/hooks/quicktype-schema.js +++ b/hooks/quicktype-schema.js @@ -2,39 +2,39 @@ const fs = require('fs'); const Path = require('path'); const filters = require("../filters/all") const { quicktype, InputData, JSONSchemaInput, JSONSchemaStore } = require("quicktype-core"); + +/** + * Generate a typescript structure from a schema. + * + * @param {String} schemaPath Path to the folder to store the generated files + * @param {*} schemaName The name of the schema to generate + * @param {*} jsonSchema The schema to generate + */ async function genSchema(schemaPath, schemaName, jsonSchema){ const schemaString = JSON.stringify(jsonSchema.json()); const schemaInput = new JSONSchemaInput(new JSONSchemaStore()); await schemaInput.addSource({ name: schemaName, schema: schemaString }); const inputData = new InputData(); inputData.addInput(schemaInput) - //const { lines } = await quicktype({ lang: "java", inputData, rendererOptions: { 'justTypes': 'true', 'packageName': schemaName} }); const { lines } = await quicktype({ lang: "typescript", inputData }); await fs.promises.mkdir(schemaPath, { recursive: true }).catch(console.error); fs.mkdirSync(schemaPath, { recursive: true }); fs.writeFileSync(Path.join(schemaPath, filters.pascalCase(schemaName)+".ts"), lines.join("\n")); - } + +/** + * Use quicktype to generate messages with their payload. + */ module.exports = { 'generate:after': async (generator) => { const allMessages = generator.asyncapi.allMessages(); for (let [messageId, message] of allMessages) { const payloadSchema = message.payload(); + //Null payload is not supported by quicktype, and cannot be generated. if(payloadSchema.type()+"" != "null"){ const filepath = Path.join(generator.targetDir, "src/messages/"); await genSchema(filepath, messageId, message.payload()); } } - // const allSchemas = generator.asyncapi.allSchemas(); - // const objectMap = {}; - // allSchemas.forEach((schema, schemaId) => { if (schema.type() === 'object') objectMap[schemaId] = schema; }); - // for (const schema in allMessages) { - // if (objectMap.hasOwnProperty(schemaName)) { - // const schema = objectMap[schemaName]; - // const filepath = Path.join(generator.targetDir, "src/messages/", schemaName+".ts"); - // console.log(filepath); - // await genSchema(filepath, schemaName, schema); - // } - // } } }; diff --git a/hooks/remove-test-files.js b/hooks/remove-test-files.js index 4a668e82b..cafb7fec8 100644 --- a/hooks/remove-test-files.js +++ b/hooks/remove-test-files.js @@ -1,6 +1,11 @@ const fs = require('fs'); const Path = require('path'); +/** + * Remove a folder recursively. + * + * @param {string} path to recursively remove + */ const deleteFolderRecursive = function(path) { if (fs.existsSync(path) && path !== "/") { fs.readdirSync(path).forEach((file, index) => { @@ -13,7 +18,12 @@ const deleteFolderRecursive = function(path) { }); fs.rmdirSync(path); } - }; +}; + +/** + * Since we cannot have a condition on a template whether to generate something + * or not we have to remove the test client if its not specified. + */ module.exports = { 'generate:after': (generator) => { if(generator.targetDir && generator.templateParams && !generator.templateParams.generateTestClient){ diff --git a/hooks/rename-njk.js b/hooks/rename-njk.js index 477525333..65bb2c668 100644 --- a/hooks/rename-njk.js +++ b/hooks/rename-njk.js @@ -1,5 +1,10 @@ const fs = require('fs'); const path = require('path'); + +/** + * + * @param {string} dir to recursively rename files with njk extension + */ var renameAllSync = function(dir) { files = fs.readdirSync(dir); files.forEach(function(file) { @@ -16,6 +21,10 @@ var renameAllSync = function(dir) { } }); }; + +/** + * Rename all the njk files to get the correct extensions + */ module.exports = { 'generate:after': (generator) => { renameAllSync(path.resolve(generator.targetDir)); From d57f3983f673811caab69d5d83696864c456dce5 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 23 Jul 2020 02:36:49 +0200 Subject: [PATCH 063/110] Fixing if pubsub nats bindings are not specified channels are never generated. --- filters/all.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/filters/all.js b/filters/all.js index 787ad509b..a989c6d8c 100644 --- a/filters/all.js +++ b/filters/all.js @@ -184,7 +184,11 @@ filter.realizeParametersForChannel = (parameters, required = true) => { filter.isPubsub = channel => { const tempChannel = channel._json; - if (tempChannel.bindings && tempChannel.bindings.nats && tempChannel.bindings.nats.is == 'pubsub') { + if ( + !tempChannel.bindings || + !tempChannel.bindings.nats || + !tempChannel.bindings.nats.is || + tempChannel.bindings.nats.is == 'pubsub') { return true; } return false; From fa6d7e2dc695d57b521bd7cb8e2cc104dc7a1619 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 23 Jul 2020 02:45:46 +0200 Subject: [PATCH 064/110] Fixing subscribe messages use name instead of uid. --- partials/channel/Reply.njk | 2 +- partials/channel/Request.njk | 2 +- partials/channel/Subscribe.njk | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/partials/channel/Reply.njk b/partials/channel/Reply.njk index dad640a35..0456101f6 100644 --- a/partials/channel/Reply.njk +++ b/partials/channel/Reply.njk @@ -42,7 +42,7 @@ export function reply( {%- if recieveMessage.payload() | messageHasNotNullPayload %} {{OnReceivingData(false)}} - let requestData = {{recieveMessage.name() | pascalCase}}Message.Convert.to{{recieveMessage.name() | pascalCase}}(receivedData); + let requestData = {{recieveMessage.uid() | pascalCase}}Message.Convert.to{{recieveMessage.uid() | pascalCase}}(receivedData); let message = {%-if params.promisifyReplyCallback | length %}await{%- endif %} onRequest(undefined, requestData{% if channelParameters | length %}, {%- set counter = 1 %} {%- for parameterName, parameter in channelParameters %} diff --git a/partials/channel/Request.njk b/partials/channel/Request.njk index 9c32105c3..ec6ff8562 100644 --- a/partials/channel/Request.njk +++ b/partials/channel/Request.njk @@ -26,7 +26,7 @@ export function request( {%- if recieveMessage.payload() | messageHasNotNullPayload %} {{OnReceivingData(true)}} - let recievedData = {{recieveMessage.name() | pascalCase}}Message.Convert.to{{recieveMessage.name() | pascalCase}}(receivedData); + let recievedData = {{recieveMessage.uid() | pascalCase}}Message.Convert.to{{recieveMessage.uid() | pascalCase}}(receivedData); resolve(recievedData); {%- else %} resolve(null); diff --git a/partials/channel/Subscribe.njk b/partials/channel/Subscribe.njk index 872eeaf26..e4ae946e0 100644 --- a/partials/channel/Subscribe.njk +++ b/partials/channel/Subscribe.njk @@ -46,7 +46,7 @@ export function subscribe( reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); return; } - let publishedData = {{subscribtionMessage.name() | pascalCase}}Message.Convert.to{{subscribtionMessage.name() | pascalCase}}(processedDataReceived); + let publishedData = {{subscribtionMessage.uid() | pascalCase}}Message.Convert.to{{subscribtionMessage.uid() | pascalCase}}(processedDataReceived); onDataCallback(undefined, publishedData{% if channelParameters | length %}, {%- set counter = 1 %} {%- for parameterName, parameter in channelParameters %} From cb8c2f6cf9fe713b5a033e1355955a8f6fb66627 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 23 Jul 2020 02:59:19 +0200 Subject: [PATCH 065/110] Added pubsub example. --- .gitignore | 3 +- README.md | 7 + examples/publish subscribe/README.md | 0 examples/publish subscribe/generate.sh | 3 + examples/publish subscribe/streetlight.json | 63 + .../publish subscribe/streetlight/README.md | 7 + .../streetlight/package-lock.json | 1082 +++++++++++++++++ .../streetlight/package.json | 29 + .../src/NatsTypescriptTemplateError.ts | 70 ++ .../StreetlightStreetlightIdCommandTurnon.ts | 48 + .../StreetlightStreetlightIdEventTurnon.ts | 35 + .../streetlight/src/hooks.ts | 57 + .../streetlight/src/index.ts | 243 ++++ .../src/messages/AnonymousMessage1.ts | 162 +++ .../src/messages/SubscribeToTurnonCommand.ts | 162 +++ .../streetlight/src/tests/testclient/index.ts | 239 ++++ .../StreetlightStreetlightIdCommandTurnon.ts | 35 + .../StreetlightStreetlightIdEventTurnon.ts | 48 + .../streetlight/tsconfig.json | 16 + 19 files changed, 2308 insertions(+), 1 deletion(-) create mode 100644 examples/publish subscribe/README.md create mode 100644 examples/publish subscribe/generate.sh create mode 100644 examples/publish subscribe/streetlight.json create mode 100644 examples/publish subscribe/streetlight/README.md create mode 100644 examples/publish subscribe/streetlight/package-lock.json create mode 100644 examples/publish subscribe/streetlight/package.json create mode 100644 examples/publish subscribe/streetlight/src/NatsTypescriptTemplateError.ts create mode 100644 examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts create mode 100644 examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts create mode 100644 examples/publish subscribe/streetlight/src/hooks.ts create mode 100644 examples/publish subscribe/streetlight/src/index.ts create mode 100644 examples/publish subscribe/streetlight/src/messages/AnonymousMessage1.ts create mode 100644 examples/publish subscribe/streetlight/src/messages/SubscribeToTurnonCommand.ts create mode 100644 examples/publish subscribe/streetlight/src/tests/testclient/index.ts create mode 100644 examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts create mode 100644 examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts create mode 100644 examples/publish subscribe/streetlight/tsconfig.json diff --git a/.gitignore b/.gitignore index 0453c489e..6a0e6aa8d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules -test/actual_comparators/* \ No newline at end of file +test/actual_comparators/* +examples/**/dist/* \ No newline at end of file diff --git a/README.md b/README.md index da560b4cc..4090d156f 100644 --- a/README.md +++ b/README.md @@ -98,3 +98,10 @@ Hooks.getInstance().registerBeforeSendingData((messageToSend: any) => { ``` ### Node.js example + + + + + + +CANNOT HAVE EMPTY OBJECTS use null instead \ No newline at end of file diff --git a/examples/publish subscribe/README.md b/examples/publish subscribe/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/examples/publish subscribe/generate.sh b/examples/publish subscribe/generate.sh new file mode 100644 index 000000000..56e9bcac5 --- /dev/null +++ b/examples/publish subscribe/generate.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +ag --install --output "./streetlight" "./streetlight.json" "../../" --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" \ No newline at end of file diff --git a/examples/publish subscribe/streetlight.json b/examples/publish subscribe/streetlight.json new file mode 100644 index 000000000..975d08951 --- /dev/null +++ b/examples/publish subscribe/streetlight.json @@ -0,0 +1,63 @@ +{ + "asyncapi": "2.0.0", + "info": { + "title": "Streetlight", + "version": "1.0.0" + }, + "defaultContentType": "json", + "channels": { + "streetlight/{streetlight_id}/command/turnon": { + "description": "Channel for the turn on command which should turn on the streetlight", + "parameters": { + "streetlight_id": { + "description": "The ID of the streetlight", + "schema": { + "type": "string" + } + } + }, + "publish": { + "operationId": "Listen when to turn on the streetlight", + "message": { + "name": "subscribeToTurnonCommand", + "payload": { + "type": "object", + "required": ["lumen"], + "properties": { + "lumen": { + "type": "integer", + "description": "How bright should the light be." + } + } + } + } + } + }, + "streetlight/{streetlight_id}/event/turnon": { + "description": "Channel for when the streetlight is turned on", + "parameters": { + "streetlight_id": { + "description": "The ID of the streetlight", + "schema": { + "type": "string" + } + } + }, + "subscribe": { + "operationId": "Publish when the streetlight gets turned on", + "message": { + "payload": { + "type": "object", + "required": ["lumen"], + "properties": { + "lumen": { + "type": "integer", + "description": "How bright should the light be." + } + } + } + } + } + } + } +} diff --git a/examples/publish subscribe/streetlight/README.md b/examples/publish subscribe/streetlight/README.md new file mode 100644 index 000000000..8efb38d46 --- /dev/null +++ b/examples/publish subscribe/streetlight/README.md @@ -0,0 +1,7 @@ +# Streetlight + + + + +Available nats encodings: +https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings diff --git a/examples/publish subscribe/streetlight/package-lock.json b/examples/publish subscribe/streetlight/package-lock.json new file mode 100644 index 000000000..44420165e --- /dev/null +++ b/examples/publish subscribe/streetlight/package-lock.json @@ -0,0 +1,1082 @@ +{ + "name": "streetlight", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/chai": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz", + "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==", + "dev": true + }, + "@types/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@types/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-Ibfb2jgpjYUxnl7RSVvUzOrv/vhkTVKEfPwQf9ZlDDsSyWVDp/2JtTBxO4eRrKBYtxc3cZQabdR38i8R0o1uww==", + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", + "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", + "dev": true + }, + "@types/node": { + "version": "13.9.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.5.tgz", + "integrity": "sha512-hkzMMD3xu6BrJpGVLeQ3htQQNAcOrJjX7WFmtK8zWQpz2UJf13LCFF2ALA7c9OVdvc2vQJeDdjfR35M0sBCxvw==" + }, + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chokidar": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mocha": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", + "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "dev": true, + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "chokidar": "3.3.0", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "3.0.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.5", + "ms": "2.1.1", + "node-environment-flags": "1.0.6", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "nuid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/nuid/-/nuid-1.1.4.tgz", + "integrity": "sha512-PXiYyHhGfrq8H4g5HyC8enO1lz6SBe5z6x1yx/JG4tmADzDGJVQy3l1sRf3VtEvPsN8dGn9hRFRwDKWL62x0BA==" + }, + "object-inspect": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "readdirp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "dev": true, + "requires": { + "picomatch": "^2.0.4" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "ts-nats": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/ts-nats/-/ts-nats-1.2.4.tgz", + "integrity": "sha512-bIC+PlwHplRqhooa9kE+QPcQ9RPGUXD2ruvdf6LoFpP6MjE6exVoRhYSydm0e5wk7VfuXpTbH1NoopTKHwlOKA==", + "requires": { + "nuid": "^1.1.0", + "ts-nkeys": "^1.0.12" + } + }, + "ts-nkeys": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/ts-nkeys/-/ts-nkeys-1.0.16.tgz", + "integrity": "sha512-1qrhAlavbm36wtW+7NtKOgxpzl+70NTF8xlz9mEhiA5zHMlMxjj3sEVKWm3pGZhHXE0Q3ykjrj+OSRVaYw+Dqg==", + "requires": { + "tweetnacl": "^1.0.3" + } + }, + "ts-node": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typescript": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.3.tgz", + "integrity": "sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + } + } +} diff --git a/examples/publish subscribe/streetlight/package.json b/examples/publish subscribe/streetlight/package.json new file mode 100644 index 000000000..66239b020 --- /dev/null +++ b/examples/publish subscribe/streetlight/package.json @@ -0,0 +1,29 @@ +{ + + + "name": "streetlight", + "description": "", + "version": "1.0.0", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "watch": "tsc --watch", + "build": "tsc", + "start": "node src/api/index.js", + "test": "mocha -r ts-node/register tests/**/*.spec.ts" + }, + "dependencies": { + "@types/klaw-sync": "^6.0.0", + "@types/node": "13.9.5", + "ts-nats": "1.2.4", + "typescript": "3.4.3", + "ts-nkeys":"1.0.16" + }, + "devDependencies": { + "@types/chai": "^4.2.11", + "@types/mocha": "^7.0.2", + "chai": "^4.2.0", + "mocha": "^7.1.1", + "ts-node": "^8.8.1" + } +} diff --git a/examples/publish subscribe/streetlight/src/NatsTypescriptTemplateError.ts b/examples/publish subscribe/streetlight/src/NatsTypescriptTemplateError.ts new file mode 100644 index 000000000..07ad37c3e --- /dev/null +++ b/examples/publish subscribe/streetlight/src/NatsTypescriptTemplateError.ts @@ -0,0 +1,70 @@ + +import * as util from 'util'; + +export enum ErrorCode { + NOT_CONNECTED = 'NOT_CONNECTED', + INTERNAL_NATS_TS_ERROR = 'INTERNAL_NATS_TS_ERROR', + HOOK_ERROR = 'HOOK_ERROR' +} + +/** @internal **/ +export class Messages { + static messages = new Messages(); + messages: { [key: string]: string } = {}; + + private constructor() { + this.messages[ErrorCode.NOT_CONNECTED] = 'The client is not connected'; + this.messages[ErrorCode.INTERNAL_NATS_TS_ERROR] = 'An error occured while trying to use the Nats Typescript library'; + this.messages[ErrorCode.HOOK_ERROR] = 'An error occured while trying to call one of the hooks.'; + } + + static getMessage(s: string): string { + return Messages.messages.getMessage(s); + } + + getMessage(s: string): string { + let v = this.messages[s]; + if (!v) { + v = s; + } + return v; + } +} +export class NatsTypescriptTemplateError implements Error { + + name: string; + message: string; + code: string; + chainedError?: Error; + + /** + * @param {String} message + * @param {String} code + * @param {Error} [chainedError] + * @constructor + * + * @api private + * @internal + */ + constructor(message: string, code: string, chainedError?: Error) { + Error.captureStackTrace(this, this.constructor); + this.name = 'NatsTypescriptTemplateError'; + this.message = message; + this.code = code; + this.chainedError = chainedError; + + util.inherits(NatsTypescriptTemplateError, Error); + } + + /** + * @param code + * @param chainedError + * @api private + * @internal + */ + static errorForCode(code: string, chainedError?: Error): NatsTypescriptTemplateError { + let m = Messages.getMessage(code); + return new NatsTypescriptTemplateError(m, code, chainedError); + } +} + diff --git a/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts b/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts new file mode 100644 index 000000000..b411ad58b --- /dev/null +++ b/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts @@ -0,0 +1,48 @@ + +import * as SubscribeToTurnonCommandMessage from '../messages/SubscribeToTurnonCommand' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {ErrorCode, NatsTypescriptTemplateError} from '../NatsTypescriptTemplateError'; +import { Hooks } from '../hooks'; + +export function subscribe( + onDataCallback : (err?: NatsTypescriptTemplateError, msg?: SubscribeToTurnonCommandMessage.SubscribeToTurnonCommand, streetlight_id?: string) => void, + nc: Client, + + streetlight_id: string + + ): Promise { + return new Promise(async (resolve, reject) => { + let subscribeOptions: SubscriptionOptions = {}; + + try{ + let subscription = nc.subscribe(`streetlight.${streetlight_id}.command.turnon`, (err, msg) => { + if(err){ + onDataCallback(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, err)); + }else{ + const unmodifiedChannel = `streetlight.{streetlight_id}.command.turnon` + const receivedTopicParameters = { + streetlight_id : msg.subject.slice(unmodifiedChannel.split("${streetlight_id}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlight_id}")[1].length) + } + try{ + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived: any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + return; + } + let publishedData = SubscribeToTurnonCommandMessage.Convert.toSubscribeToTurnonCommand(processedDataReceived); + onDataCallback(undefined, publishedData, + receivedTopicParameters['streetlight_id']); + } + }, subscribeOptions); + resolve(subscription); + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); + } + }) +} + + diff --git a/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts b/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts new file mode 100644 index 000000000..812a45e75 --- /dev/null +++ b/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts @@ -0,0 +1,35 @@ + +import * as AnonymousMessage1Message from '../messages/AnonymousMessage1' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {ErrorCode, NatsTypescriptTemplateError} from '../NatsTypescriptTemplateError'; +import { Hooks } from '../hooks'; + +export function publish( + message: AnonymousMessage1Message.AnonymousMessage1, + nc: Client, + + streetlight_id: string + + ): Promise { + return new Promise(async (resolve, reject) => { + try{ + +try{ + let beforeSendingHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToSend : any = message; + for(let hook of beforeSendingHooks){ + dataToSend = hook(dataToSend); + } +}catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + return; +} + + nc.publish(`streetlight.${streetlight_id}.event.turnon`, dataToSend); + resolve(); + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); + } + }); +}; + diff --git a/examples/publish subscribe/streetlight/src/hooks.ts b/examples/publish subscribe/streetlight/src/hooks.ts new file mode 100644 index 000000000..321b9085c --- /dev/null +++ b/examples/publish subscribe/streetlight/src/hooks.ts @@ -0,0 +1,57 @@ +export enum AvailableHooks { + RecievedData = 'RecievedData', + BeforeSendingData = 'BeforeSendingData' +} +export type RecievedDataHook = (receivedData: any) => string; +export type BeforeSendingDataHook = (messageToSend: any) => string; +export class Hooks { + private static instance: Hooks; + + private hooks: { + BeforeSendingData: BeforeSendingDataHook[]; + RecievedData: RecievedDataHook[]; + }; + private constructor() { + this.hooks = { + BeforeSendingData: [], + RecievedData: [] + } + } + public static getInstance(): Hooks { + if (!Hooks.instance) { + Hooks.instance = new Hooks(); + } + return Hooks.instance; + } + + + + /** + * Register a hook for BeforeSendingData + * @param hook + */ + public async registerBeforeSendingData(hook: BeforeSendingDataHook) { + this.hooks[AvailableHooks.BeforeSendingData] + ? this.hooks[AvailableHooks.BeforeSendingData].push(hook) + : [hook]; + } + + /** + * Register a hook for BeforeSendingData + * @param hook + */ + public async registerRecievedData(hook: RecievedDataHook) { + this.hooks[AvailableHooks.RecievedData] + ? this.hooks[AvailableHooks.RecievedData].push(hook) + : [hook]; + } + + + public getRecievedDataHook(): RecievedDataHook[] { + return this.hooks[AvailableHooks.RecievedData]; + } + + public getBeforeSendingDataHook(): BeforeSendingDataHook[] { + return this.hooks[AvailableHooks.BeforeSendingData]; + } +} \ No newline at end of file diff --git a/examples/publish subscribe/streetlight/src/index.ts b/examples/publish subscribe/streetlight/src/index.ts new file mode 100644 index 000000000..f62a6d5fc --- /dev/null +++ b/examples/publish subscribe/streetlight/src/index.ts @@ -0,0 +1,243 @@ + + + + +import {fromSeed} from 'ts-nkeys'; +import {AvailableHooks, RecievedDataHook, BeforeSendingDataHook, Hooks} from './hooks'; +export {AvailableHooks, RecievedDataHook, BeforeSendingDataHook, Hooks} +import * as TestClient from './tests/testclient/'; +export { TestClient }; +import {ErrorCode, NatsTypescriptTemplateError} from './NatsTypescriptTemplateError'; +export {ErrorCode, NatsTypescriptTemplateError} +import { + Client, + NatsConnectionOptions, + connect, + Payload, + NatsError, + Subscription, + ServersChangedEvent, + SubEvent, + ServerInfo + } from 'ts-nats'; +import * as streetlightStreetlightIdCommandTurnonChannel from "./channels/StreetlightStreetlightIdCommandTurnon"; +export {streetlightStreetlightIdCommandTurnonChannel}; +import * as streetlightStreetlightIdEventTurnonChannel from "./channels/StreetlightStreetlightIdEventTurnon"; +export {streetlightStreetlightIdEventTurnonChannel}; +import * as SubscribeToTurnonCommandMessage from "./messages/SubscribeToTurnonCommand"; +export {SubscribeToTurnonCommandMessage}; +import * as AnonymousMessage1Message from "./messages/AnonymousMessage1"; +export {AnonymousMessage1Message}; + + +import * as events from 'events'; +export enum AvailableEvents { + permissionError = 'permissionError', + close = 'close', + connect = 'connect', + connecting = 'connecting', + disconnect = 'disconnect', + error = 'error', + pingcount = 'pingcount', + pingtimer = 'pingtimer', + reconnect = 'reconnect', + reconnecting = 'reconnecting', + serversChanged = 'serversChanged', + subscribe = 'subscribe', + unsubscribe = 'unsubscribe', + yield = 'yield' +} +export declare interface NatsAsyncApiClient { + on(event: AvailableEvents.permissionError, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.close, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; + on(event: AvailableEvents.connecting, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.error, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.pingcount, listener: () => void): this; + on(event: AvailableEvents.pingtimer, listener: () => void): this; + on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; + on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; + on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.yield, listener: () => void): this; +} +export class NatsAsyncApiClient extends events.EventEmitter{ + + + public jsonClient?: Client; + public stringClient?: Client; + public binaryClient?: Client; + public options?: NatsConnectionOptions; + + /** + * + * @param options options to use, payload is omitted if sat in the AsyncAPI document. + */ + constructor() { + super(); + } + /** + * Try to connect to the NATS server with the different payloads. + */ + connect(options : NatsConnectionOptions): Promise{ + return new Promise(async (resolve: () => void, reject: (error: any) => void) => { + this.options = this.setDefaultOptions(options); + try{ + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); + resolve(); + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); + } + }) + } + + + /** + * Disconnect all clients from the server + */ + async disconnect(){ + this.jsonClient!.close() + } + + private chainEvents(ns: Client){ + ns.on('permissionError', (e: NatsError) => { + this.emit(AvailableEvents.permissionError, NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)) + }); + ns.on('close', (e: NatsError) => { + this.emit(AvailableEvents.close, NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)) + }); + ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.connect, connection, serverURL, info) + }); + ns.on('connecting', (serverURL: string) => { + this.emit(AvailableEvents.connecting, serverURL) + }); + ns.on('disconnect', (serverURL: string) => { + this.emit(AvailableEvents.disconnect, serverURL) + }); + ns.on('error', (e: NatsError) => { + this.emit(AvailableEvents.error, NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)) + }); + ns.on('pingcount', () => { + this.emit(AvailableEvents.pingcount) + }); + ns.on('pingtimer', () => { + this.emit(AvailableEvents.pingtimer) + }); + ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.reconnect, connection, serverURL, info) + }); + ns.on('reconnecting', (serverURL: string) => { + this.emit(AvailableEvents.reconnecting, serverURL) + }); + ns.on('serversChanged', (e: ServersChangedEvent) => { + this.emit(AvailableEvents.serversChanged, e) + }); + ns.on('subscribe', (e: SubEvent) => { + this.emit(AvailableEvents.subscribe, e) + }); + ns.on('unsubscribe', (e: SubEvent) => { + this.emit(AvailableEvents.unsubscribe, e) + }); + ns.on('yield', () => { + this.emit(AvailableEvents.yield) + }); + } + + /** + * Try to connect to the NATS server with user credentials + */ + async connectWithUserCreds(userCreds: string, options?: NatsConnectionOptions){ + await this.connect({ + userCreds: userCreds, + ... options + }); + } + /** + * Try to connect to the NATS server with user and password + */ + async connectWithUserPass(user: string, pass: string, options?: NatsConnectionOptions){ + await this.connect({ + user: user, + pass: pass, + ... options + }); + } + + /** + * Try to connect to the NATS server which has no authentication + */ + async connectToHost(host: string, options?: NatsConnectionOptions){ + await this.connect({ + servers: [host], + ... options + }); + } + + /** + * Try to connect to the NATS server with nkey authentication + */ + async connectWithNkey(publicNkey: string, seed: string, options?: NatsConnectionOptions){ + await this.connect({ + nkey: publicNkey, + nonceSigner: (nonce: string): Buffer => { + const sk = fromSeed(Buffer.from(seed)); + return sk.sign(Buffer.from(nonce)); + }, + ... options + }); + } + + /** + * Set the default options based on the AsyncAPI file. + * @param options to set + */ + private setDefaultOptions(options: NatsConnectionOptions){ + //If server binding options sat set the options + options.encoding = 'utf8'; + return options; + } + + + /** + * Channel for the turn on command which should turn on the streetlight + * @param onDataCallback Called when message recieved. + */ + public subscribeToStreetlightStreetlightIdCommandTurnon(onDataCallback : (err?: NatsTypescriptTemplateError, msg?: SubscribeToTurnonCommandMessage.SubscribeToTurnonCommand, streetlight_id?: string) => void + ,streetlight_id: string + ): Promise { + const nc: Client = this.jsonClient!; + if(nc){ + return streetlightStreetlightIdCommandTurnonChannel.subscribe(onDataCallback, nc + + ,streetlight_id + ); + }else{ + return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); + } + } + + + /** + * Channel for when the streetlight is turned on + * @param requestMessage The message to publish. + */ + public publishToStreetlightStreetlightIdEventTurnon(requestMessage: AnonymousMessage1Message.AnonymousMessage1 + ,streetlight_id: string + ): Promise { + const nc: Client = this.jsonClient!; + if(nc){ + return streetlightStreetlightIdEventTurnonChannel.publish(requestMessage, nc + + ,streetlight_id + ); + }else{ + return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); + } + } + +} diff --git a/examples/publish subscribe/streetlight/src/messages/AnonymousMessage1.ts b/examples/publish subscribe/streetlight/src/messages/AnonymousMessage1.ts new file mode 100644 index 000000000..bc9ef82eb --- /dev/null +++ b/examples/publish subscribe/streetlight/src/messages/AnonymousMessage1.ts @@ -0,0 +1,162 @@ +// To parse this data: +// +// import { Convert, AnonymousMessage1 } from "./file"; +// +// const anonymousMessage1 = Convert.toAnonymousMessage1(json); +// +// These functions will throw an error if the JSON doesn't +// match the expected interface, even if the JSON is valid. + +export interface AnonymousMessage1 { + /** + * How bright should the light be. + */ + lumen: number; +} + +// Converts JSON strings to/from your types +// and asserts the results of JSON.parse at runtime +export class Convert { + public static toAnonymousMessage1(json: string): AnonymousMessage1 { + return cast(JSON.parse(json), r("AnonymousMessage1")); + } + + public static anonymousMessage1ToJson(value: AnonymousMessage1): string { + return JSON.stringify(uncast(value, r("AnonymousMessage1")), null, 2); + } +} + +function invalidValue(typ: any, val: any): never { + throw Error(`Invalid value ${JSON.stringify(val)} for type ${JSON.stringify(typ)}`); +} + +function jsonToJSProps(typ: any): any { + if (typ.jsonToJS === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ }); + typ.jsonToJS = map; + } + return typ.jsonToJS; +} + +function jsToJSONProps(typ: any): any { + if (typ.jsToJSON === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ }); + typ.jsToJSON = map; + } + return typ.jsToJSON; +} + +function transform(val: any, typ: any, getProps: any): any { + function transformPrimitive(typ: string, val: any): any { + if (typeof typ === typeof val) return val; + return invalidValue(typ, val); + } + + function transformUnion(typs: any[], val: any): any { + // val must validate against one typ in typs + const l = typs.length; + for (let i = 0; i < l; i++) { + const typ = typs[i]; + try { + return transform(val, typ, getProps); + } catch (_) {} + } + return invalidValue(typs, val); + } + + function transformEnum(cases: string[], val: any): any { + if (cases.indexOf(val) !== -1) return val; + return invalidValue(cases, val); + } + + function transformArray(typ: any, val: any): any { + // val must be an array with no invalid elements + if (!Array.isArray(val)) return invalidValue("array", val); + return val.map(el => transform(el, typ, getProps)); + } + + function transformDate(val: any): any { + if (val === null) { + return null; + } + const d = new Date(val); + if (isNaN(d.valueOf())) { + return invalidValue("Date", val); + } + return d; + } + + function transformObject(props: { [k: string]: any }, additional: any, val: any): any { + if (val === null || typeof val !== "object" || Array.isArray(val)) { + return invalidValue("object", val); + } + const result: any = {}; + Object.getOwnPropertyNames(props).forEach(key => { + const prop = props[key]; + const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined; + result[prop.key] = transform(v, prop.typ, getProps); + }); + Object.getOwnPropertyNames(val).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(props, key)) { + result[key] = transform(val[key], additional, getProps); + } + }); + return result; + } + + if (typ === "any") return val; + if (typ === null) { + if (val === null) return val; + return invalidValue(typ, val); + } + if (typ === false) return invalidValue(typ, val); + while (typeof typ === "object" && typ.ref !== undefined) { + typ = typeMap[typ.ref]; + } + if (Array.isArray(typ)) return transformEnum(typ, val); + if (typeof typ === "object") { + return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) + : invalidValue(typ, val); + } + // Numbers can be parsed by Date but shouldn't be. + if (typ === Date && typeof val !== "number") return transformDate(val); + return transformPrimitive(typ, val); +} + +function cast(val: any, typ: any): T { + return transform(val, typ, jsonToJSProps); +} + +function uncast(val: T, typ: any): any { + return transform(val, typ, jsToJSONProps); +} + +function a(typ: any) { + return { arrayItems: typ }; +} + +function u(...typs: any[]) { + return { unionMembers: typs }; +} + +function o(props: any[], additional: any) { + return { props, additional }; +} + +function m(additional: any) { + return { props: [], additional }; +} + +function r(name: string) { + return { ref: name }; +} + +const typeMap: any = { + "AnonymousMessage1": o([ + { json: "lumen", js: "lumen", typ: 0 }, + ], "any"), +}; diff --git a/examples/publish subscribe/streetlight/src/messages/SubscribeToTurnonCommand.ts b/examples/publish subscribe/streetlight/src/messages/SubscribeToTurnonCommand.ts new file mode 100644 index 000000000..1cafd79de --- /dev/null +++ b/examples/publish subscribe/streetlight/src/messages/SubscribeToTurnonCommand.ts @@ -0,0 +1,162 @@ +// To parse this data: +// +// import { Convert, SubscribeToTurnonCommand } from "./file"; +// +// const subscribeToTurnonCommand = Convert.toSubscribeToTurnonCommand(json); +// +// These functions will throw an error if the JSON doesn't +// match the expected interface, even if the JSON is valid. + +export interface SubscribeToTurnonCommand { + /** + * How bright should the light be. + */ + lumen: number; +} + +// Converts JSON strings to/from your types +// and asserts the results of JSON.parse at runtime +export class Convert { + public static toSubscribeToTurnonCommand(json: string): SubscribeToTurnonCommand { + return cast(JSON.parse(json), r("SubscribeToTurnonCommand")); + } + + public static subscribeToTurnonCommandToJson(value: SubscribeToTurnonCommand): string { + return JSON.stringify(uncast(value, r("SubscribeToTurnonCommand")), null, 2); + } +} + +function invalidValue(typ: any, val: any): never { + throw Error(`Invalid value ${JSON.stringify(val)} for type ${JSON.stringify(typ)}`); +} + +function jsonToJSProps(typ: any): any { + if (typ.jsonToJS === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ }); + typ.jsonToJS = map; + } + return typ.jsonToJS; +} + +function jsToJSONProps(typ: any): any { + if (typ.jsToJSON === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ }); + typ.jsToJSON = map; + } + return typ.jsToJSON; +} + +function transform(val: any, typ: any, getProps: any): any { + function transformPrimitive(typ: string, val: any): any { + if (typeof typ === typeof val) return val; + return invalidValue(typ, val); + } + + function transformUnion(typs: any[], val: any): any { + // val must validate against one typ in typs + const l = typs.length; + for (let i = 0; i < l; i++) { + const typ = typs[i]; + try { + return transform(val, typ, getProps); + } catch (_) {} + } + return invalidValue(typs, val); + } + + function transformEnum(cases: string[], val: any): any { + if (cases.indexOf(val) !== -1) return val; + return invalidValue(cases, val); + } + + function transformArray(typ: any, val: any): any { + // val must be an array with no invalid elements + if (!Array.isArray(val)) return invalidValue("array", val); + return val.map(el => transform(el, typ, getProps)); + } + + function transformDate(val: any): any { + if (val === null) { + return null; + } + const d = new Date(val); + if (isNaN(d.valueOf())) { + return invalidValue("Date", val); + } + return d; + } + + function transformObject(props: { [k: string]: any }, additional: any, val: any): any { + if (val === null || typeof val !== "object" || Array.isArray(val)) { + return invalidValue("object", val); + } + const result: any = {}; + Object.getOwnPropertyNames(props).forEach(key => { + const prop = props[key]; + const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined; + result[prop.key] = transform(v, prop.typ, getProps); + }); + Object.getOwnPropertyNames(val).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(props, key)) { + result[key] = transform(val[key], additional, getProps); + } + }); + return result; + } + + if (typ === "any") return val; + if (typ === null) { + if (val === null) return val; + return invalidValue(typ, val); + } + if (typ === false) return invalidValue(typ, val); + while (typeof typ === "object" && typ.ref !== undefined) { + typ = typeMap[typ.ref]; + } + if (Array.isArray(typ)) return transformEnum(typ, val); + if (typeof typ === "object") { + return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) + : invalidValue(typ, val); + } + // Numbers can be parsed by Date but shouldn't be. + if (typ === Date && typeof val !== "number") return transformDate(val); + return transformPrimitive(typ, val); +} + +function cast(val: any, typ: any): T { + return transform(val, typ, jsonToJSProps); +} + +function uncast(val: T, typ: any): any { + return transform(val, typ, jsToJSONProps); +} + +function a(typ: any) { + return { arrayItems: typ }; +} + +function u(...typs: any[]) { + return { unionMembers: typs }; +} + +function o(props: any[], additional: any) { + return { props, additional }; +} + +function m(additional: any) { + return { props: [], additional }; +} + +function r(name: string) { + return { ref: name }; +} + +const typeMap: any = { + "SubscribeToTurnonCommand": o([ + { json: "lumen", js: "lumen", typ: 0 }, + ], "any"), +}; diff --git a/examples/publish subscribe/streetlight/src/tests/testclient/index.ts b/examples/publish subscribe/streetlight/src/tests/testclient/index.ts new file mode 100644 index 000000000..d8d97e7a1 --- /dev/null +++ b/examples/publish subscribe/streetlight/src/tests/testclient/index.ts @@ -0,0 +1,239 @@ + + +import {fromSeed} from 'ts-nkeys'; +import {ErrorCode, NatsTypescriptTemplateError} from '../../NatsTypescriptTemplateError'; +import { + Client, + NatsConnectionOptions, + connect, + Payload, + NatsError, + Subscription, + ServersChangedEvent, + SubEvent, + ServerInfo + } from 'ts-nats'; +import * as streetlightStreetlightIdCommandTurnonChannel from "./testchannels/StreetlightStreetlightIdCommandTurnon"; +export {streetlightStreetlightIdCommandTurnonChannel}; +import * as streetlightStreetlightIdEventTurnonChannel from "./testchannels/StreetlightStreetlightIdEventTurnon"; +export {streetlightStreetlightIdEventTurnonChannel}; +import * as SubscribeToTurnonCommandMessage from "../../messages/SubscribeToTurnonCommand"; +export {SubscribeToTurnonCommandMessage}; +import * as AnonymousMessage1Message from "../../messages/AnonymousMessage1"; +export {AnonymousMessage1Message}; + + + +import * as events from 'events'; +export enum AvailableEvents { + permissionError = 'permissionError', + close = 'close', + connect = 'connect', + connecting = 'connecting', + disconnect = 'disconnect', + error = 'error', + pingcount = 'pingcount', + pingtimer = 'pingtimer', + reconnect = 'reconnect', + reconnecting = 'reconnecting', + serversChanged = 'serversChanged', + subscribe = 'subscribe', + unsubscribe = 'unsubscribe', + yield = 'yield' +} +export declare interface NatsAsyncApiTestClient { + on(event: AvailableEvents.permissionError, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.close, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; + on(event: AvailableEvents.connecting, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.error, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.pingcount, listener: () => void): this; + on(event: AvailableEvents.pingtimer, listener: () => void): this; + on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; + on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; + on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.yield, listener: () => void): this; +} +export class NatsAsyncApiTestClient extends events.EventEmitter{ + + + + public jsonClient?: Client; + public stringClient?: Client; + public binaryClient?: Client; + public options?: NatsConnectionOptions; + + /** + * + * @param options options to use, payload is omitted if sat in the AsyncAPI document. + */ + constructor() { + super(); + } + /** + * Try to connect to the NATS server with the different payloads. + */ + connect(options : NatsConnectionOptions): Promise{ + return new Promise(async (resolve: () => void, reject: (error: any) => void) => { + this.options = this.setDefaultOptions(options); + try{ + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); + resolve(); + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); + } + }) + } + + + /** + * Disconnect all clients from the server + */ + async disconnect(){ + this.jsonClient!.close() + } + + private chainEvents(ns: Client){ + ns.on('permissionError', (e: NatsError) => { + this.emit(AvailableEvents.permissionError, NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)) + }); + ns.on('close', (e: NatsError) => { + this.emit(AvailableEvents.close, NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)) + }); + ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.connect, connection, serverURL, info) + }); + ns.on('connecting', (serverURL: string) => { + this.emit(AvailableEvents.connecting, serverURL) + }); + ns.on('disconnect', (serverURL: string) => { + this.emit(AvailableEvents.disconnect, serverURL) + }); + ns.on('error', (e: NatsError) => { + this.emit(AvailableEvents.error, NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)) + }); + ns.on('pingcount', () => { + this.emit(AvailableEvents.pingcount) + }); + ns.on('pingtimer', () => { + this.emit(AvailableEvents.pingtimer) + }); + ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.reconnect, connection, serverURL, info) + }); + ns.on('reconnecting', (serverURL: string) => { + this.emit(AvailableEvents.reconnecting, serverURL) + }); + ns.on('serversChanged', (e: ServersChangedEvent) => { + this.emit(AvailableEvents.serversChanged, e) + }); + ns.on('subscribe', (e: SubEvent) => { + this.emit(AvailableEvents.subscribe, e) + }); + ns.on('unsubscribe', (e: SubEvent) => { + this.emit(AvailableEvents.unsubscribe, e) + }); + ns.on('yield', () => { + this.emit(AvailableEvents.yield) + }); + } + + /** + * Try to connect to the NATS server with user credentials + */ + async connectWithUserCreds(userCreds: string, options?: NatsConnectionOptions){ + await this.connect({ + userCreds: userCreds, + ... options + }); + } + /** + * Try to connect to the NATS server with user and password + */ + async connectWithUserPass(user: string, pass: string, options?: NatsConnectionOptions){ + await this.connect({ + user: user, + pass: pass, + ... options + }); + } + + /** + * Try to connect to the NATS server which has no authentication + */ + async connectToHost(host: string, options?: NatsConnectionOptions){ + await this.connect({ + servers: [host], + ... options + }); + } + + /** + * Try to connect to the NATS server with nkey authentication + */ + async connectWithNkey(publicNkey: string, seed: string, options?: NatsConnectionOptions){ + await this.connect({ + nkey: publicNkey, + nonceSigner: (nonce: string): Buffer => { + const sk = fromSeed(Buffer.from(seed)); + return sk.sign(Buffer.from(nonce)); + }, + ... options + }); + } + + /** + * Set the default options based on the AsyncAPI file. + * @param options to set + */ + private setDefaultOptions(options: NatsConnectionOptions){ + //If server binding options sat set the options + options.encoding = 'utf8'; + return options; + } + + + /** + * Channel for the turn on command which should turn on the streetlight + * @param requestMessage The message to publish. + */ + public publishToStreetlightStreetlightIdCommandTurnon(requestMessage: SubscribeToTurnonCommandMessage.SubscribeToTurnonCommand + ,streetlight_id: string + ): Promise { + const nc: Client = this.jsonClient!; + if(nc){ + return streetlightStreetlightIdCommandTurnonChannel.publish(requestMessage, nc + + ,streetlight_id + ); + }else{ + return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); + } + } + + + /** + * Channel for when the streetlight is turned on + * @param onDataCallback Called when message recieved. + */ + public subscribeToStreetlightStreetlightIdEventTurnon(onDataCallback : (err?: NatsTypescriptTemplateError, msg?: AnonymousMessage1Message.AnonymousMessage1, streetlight_id?: string) => void + ,streetlight_id: string + ): Promise { + const nc: Client = this.jsonClient!; + if(nc){ + return streetlightStreetlightIdEventTurnonChannel.subscribe(onDataCallback, nc + + ,streetlight_id + ); + }else{ + return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); + } + } + + +} \ No newline at end of file diff --git a/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts b/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts new file mode 100644 index 000000000..6040ea8ec --- /dev/null +++ b/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts @@ -0,0 +1,35 @@ + +import * as SubscribeToTurnonCommandMessage from '../../../messages/SubscribeToTurnonCommand'; +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {ErrorCode, NatsTypescriptTemplateError} from '../../../NatsTypescriptTemplateError'; +import { Hooks } from '../../../hooks'; + +export function publish( + message: SubscribeToTurnonCommandMessage.SubscribeToTurnonCommand, + nc: Client, + + streetlight_id: string + + ): Promise { + return new Promise(async (resolve, reject) => { + try{ + +try{ + let beforeSendingHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToSend : any = message; + for(let hook of beforeSendingHooks){ + dataToSend = hook(dataToSend); + } +}catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + return; +} + + nc.publish(`streetlight.${streetlight_id}.command.turnon`, dataToSend); + resolve(); + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); + } + }); +}; + diff --git a/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts b/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts new file mode 100644 index 000000000..c6d3c174b --- /dev/null +++ b/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts @@ -0,0 +1,48 @@ + +import * as AnonymousMessage1Message from '../../../messages/AnonymousMessage1'; +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {ErrorCode, NatsTypescriptTemplateError} from '../../../NatsTypescriptTemplateError'; +import { Hooks } from '../../../hooks'; + +export function subscribe( + onDataCallback : (err?: NatsTypescriptTemplateError, msg?: AnonymousMessage1Message.AnonymousMessage1, streetlight_id?: string) => void, + nc: Client, + + streetlight_id: string + + ): Promise { + return new Promise(async (resolve, reject) => { + let subscribeOptions: SubscriptionOptions = {}; + + try{ + let subscription = nc.subscribe(`streetlight.${streetlight_id}.event.turnon`, (err, msg) => { + if(err){ + onDataCallback(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, err)); + }else{ + const unmodifiedChannel = `streetlight.{streetlight_id}.event.turnon` + const receivedTopicParameters = { + streetlight_id : msg.subject.slice(unmodifiedChannel.split("${streetlight_id}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlight_id}")[1].length) + } + try{ + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var processedDataReceived: any = msg.data; + for(let hook of receivedDataHooks){ + processedDataReceived = hook(processedDataReceived); + } + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + return; + } + let publishedData = AnonymousMessage1Message.Convert.toAnonymousMessage1(processedDataReceived); + onDataCallback(undefined, publishedData, + receivedTopicParameters['streetlight_id']); + } + }, subscribeOptions); + resolve(subscription); + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); + } + }) +} + + diff --git a/examples/publish subscribe/streetlight/tsconfig.json b/examples/publish subscribe/streetlight/tsconfig.json new file mode 100644 index 000000000..75097457a --- /dev/null +++ b/examples/publish subscribe/streetlight/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "declaration": true, + "strict": true, + "noImplicitAny": true, + "removeComments": true, + "preserveConstEnums": true, + "sourceMap": true, + "outDir": "dist/", + "baseUrl": "./src" + }, + "include": ["src"], + "exclude": ["node_modules", "**/*.spec.ts"] +} From 915732498e027bcb1af5eca54003c76b2f94623e Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 23 Jul 2020 03:16:49 +0200 Subject: [PATCH 066/110] Added request reply example --- examples/request reply/README.md | 0 examples/request reply/generate.sh | 3 + examples/request reply/streetlight.json | 109 ++ examples/request reply/streetlight/README.md | 7 + .../streetlight/package-lock.json | 1082 +++++++++++++++++ .../request reply/streetlight/package.json | 29 + .../src/NatsTypescriptTemplateError.ts | 70 ++ .../StreetlightStreetlightIdCommandTurnon.ts | 72 ++ .../StreetlightStreetlightIdEventTurnon.ts | 53 + .../request reply/streetlight/src/hooks.ts | 57 + .../request reply/streetlight/src/index.ts | 253 ++++ .../src/messages/AnonymousMessage3.ts | 162 +++ .../streetlight/src/messages/GeneralReply.ts | 161 +++ .../src/messages/SubscribeToTurnonCommand.ts | 162 +++ .../streetlight/src/tests/testclient/index.ts | 249 ++++ .../StreetlightStreetlightIdCommandTurnon.ts | 53 + .../StreetlightStreetlightIdEventTurnon.ts | 72 ++ .../request reply/streetlight/tsconfig.json | 16 + 18 files changed, 2610 insertions(+) create mode 100644 examples/request reply/README.md create mode 100644 examples/request reply/generate.sh create mode 100644 examples/request reply/streetlight.json create mode 100644 examples/request reply/streetlight/README.md create mode 100644 examples/request reply/streetlight/package-lock.json create mode 100644 examples/request reply/streetlight/package.json create mode 100644 examples/request reply/streetlight/src/NatsTypescriptTemplateError.ts create mode 100644 examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts create mode 100644 examples/request reply/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts create mode 100644 examples/request reply/streetlight/src/hooks.ts create mode 100644 examples/request reply/streetlight/src/index.ts create mode 100644 examples/request reply/streetlight/src/messages/AnonymousMessage3.ts create mode 100644 examples/request reply/streetlight/src/messages/GeneralReply.ts create mode 100644 examples/request reply/streetlight/src/messages/SubscribeToTurnonCommand.ts create mode 100644 examples/request reply/streetlight/src/tests/testclient/index.ts create mode 100644 examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts create mode 100644 examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts create mode 100644 examples/request reply/streetlight/tsconfig.json diff --git a/examples/request reply/README.md b/examples/request reply/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/examples/request reply/generate.sh b/examples/request reply/generate.sh new file mode 100644 index 000000000..56e9bcac5 --- /dev/null +++ b/examples/request reply/generate.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +ag --install --output "./streetlight" "./streetlight.json" "../../" --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" \ No newline at end of file diff --git a/examples/request reply/streetlight.json b/examples/request reply/streetlight.json new file mode 100644 index 000000000..e13794936 --- /dev/null +++ b/examples/request reply/streetlight.json @@ -0,0 +1,109 @@ +{ + "asyncapi": "2.0.0", + "info": { + "title": "Streetlight", + "version": "1.0.0" + }, + "defaultContentType": "json", + "channels": { + "streetlight/{streetlight_id}/command/turnon": { + "description": "Channel for the turn on command which should turn on the streetlight", + "parameters": { + "streetlight_id": { + "description": "The ID of the streetlight", + "schema": { + "type": "string" + } + } + }, + "subscribe": { + "message": { + "$ref": "#/components/messages/generalReply" + } + }, + "publish": { + "operationId": "Listen when to turn on the streetlight", + "message": { + "name": "subscribeToTurnonCommand", + "payload": { + "type": "object", + "required": ["lumen"], + "properties": { + "lumen": { + "type": "integer", + "description": "How bright should the light be." + } + } + } + } + }, + "bindings": { + "nats": { + "is": "requestReply", + "requestReply": { + "is": "replier" + }, + "bindingVersion": "0.1.0" + } + } + }, + "streetlight/{streetlight_id}/event/turnon": { + "description": "Channel for when the streetlight is turned on", + "parameters": { + "streetlight_id": { + "description": "The ID of the streetlight", + "schema": { + "type": "string" + } + } + }, + "subscribe": { + "operationId": "Publish when the streetlight gets turned on", + "message": { + "payload": { + "type": "object", + "required": ["lumen"], + "properties": { + "lumen": { + "type": "integer", + "description": "How bright should the light be." + } + } + } + } + }, + "publish": { + "message": { + "$ref": "#/components/messages/generalReply" + } + }, + "bindings": { + "nats": { + "is": "requestReply", + "requestReply": { + "is": "requester" + }, + "bindingVersion": "0.1.0" + } + } + } + }, + "components": { + "messages": { + "generalReply": { + "payload": { + "type": "object", + "$id": "GeneralReply", + "properties": { + "status_code": { + "type": "integer" + }, + "status_message": { + "type": "string" + } + } + } + } + } + } +} diff --git a/examples/request reply/streetlight/README.md b/examples/request reply/streetlight/README.md new file mode 100644 index 000000000..8efb38d46 --- /dev/null +++ b/examples/request reply/streetlight/README.md @@ -0,0 +1,7 @@ +# Streetlight + + + + +Available nats encodings: +https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings diff --git a/examples/request reply/streetlight/package-lock.json b/examples/request reply/streetlight/package-lock.json new file mode 100644 index 000000000..44420165e --- /dev/null +++ b/examples/request reply/streetlight/package-lock.json @@ -0,0 +1,1082 @@ +{ + "name": "streetlight", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/chai": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz", + "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==", + "dev": true + }, + "@types/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@types/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-Ibfb2jgpjYUxnl7RSVvUzOrv/vhkTVKEfPwQf9ZlDDsSyWVDp/2JtTBxO4eRrKBYtxc3cZQabdR38i8R0o1uww==", + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", + "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", + "dev": true + }, + "@types/node": { + "version": "13.9.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.5.tgz", + "integrity": "sha512-hkzMMD3xu6BrJpGVLeQ3htQQNAcOrJjX7WFmtK8zWQpz2UJf13LCFF2ALA7c9OVdvc2vQJeDdjfR35M0sBCxvw==" + }, + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chokidar": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mocha": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", + "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "dev": true, + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "chokidar": "3.3.0", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "3.0.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.5", + "ms": "2.1.1", + "node-environment-flags": "1.0.6", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "nuid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/nuid/-/nuid-1.1.4.tgz", + "integrity": "sha512-PXiYyHhGfrq8H4g5HyC8enO1lz6SBe5z6x1yx/JG4tmADzDGJVQy3l1sRf3VtEvPsN8dGn9hRFRwDKWL62x0BA==" + }, + "object-inspect": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "readdirp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "dev": true, + "requires": { + "picomatch": "^2.0.4" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "ts-nats": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/ts-nats/-/ts-nats-1.2.4.tgz", + "integrity": "sha512-bIC+PlwHplRqhooa9kE+QPcQ9RPGUXD2ruvdf6LoFpP6MjE6exVoRhYSydm0e5wk7VfuXpTbH1NoopTKHwlOKA==", + "requires": { + "nuid": "^1.1.0", + "ts-nkeys": "^1.0.12" + } + }, + "ts-nkeys": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/ts-nkeys/-/ts-nkeys-1.0.16.tgz", + "integrity": "sha512-1qrhAlavbm36wtW+7NtKOgxpzl+70NTF8xlz9mEhiA5zHMlMxjj3sEVKWm3pGZhHXE0Q3ykjrj+OSRVaYw+Dqg==", + "requires": { + "tweetnacl": "^1.0.3" + } + }, + "ts-node": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typescript": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.3.tgz", + "integrity": "sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + } + } +} diff --git a/examples/request reply/streetlight/package.json b/examples/request reply/streetlight/package.json new file mode 100644 index 000000000..66239b020 --- /dev/null +++ b/examples/request reply/streetlight/package.json @@ -0,0 +1,29 @@ +{ + + + "name": "streetlight", + "description": "", + "version": "1.0.0", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "watch": "tsc --watch", + "build": "tsc", + "start": "node src/api/index.js", + "test": "mocha -r ts-node/register tests/**/*.spec.ts" + }, + "dependencies": { + "@types/klaw-sync": "^6.0.0", + "@types/node": "13.9.5", + "ts-nats": "1.2.4", + "typescript": "3.4.3", + "ts-nkeys":"1.0.16" + }, + "devDependencies": { + "@types/chai": "^4.2.11", + "@types/mocha": "^7.0.2", + "chai": "^4.2.0", + "mocha": "^7.1.1", + "ts-node": "^8.8.1" + } +} diff --git a/examples/request reply/streetlight/src/NatsTypescriptTemplateError.ts b/examples/request reply/streetlight/src/NatsTypescriptTemplateError.ts new file mode 100644 index 000000000..07ad37c3e --- /dev/null +++ b/examples/request reply/streetlight/src/NatsTypescriptTemplateError.ts @@ -0,0 +1,70 @@ + +import * as util from 'util'; + +export enum ErrorCode { + NOT_CONNECTED = 'NOT_CONNECTED', + INTERNAL_NATS_TS_ERROR = 'INTERNAL_NATS_TS_ERROR', + HOOK_ERROR = 'HOOK_ERROR' +} + +/** @internal **/ +export class Messages { + static messages = new Messages(); + messages: { [key: string]: string } = {}; + + private constructor() { + this.messages[ErrorCode.NOT_CONNECTED] = 'The client is not connected'; + this.messages[ErrorCode.INTERNAL_NATS_TS_ERROR] = 'An error occured while trying to use the Nats Typescript library'; + this.messages[ErrorCode.HOOK_ERROR] = 'An error occured while trying to call one of the hooks.'; + } + + static getMessage(s: string): string { + return Messages.messages.getMessage(s); + } + + getMessage(s: string): string { + let v = this.messages[s]; + if (!v) { + v = s; + } + return v; + } +} +export class NatsTypescriptTemplateError implements Error { + + name: string; + message: string; + code: string; + chainedError?: Error; + + /** + * @param {String} message + * @param {String} code + * @param {Error} [chainedError] + * @constructor + * + * @api private + * @internal + */ + constructor(message: string, code: string, chainedError?: Error) { + Error.captureStackTrace(this, this.constructor); + this.name = 'NatsTypescriptTemplateError'; + this.message = message; + this.code = code; + this.chainedError = chainedError; + + util.inherits(NatsTypescriptTemplateError, Error); + } + + /** + * @param code + * @param chainedError + * @api private + * @internal + */ + static errorForCode(code: string, chainedError?: Error): NatsTypescriptTemplateError { + let m = Messages.getMessage(code); + return new NatsTypescriptTemplateError(m, code, chainedError); + } +} + diff --git a/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts new file mode 100644 index 000000000..c8730331f --- /dev/null +++ b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts @@ -0,0 +1,72 @@ + +import * as SubscribeToTurnonCommandMessage from '../messages/SubscribeToTurnonCommand' +import * as GeneralReplyMessage from '../messages/GeneralReply' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {ErrorCode, NatsTypescriptTemplateError} from '../NatsTypescriptTemplateError'; +import { Hooks } from '../hooks'; + +export function reply( + onRequest: (err?: NatsTypescriptTemplateError, msg?: SubscribeToTurnonCommandMessage.SubscribeToTurnonCommand, streetlight_id?: string) =>Promise, + onReplyError: (err: NatsTypescriptTemplateError) => void, + nc: Client, + + streetlight_id: string + + ): Promise { + return new Promise(async (resolve, reject) => { + try { + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(`streetlight.${streetlight_id}.command.turnon`,async (err, msg) => { + if (err) { + onRequest(err); + } else { + const unmodifiedChannel = `streetlight.{streetlight_id}.command.turnon` + const receivedTopicParameters = { + streetlight_id : msg.subject.slice(unmodifiedChannel.split("{streetlight_id}")[0].length, msg.subject.length-unmodifiedChannel.split("{streetlight_id}")[1].length) + } + +try { + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var receivedData : any = msg.data; + for(let hook of receivedDataHooks){ + receivedData = hook(receivedData); + } +} catch (e) { + onReplyError(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)) + return; +} + + let requestData = SubscribeToTurnonCommandMessage.Convert.toSubscribeToTurnonCommand(receivedData); + let message =await onRequest(undefined, requestData, + receivedTopicParameters['streetlight_id']); + + if (msg.reply) { + +try{ + let beforeSendingHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToSend : any = message; + for(let hook of beforeSendingHooks){ + dataToSend = hook(dataToSend); + } +}catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + return; +} + + nc.publish(`streetlight.${streetlight_id}.command.turnon`, dataToSend); + } else { + let error = new NatsTypescriptTemplateError('Expected request to need a reply, did not..', '000'); + onReplyError(error) + return; + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); + } + }) +} + + diff --git a/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts new file mode 100644 index 000000000..6e6b52866 --- /dev/null +++ b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts @@ -0,0 +1,53 @@ + +import * as GeneralReplyMessage from '../messages/GeneralReply' +import * as AnonymousMessage3Message from '../messages/AnonymousMessage3' +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {ErrorCode, NatsTypescriptTemplateError} from '../NatsTypescriptTemplateError'; +import { Hooks } from '../hooks'; + +export function request( + message: AnonymousMessage3Message.AnonymousMessage3, + nc: Client, + + streetlight_id: string + + ): Promise { + return new Promise(async (resolve, reject) => { + + let msg; + try { + +try{ + let beforeSendingHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToSend : any = message; + for(let hook of beforeSendingHooks){ + dataToSend = hook(dataToSend); + } +}catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + return; +} + + msg = await nc.request(`streetlight.${streetlight_id}.event.turnon`, undefined, dataToSend) + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); + return; + } + +try { + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var receivedData : any = msg.data; + for(let hook of receivedDataHooks){ + receivedData = hook(receivedData); + } +} catch (e) { + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + return; +} + + let recievedData = GeneralReplyMessage.Convert.toGeneralReply(receivedData); + resolve(recievedData); + }) +} + + diff --git a/examples/request reply/streetlight/src/hooks.ts b/examples/request reply/streetlight/src/hooks.ts new file mode 100644 index 000000000..321b9085c --- /dev/null +++ b/examples/request reply/streetlight/src/hooks.ts @@ -0,0 +1,57 @@ +export enum AvailableHooks { + RecievedData = 'RecievedData', + BeforeSendingData = 'BeforeSendingData' +} +export type RecievedDataHook = (receivedData: any) => string; +export type BeforeSendingDataHook = (messageToSend: any) => string; +export class Hooks { + private static instance: Hooks; + + private hooks: { + BeforeSendingData: BeforeSendingDataHook[]; + RecievedData: RecievedDataHook[]; + }; + private constructor() { + this.hooks = { + BeforeSendingData: [], + RecievedData: [] + } + } + public static getInstance(): Hooks { + if (!Hooks.instance) { + Hooks.instance = new Hooks(); + } + return Hooks.instance; + } + + + + /** + * Register a hook for BeforeSendingData + * @param hook + */ + public async registerBeforeSendingData(hook: BeforeSendingDataHook) { + this.hooks[AvailableHooks.BeforeSendingData] + ? this.hooks[AvailableHooks.BeforeSendingData].push(hook) + : [hook]; + } + + /** + * Register a hook for BeforeSendingData + * @param hook + */ + public async registerRecievedData(hook: RecievedDataHook) { + this.hooks[AvailableHooks.RecievedData] + ? this.hooks[AvailableHooks.RecievedData].push(hook) + : [hook]; + } + + + public getRecievedDataHook(): RecievedDataHook[] { + return this.hooks[AvailableHooks.RecievedData]; + } + + public getBeforeSendingDataHook(): BeforeSendingDataHook[] { + return this.hooks[AvailableHooks.BeforeSendingData]; + } +} \ No newline at end of file diff --git a/examples/request reply/streetlight/src/index.ts b/examples/request reply/streetlight/src/index.ts new file mode 100644 index 000000000..fa4aeea83 --- /dev/null +++ b/examples/request reply/streetlight/src/index.ts @@ -0,0 +1,253 @@ + + + + +import {fromSeed} from 'ts-nkeys'; +import {AvailableHooks, RecievedDataHook, BeforeSendingDataHook, Hooks} from './hooks'; +export {AvailableHooks, RecievedDataHook, BeforeSendingDataHook, Hooks} +import * as TestClient from './tests/testclient/'; +export { TestClient }; +import {ErrorCode, NatsTypescriptTemplateError} from './NatsTypescriptTemplateError'; +export {ErrorCode, NatsTypescriptTemplateError} +import { + Client, + NatsConnectionOptions, + connect, + Payload, + NatsError, + Subscription, + ServersChangedEvent, + SubEvent, + ServerInfo + } from 'ts-nats'; +import * as streetlightStreetlightIdCommandTurnonChannel from "./channels/StreetlightStreetlightIdCommandTurnon"; +export {streetlightStreetlightIdCommandTurnonChannel}; +import * as streetlightStreetlightIdEventTurnonChannel from "./channels/StreetlightStreetlightIdEventTurnon"; +export {streetlightStreetlightIdEventTurnonChannel}; +import * as SubscribeToTurnonCommandMessage from "./messages/SubscribeToTurnonCommand"; +export {SubscribeToTurnonCommandMessage}; +import * as GeneralReplyMessage from "./messages/GeneralReply"; +export {GeneralReplyMessage}; +import * as AnonymousMessage3Message from "./messages/AnonymousMessage3"; +export {AnonymousMessage3Message}; + + +import * as events from 'events'; +export enum AvailableEvents { + permissionError = 'permissionError', + close = 'close', + connect = 'connect', + connecting = 'connecting', + disconnect = 'disconnect', + error = 'error', + pingcount = 'pingcount', + pingtimer = 'pingtimer', + reconnect = 'reconnect', + reconnecting = 'reconnecting', + serversChanged = 'serversChanged', + subscribe = 'subscribe', + unsubscribe = 'unsubscribe', + yield = 'yield' +} +export declare interface NatsAsyncApiClient { + on(event: AvailableEvents.permissionError, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.close, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; + on(event: AvailableEvents.connecting, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.error, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.pingcount, listener: () => void): this; + on(event: AvailableEvents.pingtimer, listener: () => void): this; + on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; + on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; + on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.yield, listener: () => void): this; +} +export class NatsAsyncApiClient extends events.EventEmitter{ + + + public jsonClient?: Client; + public stringClient?: Client; + public binaryClient?: Client; + public options?: NatsConnectionOptions; + + /** + * + * @param options options to use, payload is omitted if sat in the AsyncAPI document. + */ + constructor() { + super(); + } + /** + * Try to connect to the NATS server with the different payloads. + */ + connect(options : NatsConnectionOptions): Promise{ + return new Promise(async (resolve: () => void, reject: (error: any) => void) => { + this.options = this.setDefaultOptions(options); + try{ + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); + resolve(); + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); + } + }) + } + + + /** + * Disconnect all clients from the server + */ + async disconnect(){ + this.jsonClient!.close() + } + + private chainEvents(ns: Client){ + ns.on('permissionError', (e: NatsError) => { + this.emit(AvailableEvents.permissionError, NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)) + }); + ns.on('close', (e: NatsError) => { + this.emit(AvailableEvents.close, NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)) + }); + ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.connect, connection, serverURL, info) + }); + ns.on('connecting', (serverURL: string) => { + this.emit(AvailableEvents.connecting, serverURL) + }); + ns.on('disconnect', (serverURL: string) => { + this.emit(AvailableEvents.disconnect, serverURL) + }); + ns.on('error', (e: NatsError) => { + this.emit(AvailableEvents.error, NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)) + }); + ns.on('pingcount', () => { + this.emit(AvailableEvents.pingcount) + }); + ns.on('pingtimer', () => { + this.emit(AvailableEvents.pingtimer) + }); + ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.reconnect, connection, serverURL, info) + }); + ns.on('reconnecting', (serverURL: string) => { + this.emit(AvailableEvents.reconnecting, serverURL) + }); + ns.on('serversChanged', (e: ServersChangedEvent) => { + this.emit(AvailableEvents.serversChanged, e) + }); + ns.on('subscribe', (e: SubEvent) => { + this.emit(AvailableEvents.subscribe, e) + }); + ns.on('unsubscribe', (e: SubEvent) => { + this.emit(AvailableEvents.unsubscribe, e) + }); + ns.on('yield', () => { + this.emit(AvailableEvents.yield) + }); + } + + /** + * Try to connect to the NATS server with user credentials + */ + async connectWithUserCreds(userCreds: string, options?: NatsConnectionOptions){ + await this.connect({ + userCreds: userCreds, + ... options + }); + } + /** + * Try to connect to the NATS server with user and password + */ + async connectWithUserPass(user: string, pass: string, options?: NatsConnectionOptions){ + await this.connect({ + user: user, + pass: pass, + ... options + }); + } + + /** + * Try to connect to the NATS server which has no authentication + */ + async connectToHost(host: string, options?: NatsConnectionOptions){ + await this.connect({ + servers: [host], + ... options + }); + } + + /** + * Try to connect to the NATS server with nkey authentication + */ + async connectWithNkey(publicNkey: string, seed: string, options?: NatsConnectionOptions){ + await this.connect({ + nkey: publicNkey, + nonceSigner: (nonce: string): Buffer => { + const sk = fromSeed(Buffer.from(seed)); + return sk.sign(Buffer.from(nonce)); + }, + ... options + }); + } + + /** + * Set the default options based on the AsyncAPI file. + * @param options to set + */ + private setDefaultOptions(options: NatsConnectionOptions){ + //If server binding options sat set the options + options.encoding = 'utf8'; + return options; + } + + + /** + * Channel for the turn on command which should turn on the streetlight + * @param onRequest Called when request recieved. + * @param onReplyError Called when it was not possible to send the reply. + */ + public replyToStreetlightStreetlightIdCommandTurnon( + onRequest : ( + err?: NatsTypescriptTemplateError, + msg?: SubscribeToTurnonCommandMessage.SubscribeToTurnonCommand,streetlight_id?: string + ) =>Promise, onReplyError : (err: NatsTypescriptTemplateError) => void + + ,streetlight_id: string + ): Promise { + const nc: Client = this.jsonClient!; + + if(nc){ + return streetlightStreetlightIdCommandTurnonChannel.reply(onRequest, onReplyError, nc + + ,streetlight_id + ); + }else{ + return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); + } + } + + + /** + * Channel for when the streetlight is turned on + * @param requestMessage The request message to send. + */ + public requestStreetlightStreetlightIdEventTurnon(requestMessage:AnonymousMessage3Message.AnonymousMessage3 + + ,streetlight_id: string + ): Promise { + const nc: Client = this.jsonClient!; + if(nc){ + return streetlightStreetlightIdEventTurnonChannel.request(requestMessage, nc + + ,streetlight_id + ); + }else{ + return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); + } + } + +} diff --git a/examples/request reply/streetlight/src/messages/AnonymousMessage3.ts b/examples/request reply/streetlight/src/messages/AnonymousMessage3.ts new file mode 100644 index 000000000..d28aa3985 --- /dev/null +++ b/examples/request reply/streetlight/src/messages/AnonymousMessage3.ts @@ -0,0 +1,162 @@ +// To parse this data: +// +// import { Convert, AnonymousMessage3 } from "./file"; +// +// const anonymousMessage3 = Convert.toAnonymousMessage3(json); +// +// These functions will throw an error if the JSON doesn't +// match the expected interface, even if the JSON is valid. + +export interface AnonymousMessage3 { + /** + * How bright should the light be. + */ + lumen: number; +} + +// Converts JSON strings to/from your types +// and asserts the results of JSON.parse at runtime +export class Convert { + public static toAnonymousMessage3(json: string): AnonymousMessage3 { + return cast(JSON.parse(json), r("AnonymousMessage3")); + } + + public static anonymousMessage3ToJson(value: AnonymousMessage3): string { + return JSON.stringify(uncast(value, r("AnonymousMessage3")), null, 2); + } +} + +function invalidValue(typ: any, val: any): never { + throw Error(`Invalid value ${JSON.stringify(val)} for type ${JSON.stringify(typ)}`); +} + +function jsonToJSProps(typ: any): any { + if (typ.jsonToJS === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ }); + typ.jsonToJS = map; + } + return typ.jsonToJS; +} + +function jsToJSONProps(typ: any): any { + if (typ.jsToJSON === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ }); + typ.jsToJSON = map; + } + return typ.jsToJSON; +} + +function transform(val: any, typ: any, getProps: any): any { + function transformPrimitive(typ: string, val: any): any { + if (typeof typ === typeof val) return val; + return invalidValue(typ, val); + } + + function transformUnion(typs: any[], val: any): any { + // val must validate against one typ in typs + const l = typs.length; + for (let i = 0; i < l; i++) { + const typ = typs[i]; + try { + return transform(val, typ, getProps); + } catch (_) {} + } + return invalidValue(typs, val); + } + + function transformEnum(cases: string[], val: any): any { + if (cases.indexOf(val) !== -1) return val; + return invalidValue(cases, val); + } + + function transformArray(typ: any, val: any): any { + // val must be an array with no invalid elements + if (!Array.isArray(val)) return invalidValue("array", val); + return val.map(el => transform(el, typ, getProps)); + } + + function transformDate(val: any): any { + if (val === null) { + return null; + } + const d = new Date(val); + if (isNaN(d.valueOf())) { + return invalidValue("Date", val); + } + return d; + } + + function transformObject(props: { [k: string]: any }, additional: any, val: any): any { + if (val === null || typeof val !== "object" || Array.isArray(val)) { + return invalidValue("object", val); + } + const result: any = {}; + Object.getOwnPropertyNames(props).forEach(key => { + const prop = props[key]; + const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined; + result[prop.key] = transform(v, prop.typ, getProps); + }); + Object.getOwnPropertyNames(val).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(props, key)) { + result[key] = transform(val[key], additional, getProps); + } + }); + return result; + } + + if (typ === "any") return val; + if (typ === null) { + if (val === null) return val; + return invalidValue(typ, val); + } + if (typ === false) return invalidValue(typ, val); + while (typeof typ === "object" && typ.ref !== undefined) { + typ = typeMap[typ.ref]; + } + if (Array.isArray(typ)) return transformEnum(typ, val); + if (typeof typ === "object") { + return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) + : invalidValue(typ, val); + } + // Numbers can be parsed by Date but shouldn't be. + if (typ === Date && typeof val !== "number") return transformDate(val); + return transformPrimitive(typ, val); +} + +function cast(val: any, typ: any): T { + return transform(val, typ, jsonToJSProps); +} + +function uncast(val: T, typ: any): any { + return transform(val, typ, jsToJSONProps); +} + +function a(typ: any) { + return { arrayItems: typ }; +} + +function u(...typs: any[]) { + return { unionMembers: typs }; +} + +function o(props: any[], additional: any) { + return { props, additional }; +} + +function m(additional: any) { + return { props: [], additional }; +} + +function r(name: string) { + return { ref: name }; +} + +const typeMap: any = { + "AnonymousMessage3": o([ + { json: "lumen", js: "lumen", typ: 0 }, + ], "any"), +}; diff --git a/examples/request reply/streetlight/src/messages/GeneralReply.ts b/examples/request reply/streetlight/src/messages/GeneralReply.ts new file mode 100644 index 000000000..a705e3755 --- /dev/null +++ b/examples/request reply/streetlight/src/messages/GeneralReply.ts @@ -0,0 +1,161 @@ +// To parse this data: +// +// import { Convert, GeneralReply } from "./file"; +// +// const generalReply = Convert.toGeneralReply(json); +// +// These functions will throw an error if the JSON doesn't +// match the expected interface, even if the JSON is valid. + +export interface GeneralReply { + status_code?: number; + status_message?: string; +} + +// Converts JSON strings to/from your types +// and asserts the results of JSON.parse at runtime +export class Convert { + public static toGeneralReply(json: string): GeneralReply { + return cast(JSON.parse(json), r("GeneralReply")); + } + + public static generalReplyToJson(value: GeneralReply): string { + return JSON.stringify(uncast(value, r("GeneralReply")), null, 2); + } +} + +function invalidValue(typ: any, val: any): never { + throw Error(`Invalid value ${JSON.stringify(val)} for type ${JSON.stringify(typ)}`); +} + +function jsonToJSProps(typ: any): any { + if (typ.jsonToJS === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ }); + typ.jsonToJS = map; + } + return typ.jsonToJS; +} + +function jsToJSONProps(typ: any): any { + if (typ.jsToJSON === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ }); + typ.jsToJSON = map; + } + return typ.jsToJSON; +} + +function transform(val: any, typ: any, getProps: any): any { + function transformPrimitive(typ: string, val: any): any { + if (typeof typ === typeof val) return val; + return invalidValue(typ, val); + } + + function transformUnion(typs: any[], val: any): any { + // val must validate against one typ in typs + const l = typs.length; + for (let i = 0; i < l; i++) { + const typ = typs[i]; + try { + return transform(val, typ, getProps); + } catch (_) {} + } + return invalidValue(typs, val); + } + + function transformEnum(cases: string[], val: any): any { + if (cases.indexOf(val) !== -1) return val; + return invalidValue(cases, val); + } + + function transformArray(typ: any, val: any): any { + // val must be an array with no invalid elements + if (!Array.isArray(val)) return invalidValue("array", val); + return val.map(el => transform(el, typ, getProps)); + } + + function transformDate(val: any): any { + if (val === null) { + return null; + } + const d = new Date(val); + if (isNaN(d.valueOf())) { + return invalidValue("Date", val); + } + return d; + } + + function transformObject(props: { [k: string]: any }, additional: any, val: any): any { + if (val === null || typeof val !== "object" || Array.isArray(val)) { + return invalidValue("object", val); + } + const result: any = {}; + Object.getOwnPropertyNames(props).forEach(key => { + const prop = props[key]; + const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined; + result[prop.key] = transform(v, prop.typ, getProps); + }); + Object.getOwnPropertyNames(val).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(props, key)) { + result[key] = transform(val[key], additional, getProps); + } + }); + return result; + } + + if (typ === "any") return val; + if (typ === null) { + if (val === null) return val; + return invalidValue(typ, val); + } + if (typ === false) return invalidValue(typ, val); + while (typeof typ === "object" && typ.ref !== undefined) { + typ = typeMap[typ.ref]; + } + if (Array.isArray(typ)) return transformEnum(typ, val); + if (typeof typ === "object") { + return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) + : invalidValue(typ, val); + } + // Numbers can be parsed by Date but shouldn't be. + if (typ === Date && typeof val !== "number") return transformDate(val); + return transformPrimitive(typ, val); +} + +function cast(val: any, typ: any): T { + return transform(val, typ, jsonToJSProps); +} + +function uncast(val: T, typ: any): any { + return transform(val, typ, jsToJSONProps); +} + +function a(typ: any) { + return { arrayItems: typ }; +} + +function u(...typs: any[]) { + return { unionMembers: typs }; +} + +function o(props: any[], additional: any) { + return { props, additional }; +} + +function m(additional: any) { + return { props: [], additional }; +} + +function r(name: string) { + return { ref: name }; +} + +const typeMap: any = { + "GeneralReply": o([ + { json: "status_code", js: "status_code", typ: u(undefined, 0) }, + { json: "status_message", js: "status_message", typ: u(undefined, "") }, + ], "any"), +}; diff --git a/examples/request reply/streetlight/src/messages/SubscribeToTurnonCommand.ts b/examples/request reply/streetlight/src/messages/SubscribeToTurnonCommand.ts new file mode 100644 index 000000000..1cafd79de --- /dev/null +++ b/examples/request reply/streetlight/src/messages/SubscribeToTurnonCommand.ts @@ -0,0 +1,162 @@ +// To parse this data: +// +// import { Convert, SubscribeToTurnonCommand } from "./file"; +// +// const subscribeToTurnonCommand = Convert.toSubscribeToTurnonCommand(json); +// +// These functions will throw an error if the JSON doesn't +// match the expected interface, even if the JSON is valid. + +export interface SubscribeToTurnonCommand { + /** + * How bright should the light be. + */ + lumen: number; +} + +// Converts JSON strings to/from your types +// and asserts the results of JSON.parse at runtime +export class Convert { + public static toSubscribeToTurnonCommand(json: string): SubscribeToTurnonCommand { + return cast(JSON.parse(json), r("SubscribeToTurnonCommand")); + } + + public static subscribeToTurnonCommandToJson(value: SubscribeToTurnonCommand): string { + return JSON.stringify(uncast(value, r("SubscribeToTurnonCommand")), null, 2); + } +} + +function invalidValue(typ: any, val: any): never { + throw Error(`Invalid value ${JSON.stringify(val)} for type ${JSON.stringify(typ)}`); +} + +function jsonToJSProps(typ: any): any { + if (typ.jsonToJS === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ }); + typ.jsonToJS = map; + } + return typ.jsonToJS; +} + +function jsToJSONProps(typ: any): any { + if (typ.jsToJSON === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ }); + typ.jsToJSON = map; + } + return typ.jsToJSON; +} + +function transform(val: any, typ: any, getProps: any): any { + function transformPrimitive(typ: string, val: any): any { + if (typeof typ === typeof val) return val; + return invalidValue(typ, val); + } + + function transformUnion(typs: any[], val: any): any { + // val must validate against one typ in typs + const l = typs.length; + for (let i = 0; i < l; i++) { + const typ = typs[i]; + try { + return transform(val, typ, getProps); + } catch (_) {} + } + return invalidValue(typs, val); + } + + function transformEnum(cases: string[], val: any): any { + if (cases.indexOf(val) !== -1) return val; + return invalidValue(cases, val); + } + + function transformArray(typ: any, val: any): any { + // val must be an array with no invalid elements + if (!Array.isArray(val)) return invalidValue("array", val); + return val.map(el => transform(el, typ, getProps)); + } + + function transformDate(val: any): any { + if (val === null) { + return null; + } + const d = new Date(val); + if (isNaN(d.valueOf())) { + return invalidValue("Date", val); + } + return d; + } + + function transformObject(props: { [k: string]: any }, additional: any, val: any): any { + if (val === null || typeof val !== "object" || Array.isArray(val)) { + return invalidValue("object", val); + } + const result: any = {}; + Object.getOwnPropertyNames(props).forEach(key => { + const prop = props[key]; + const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined; + result[prop.key] = transform(v, prop.typ, getProps); + }); + Object.getOwnPropertyNames(val).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(props, key)) { + result[key] = transform(val[key], additional, getProps); + } + }); + return result; + } + + if (typ === "any") return val; + if (typ === null) { + if (val === null) return val; + return invalidValue(typ, val); + } + if (typ === false) return invalidValue(typ, val); + while (typeof typ === "object" && typ.ref !== undefined) { + typ = typeMap[typ.ref]; + } + if (Array.isArray(typ)) return transformEnum(typ, val); + if (typeof typ === "object") { + return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) + : invalidValue(typ, val); + } + // Numbers can be parsed by Date but shouldn't be. + if (typ === Date && typeof val !== "number") return transformDate(val); + return transformPrimitive(typ, val); +} + +function cast(val: any, typ: any): T { + return transform(val, typ, jsonToJSProps); +} + +function uncast(val: T, typ: any): any { + return transform(val, typ, jsToJSONProps); +} + +function a(typ: any) { + return { arrayItems: typ }; +} + +function u(...typs: any[]) { + return { unionMembers: typs }; +} + +function o(props: any[], additional: any) { + return { props, additional }; +} + +function m(additional: any) { + return { props: [], additional }; +} + +function r(name: string) { + return { ref: name }; +} + +const typeMap: any = { + "SubscribeToTurnonCommand": o([ + { json: "lumen", js: "lumen", typ: 0 }, + ], "any"), +}; diff --git a/examples/request reply/streetlight/src/tests/testclient/index.ts b/examples/request reply/streetlight/src/tests/testclient/index.ts new file mode 100644 index 000000000..51d80c268 --- /dev/null +++ b/examples/request reply/streetlight/src/tests/testclient/index.ts @@ -0,0 +1,249 @@ + + +import {fromSeed} from 'ts-nkeys'; +import {ErrorCode, NatsTypescriptTemplateError} from '../../NatsTypescriptTemplateError'; +import { + Client, + NatsConnectionOptions, + connect, + Payload, + NatsError, + Subscription, + ServersChangedEvent, + SubEvent, + ServerInfo + } from 'ts-nats'; +import * as streetlightStreetlightIdCommandTurnonChannel from "./testchannels/StreetlightStreetlightIdCommandTurnon"; +export {streetlightStreetlightIdCommandTurnonChannel}; +import * as streetlightStreetlightIdEventTurnonChannel from "./testchannels/StreetlightStreetlightIdEventTurnon"; +export {streetlightStreetlightIdEventTurnonChannel}; +import * as SubscribeToTurnonCommandMessage from "../../messages/SubscribeToTurnonCommand"; +export {SubscribeToTurnonCommandMessage}; +import * as GeneralReplyMessage from "../../messages/GeneralReply"; +export {GeneralReplyMessage}; +import * as AnonymousMessage3Message from "../../messages/AnonymousMessage3"; +export {AnonymousMessage3Message}; + + + +import * as events from 'events'; +export enum AvailableEvents { + permissionError = 'permissionError', + close = 'close', + connect = 'connect', + connecting = 'connecting', + disconnect = 'disconnect', + error = 'error', + pingcount = 'pingcount', + pingtimer = 'pingtimer', + reconnect = 'reconnect', + reconnecting = 'reconnecting', + serversChanged = 'serversChanged', + subscribe = 'subscribe', + unsubscribe = 'unsubscribe', + yield = 'yield' +} +export declare interface NatsAsyncApiTestClient { + on(event: AvailableEvents.permissionError, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.close, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; + on(event: AvailableEvents.connecting, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.error, listener: (error: NatsTypescriptTemplateError) => void): this; + on(event: AvailableEvents.pingcount, listener: () => void): this; + on(event: AvailableEvents.pingtimer, listener: () => void): this; + on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; + on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; + on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; + on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; + on(event: AvailableEvents.yield, listener: () => void): this; +} +export class NatsAsyncApiTestClient extends events.EventEmitter{ + + + + public jsonClient?: Client; + public stringClient?: Client; + public binaryClient?: Client; + public options?: NatsConnectionOptions; + + /** + * + * @param options options to use, payload is omitted if sat in the AsyncAPI document. + */ + constructor() { + super(); + } + /** + * Try to connect to the NATS server with the different payloads. + */ + connect(options : NatsConnectionOptions): Promise{ + return new Promise(async (resolve: () => void, reject: (error: any) => void) => { + this.options = this.setDefaultOptions(options); + try{ + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); + resolve(); + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); + } + }) + } + + + /** + * Disconnect all clients from the server + */ + async disconnect(){ + this.jsonClient!.close() + } + + private chainEvents(ns: Client){ + ns.on('permissionError', (e: NatsError) => { + this.emit(AvailableEvents.permissionError, NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)) + }); + ns.on('close', (e: NatsError) => { + this.emit(AvailableEvents.close, NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)) + }); + ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.connect, connection, serverURL, info) + }); + ns.on('connecting', (serverURL: string) => { + this.emit(AvailableEvents.connecting, serverURL) + }); + ns.on('disconnect', (serverURL: string) => { + this.emit(AvailableEvents.disconnect, serverURL) + }); + ns.on('error', (e: NatsError) => { + this.emit(AvailableEvents.error, NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)) + }); + ns.on('pingcount', () => { + this.emit(AvailableEvents.pingcount) + }); + ns.on('pingtimer', () => { + this.emit(AvailableEvents.pingtimer) + }); + ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { + this.emit(AvailableEvents.reconnect, connection, serverURL, info) + }); + ns.on('reconnecting', (serverURL: string) => { + this.emit(AvailableEvents.reconnecting, serverURL) + }); + ns.on('serversChanged', (e: ServersChangedEvent) => { + this.emit(AvailableEvents.serversChanged, e) + }); + ns.on('subscribe', (e: SubEvent) => { + this.emit(AvailableEvents.subscribe, e) + }); + ns.on('unsubscribe', (e: SubEvent) => { + this.emit(AvailableEvents.unsubscribe, e) + }); + ns.on('yield', () => { + this.emit(AvailableEvents.yield) + }); + } + + /** + * Try to connect to the NATS server with user credentials + */ + async connectWithUserCreds(userCreds: string, options?: NatsConnectionOptions){ + await this.connect({ + userCreds: userCreds, + ... options + }); + } + /** + * Try to connect to the NATS server with user and password + */ + async connectWithUserPass(user: string, pass: string, options?: NatsConnectionOptions){ + await this.connect({ + user: user, + pass: pass, + ... options + }); + } + + /** + * Try to connect to the NATS server which has no authentication + */ + async connectToHost(host: string, options?: NatsConnectionOptions){ + await this.connect({ + servers: [host], + ... options + }); + } + + /** + * Try to connect to the NATS server with nkey authentication + */ + async connectWithNkey(publicNkey: string, seed: string, options?: NatsConnectionOptions){ + await this.connect({ + nkey: publicNkey, + nonceSigner: (nonce: string): Buffer => { + const sk = fromSeed(Buffer.from(seed)); + return sk.sign(Buffer.from(nonce)); + }, + ... options + }); + } + + /** + * Set the default options based on the AsyncAPI file. + * @param options to set + */ + private setDefaultOptions(options: NatsConnectionOptions){ + //If server binding options sat set the options + options.encoding = 'utf8'; + return options; + } + + + /** + * Channel for the turn on command which should turn on the streetlight + * @param requestMessage The request message to send. + */ + public requestStreetlightStreetlightIdCommandTurnon(requestMessage:GeneralReplyMessage.GeneralReply + + ,streetlight_id: string + ): Promise { + const nc: Client = this.jsonClient!; + if(nc){ + return streetlightStreetlightIdCommandTurnonChannel.request(requestMessage, nc + + ,streetlight_id + ); + }else{ + return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); + } + } + + + /** + * Channel for when the streetlight is turned on + * @param onRequest Called when request recieved. + * @param onReplyError Called when it was not possible to send the reply. + */ + public replyToStreetlightStreetlightIdEventTurnon( + onRequest : ( + err?: NatsTypescriptTemplateError, + msg?: GeneralReplyMessage.GeneralReply,streetlight_id?: string + ) =>Promise, onReplyError : (err: NatsTypescriptTemplateError) => void + + ,streetlight_id: string + ): Promise { + const nc: Client = this.jsonClient!; + + if(nc){ + return streetlightStreetlightIdEventTurnonChannel.reply(onRequest, onReplyError, nc + + ,streetlight_id + ); + }else{ + return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); + } + } + + +} \ No newline at end of file diff --git a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts new file mode 100644 index 000000000..57a450dfe --- /dev/null +++ b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts @@ -0,0 +1,53 @@ + +import * as SubscribeToTurnonCommandMessage from '../../../messages/SubscribeToTurnonCommand'; +import * as GeneralReplyMessage from '../../../messages/GeneralReply'; +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {ErrorCode, NatsTypescriptTemplateError} from '../../../NatsTypescriptTemplateError'; +import { Hooks } from '../../../hooks'; + +export function request( + message: GeneralReplyMessage.GeneralReply, + nc: Client, + + streetlight_id: string + + ): Promise { + return new Promise(async (resolve, reject) => { + + let msg; + try { + +try{ + let beforeSendingHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToSend : any = message; + for(let hook of beforeSendingHooks){ + dataToSend = hook(dataToSend); + } +}catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + return; +} + + msg = await nc.request(`streetlight.${streetlight_id}.command.turnon`, undefined, dataToSend) + }catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); + return; + } + +try { + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var receivedData : any = msg.data; + for(let hook of receivedDataHooks){ + receivedData = hook(receivedData); + } +} catch (e) { + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + return; +} + + let recievedData = SubscribeToTurnonCommandMessage.Convert.toSubscribeToTurnonCommand(receivedData); + resolve(recievedData); + }) +} + + diff --git a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts new file mode 100644 index 000000000..6366fa6f8 --- /dev/null +++ b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts @@ -0,0 +1,72 @@ + +import * as GeneralReplyMessage from '../../../messages/GeneralReply'; +import * as AnonymousMessage3Message from '../../../messages/AnonymousMessage3'; +import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; +import {ErrorCode, NatsTypescriptTemplateError} from '../../../NatsTypescriptTemplateError'; +import { Hooks } from '../../../hooks'; + +export function reply( + onRequest: (err?: NatsTypescriptTemplateError, msg?: GeneralReplyMessage.GeneralReply, streetlight_id?: string) =>Promise, + onReplyError: (err: NatsTypescriptTemplateError) => void, + nc: Client, + + streetlight_id: string + + ): Promise { + return new Promise(async (resolve, reject) => { + try { + let subscribeOptions: SubscriptionOptions = {}; + + let subscription = nc.subscribe(`streetlight.${streetlight_id}.event.turnon`,async (err, msg) => { + if (err) { + onRequest(err); + } else { + const unmodifiedChannel = `streetlight.{streetlight_id}.event.turnon` + const receivedTopicParameters = { + streetlight_id : msg.subject.slice(unmodifiedChannel.split("{streetlight_id}")[0].length, msg.subject.length-unmodifiedChannel.split("{streetlight_id}")[1].length) + } + +try { + let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + var receivedData : any = msg.data; + for(let hook of receivedDataHooks){ + receivedData = hook(receivedData); + } +} catch (e) { + onReplyError(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)) + return; +} + + let requestData = GeneralReplyMessage.Convert.toGeneralReply(receivedData); + let message =await onRequest(undefined, requestData, + receivedTopicParameters['streetlight_id']); + + if (msg.reply) { + +try{ + let beforeSendingHooks = Hooks.getInstance().getBeforeSendingDataHook(); + var dataToSend : any = message; + for(let hook of beforeSendingHooks){ + dataToSend = hook(dataToSend); + } +}catch(e){ + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + return; +} + + nc.publish(`streetlight.${streetlight_id}.event.turnon`, dataToSend); + } else { + let error = new NatsTypescriptTemplateError('Expected request to need a reply, did not..', '000'); + onReplyError(error) + return; + } + } + }, subscribeOptions); + resolve(subscription); + } catch (e) { + reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); + } + }) +} + + diff --git a/examples/request reply/streetlight/tsconfig.json b/examples/request reply/streetlight/tsconfig.json new file mode 100644 index 000000000..75097457a --- /dev/null +++ b/examples/request reply/streetlight/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "declaration": true, + "strict": true, + "noImplicitAny": true, + "removeComments": true, + "preserveConstEnums": true, + "sourceMap": true, + "outDir": "dist/", + "baseUrl": "./src" + }, + "include": ["src"], + "exclude": ["node_modules", "**/*.spec.ts"] +} From 415448141af50d60be97bfe89b1616d84e582cec Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 23 Jul 2020 03:20:49 +0200 Subject: [PATCH 067/110] Changed .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6a0e6aa8d..1d077b3a2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ node_modules test/actual_comparators/* -examples/**/dist/* \ No newline at end of file +dist \ No newline at end of file From 616495f085b3aab978b93a33afee2ea5e4e3adc4 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 23 Jul 2020 03:26:04 +0200 Subject: [PATCH 068/110] Removed test directory for the template --- .../0.1.0/components/channel-bindings.yml | 9 - test/docs/0.1.0/components/messages.yml | 31 --- test/docs/0.1.0/components/parameters.yml | 4 - test/docs/0.1.0/components/schemas.yml | 57 ---- test/docs/0.1.0/frontend.yml | 121 -------- test/docs/0.1.0/light-controller.yml | 127 --------- .../latest/frontend/README.md | 17 -- .../latest/frontend/package.json | 42 --- ...ingStreetlights10ActionStreetlightIdDim.ts | 70 ----- ...treetlights10ActionStreetlightIdTurnOff.ts | 70 ----- ...Streetlights10ActionStreetlightIdTurnOn.ts | 70 ----- ...hts10EventStreetlightIdLightingMeasured.ts | 32 --- .../latest/frontend/src/hooks.ts | 60 ---- .../latest/frontend/src/index.ts | 240 ---------------- .../latest/frontend/src/messages/DimLight.ts | 29 -- .../frontend/src/messages/DimLightResponse.ts | 26 -- .../frontend/src/messages/LightMeasured.ts | 26 -- .../latest/frontend/src/messages/TurnOnOff.ts | 26 -- .../src/messages/TurnOnOffResponse.ts | 26 -- .../src/schema/DimLightPayloadserere.ts | 19 -- .../src/schema/LightMeasuredPayload.ts | 19 -- .../latest/frontend/src/schema/Response.ts | 21 -- .../frontend/src/schema/TurnOnOffPayload.ts | 19 -- .../frontend/src/tests/testclient/index.ts | 247 ----------------- ...ingStreetlights10ActionStreetlightIdDim.ts | 45 --- ...treetlights10ActionStreetlightIdTurnOff.ts | 45 --- ...Streetlights10ActionStreetlightIdTurnOn.ts | 45 --- ...hts10EventStreetlightIdLightingMeasured.ts | 42 --- .../latest/frontend/tsconfig.json | 25 -- .../latest/light-controller/README.md | 17 -- .../latest/light-controller/package.json | 42 --- ...ingStreetlights10ActionStreetlightIdDim.ts | 45 --- ...treetlights10ActionStreetlightIdTurnOff.ts | 45 --- ...Streetlights10ActionStreetlightIdTurnOn.ts | 45 --- .../SmartylightingStreetlights10Event.ts | 35 --- ...hts10EventStreetlightIdLightingMeasured.ts | 42 --- .../latest/light-controller/src/hooks.ts | 60 ---- .../latest/light-controller/src/index.ts | 262 ------------------ .../light-controller/src/messages/DimLight.ts | 29 -- .../src/messages/DimLightResponse.ts | 26 -- .../src/messages/LightMeasured.ts | 26 -- .../src/messages/TurnOnOff.ts | 26 -- .../src/messages/TurnOnOffResponse.ts | 26 -- .../src/schema/DimLightPayloadserere.ts | 19 -- .../src/schema/LightMeasuredPayload.ts | 19 -- .../light-controller/src/schema/Response.ts | 21 -- .../src/schema/TurnOnOffPayload.ts | 19 -- .../src/tests/testclient/index.ts | 257 ----------------- ...ingStreetlights10ActionStreetlightIdDim.ts | 70 ----- ...treetlights10ActionStreetlightIdTurnOff.ts | 70 ----- ...Streetlights10ActionStreetlightIdTurnOn.ts | 70 ----- .../SmartylightingStreetlights10Event.ts | 30 -- ...hts10EventStreetlightIdLightingMeasured.ts | 32 --- .../latest/light-controller/tsconfig.json | 25 -- test/template.js | 26 -- 55 files changed, 2994 deletions(-) delete mode 100644 test/docs/0.1.0/components/channel-bindings.yml delete mode 100644 test/docs/0.1.0/components/messages.yml delete mode 100644 test/docs/0.1.0/components/parameters.yml delete mode 100644 test/docs/0.1.0/components/schemas.yml delete mode 100644 test/docs/0.1.0/frontend.yml delete mode 100644 test/docs/0.1.0/light-controller.yml delete mode 100644 test/expected_comparators/latest/frontend/README.md delete mode 100644 test/expected_comparators/latest/frontend/package.json delete mode 100644 test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdDim.ts delete mode 100644 test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts delete mode 100644 test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts delete mode 100644 test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts delete mode 100644 test/expected_comparators/latest/frontend/src/hooks.ts delete mode 100644 test/expected_comparators/latest/frontend/src/index.ts delete mode 100644 test/expected_comparators/latest/frontend/src/messages/DimLight.ts delete mode 100644 test/expected_comparators/latest/frontend/src/messages/DimLightResponse.ts delete mode 100644 test/expected_comparators/latest/frontend/src/messages/LightMeasured.ts delete mode 100644 test/expected_comparators/latest/frontend/src/messages/TurnOnOff.ts delete mode 100644 test/expected_comparators/latest/frontend/src/messages/TurnOnOffResponse.ts delete mode 100644 test/expected_comparators/latest/frontend/src/schema/DimLightPayloadserere.ts delete mode 100644 test/expected_comparators/latest/frontend/src/schema/LightMeasuredPayload.ts delete mode 100644 test/expected_comparators/latest/frontend/src/schema/Response.ts delete mode 100644 test/expected_comparators/latest/frontend/src/schema/TurnOnOffPayload.ts delete mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/index.ts delete mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdDim.ts delete mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts delete mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts delete mode 100644 test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts delete mode 100644 test/expected_comparators/latest/frontend/tsconfig.json delete mode 100644 test/expected_comparators/latest/light-controller/README.md delete mode 100644 test/expected_comparators/latest/light-controller/package.json delete mode 100644 test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdDim.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10Event.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/hooks.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/index.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/messages/DimLight.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/messages/DimLightResponse.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/messages/LightMeasured.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/messages/TurnOnOff.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/messages/TurnOnOffResponse.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/schema/DimLightPayloadserere.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/schema/LightMeasuredPayload.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/schema/Response.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/schema/TurnOnOffPayload.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/index.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdDim.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10Event.ts delete mode 100644 test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts delete mode 100644 test/expected_comparators/latest/light-controller/tsconfig.json delete mode 100644 test/template.js diff --git a/test/docs/0.1.0/components/channel-bindings.yml b/test/docs/0.1.0/components/channel-bindings.yml deleted file mode 100644 index 8e2de6ae6..000000000 --- a/test/docs/0.1.0/components/channel-bindings.yml +++ /dev/null @@ -1,9 +0,0 @@ -smartylightingMeasurement: - nats: - is: pubsub - queue: - name: smartylightingMeasurement - bindingVersion: '0.1.0' - - - diff --git a/test/docs/0.1.0/components/messages.yml b/test/docs/0.1.0/components/messages.yml deleted file mode 100644 index d144416f8..000000000 --- a/test/docs/0.1.0/components/messages.yml +++ /dev/null @@ -1,31 +0,0 @@ -lightMeasured: - name: lightMeasured - title: Light measured - summary: Inform about environmental lighting conditions of a particular streetlight. - contentType: application/json - payload: - $ref: "./schemas.yml#/lightMeasuredPayload" -turnOnOff: - name: turnOnOff - title: Turn on/off - summary: Command a particular streetlight to turn the lights on or off. - payload: - $ref: "./schemas.yml#/turnOnOffPayload" -turnOnOffResponse: - name: turnOnOffResponse - title: turn on/off light response when processed. - payload: - $ref: "./schemas.yml#/response" -dimLight: - name: dimLight - title: Dim light - summary: Command a particular streetlight to dim the lights. - payload: - anyOf: - - $ref: "./schemas.yml#/dimLightPayloadserere" - - $ref: "./schemas.yml#/response" -dimLightResponse: - name: dimLightResponse - title: Dim light response when processed. - payload: - $ref: "./schemas.yml#/response" diff --git a/test/docs/0.1.0/components/parameters.yml b/test/docs/0.1.0/components/parameters.yml deleted file mode 100644 index b8ef4fce5..000000000 --- a/test/docs/0.1.0/components/parameters.yml +++ /dev/null @@ -1,4 +0,0 @@ -streetlightId: - description: The ID of the streetlight. - schema: - type: string diff --git a/test/docs/0.1.0/components/schemas.yml b/test/docs/0.1.0/components/schemas.yml deleted file mode 100644 index 800b42cb8..000000000 --- a/test/docs/0.1.0/components/schemas.yml +++ /dev/null @@ -1,57 +0,0 @@ -lightMeasuredPayload: - type: object - $id: lightMeasuredPayload - x-parser-schema-id: lightMeasuredPayload - properties: - lumens: - type: integer - minimum: 0 - description: Light intensity measured in lumens. - x-pi: false - sentAt: - $ref: "#/sentAt" -turnOnOffPayload: - type: object - $id: turnOnOffPayload - x-parser-schema-id: turnOnOffPayload - properties: - command: - type: string - enum: - - on - - off - description: Whether to turn on or off the light. - x-pi: false - sentAt: - $ref: "#/sentAt" -dimLightPayloadserere: - type: object - $id: dimLightPayloadserere - x-parser-schema-id: dimLightPayloadserere - properties: - percentage: - type: integer - description: Percentage to which the light should be dimmed to. - minimum: 0 - maximum: 100 - sentAt: - $ref: "#/sentAt" -sentAt: - type: string - format: date-time - description: Date and time when the message was sent. -response: - type: object - $id: response - x-parser-schema-id: response - properties: - status: - type: integer - description: Like http codes - statusMessage: - type: string - enum: - - OK - - ERROR - sentAt: - $ref: "#/sentAt" diff --git a/test/docs/0.1.0/frontend.yml b/test/docs/0.1.0/frontend.yml deleted file mode 100644 index ead10b58d..000000000 --- a/test/docs/0.1.0/frontend.yml +++ /dev/null @@ -1,121 +0,0 @@ -asyncapi: '2.0.0' -info: - title: Streetlights Nats API for lightning controllers - version: '1.0.0' - description: | - The Smartylighting Streetlights API allows you to remotely manage the city lights. - - This is for the lighting controllers, which assumed are multiple instances to ensure availability. - - ### Check out its awesome features: - - * Turn a specific streetlight on/off 🌃 - * Dim a specific streetlight 😎 - * Receive real-time information about environmental lighting conditions 📈 - license: - name: Apache 2.0 - url: https://www.apache.org/licenses/LICENSE-2.0 - -servers: - production: - url: test.nats.org:{port} - protocol: nats - description: Test broker - variables: - port: - default: '4444' - security: - - apiKey: [] - -defaultContentType: json -channels: - smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured: - description: Any measured values will be published through this method. - parameters: - streetlightId: - $ref: './components/parameters.yml#/streetlightId' - publish: - operationId: publishLightMeasurement - message: - $ref: './components/messages.yml#/lightMeasured' - bindings: - $ref: './components/channel-bindings.yml#/smartylightingMeasurement' - - smartylighting/streetlights/1/0/action/{streetlightId}/turn/on: - description: Get notified when a streetlight should be turned on. This should only be handled by 1 subscriber but ensured by request reply. - parameters: - streetlightId: - $ref: './components/parameters.yml#/streetlightId' - publish: - operationId: turnOnResponse - description: The response returned by us to the frontend. - message: - $ref: './components/messages.yml#/turnOnOffResponse' - subscribe: - operationId: turnOn - description: The turn on request received from the frontend. - message: - $ref: './components/messages.yml#/turnOnOff' - bindings: - nats: - is: requestReply - requestReply: - is: replier - queue: - name: smartylightingTurnOn - bindingVersion: '0.1.0' - - smartylighting/streetlights/1/0/action/{streetlightId}/turn/off: - description: Get notified when a streetlight should be turned off. This should only be handled by 1 subscriber but ensured by request reply. - parameters: - streetlightId: - $ref: './components/parameters.yml#/streetlightId' - publish: - operationId: turnOffResponse - description: The response returned by us to the frontend. - message: - $ref: './components/messages.yml#/turnOnOffResponse' - subscribe: - operationId: turnOff - description: The turn off request received from the frontend. - message: - $ref: './components/messages.yml#/turnOnOff' - bindings: - nats: - is: requestReply - requestReply: - is: replier - queue: - name: smartylightingTurnOff - bindingVersion: '0.1.0' - - smartylighting/streetlights/1/0/action/{streetlightId}/dim: - description: Get notified when a streetlight should be dimmed. This should only be handled by 1 subscriber but ensured by request reply. - parameters: - streetlightId: - $ref: './components/parameters.yml#/streetlightId' - publish: - operationId: dimLightResponse - description: The response returned by us. - message: - $ref: './components/messages.yml#/dimLightResponse' - subscribe: - operationId: dimLight - description: The dim light request received from the frontend. - message: - $ref: './components/messages.yml#/dimLight' - bindings: - nats: - is: requestReply - requestReply: - is: replier - queue: - name: smartylightingDim - bindingVersion: '0.1.0' - -components: - securitySchemes: - apiKey: - type: apiKey - in: user - description: Provide your API key as the user and leave the password empty. diff --git a/test/docs/0.1.0/light-controller.yml b/test/docs/0.1.0/light-controller.yml deleted file mode 100644 index 25d903dcb..000000000 --- a/test/docs/0.1.0/light-controller.yml +++ /dev/null @@ -1,127 +0,0 @@ -asyncapi: '2.0.0' -info: - title: Streetlights Nats API for the frontend - version: '1.0.0' - description: | - The Smartylighting Streetlights API allows you to remotely manage the city lights. - - This is for the frontend where the lights can be controlled, which assumed are multiple instances to ensure availability. - - ### Check out its awesome features: - - * Turn a specific streetlight on/off 🌃 - * Dim a specific streetlight 😎 - * Receive real-time information about environmental lighting conditions 📈 - license: - name: Apache 2.0 - url: https://www.apache.org/licenses/LICENSE-2.0 - -servers: - production: - url: test.nats.org:{port} - protocol: nats - description: Test broker - variables: - port: - default: '4444' - security: - - apiKey: [] - -defaultContentType: json - -channels: - smartylighting/streetlights/1/0/event/*: - description: Topic for which one can subscribe to all measurements regardless of id. - subscribe: - operationId: receiveAllLightMeasurements - message: - $ref: './components/messages.yml#/lightMeasured' - bindings: - $ref: './components/channel-bindings.yml#/smartylightingMeasurement' - - smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured: - description: Topic for which one can subscribe to measurements on a specific streetlightId. - parameters: - streetlightId: - $ref: './components/parameters.yml#/streetlightId' - subscribe: - operationId: receiveLightMeasurements - message: - $ref: './components/messages.yml#/lightMeasured' - bindings: - $ref: './components/channel-bindings.yml#/smartylightingMeasurement' - - smartylighting/streetlights/1/0/action/{streetlightId}/turn/on: - parameters: - streetlightId: - $ref: './components/parameters.yml#/streetlightId' - publish: - operationId: turnOn - description: The turn on request send to the light controller. - message: - $ref: './components/messages.yml#/turnOnOff' - subscribe: - operationId: turnOnResponse - description: The response returned by the light controller. - message: - $ref: './components/messages.yml#/turnOnOffResponse' - bindings: - nats: - is: requestReply - requestReply: - is: requester - queue: - name: smartylightingTurnOn - bindingVersion: '0.1.0' - smartylighting/streetlights/1/0/action/{streetlightId}/turn/off: - parameters: - streetlightId: - $ref: './components/parameters.yml#/streetlightId' - subscribe: - operationId: turnOffResponse - description: The response returned by the light controller. - message: - $ref: './components/messages.yml#/turnOnOffResponse' - publish: - operationId: turnOff - description: The turn off request send to the light controller. - message: - $ref: './components/messages.yml#/turnOnOff' - bindings: - nats: - is: requestReply - requestReply: - is: requester - queue: - name: smartylightingTurnOff - bindingVersion: '0.1.0' - - smartylighting/streetlights/1/0/action/{streetlightId}/dim: - parameters: - streetlightId: - $ref: './components/parameters.yml#/streetlightId' - subscribe: - operationId: dimLightResponse - description: The response returned by the light controller. - message: - $ref: './components/messages.yml#/dimLightResponse' - publish: - operationId: dimLight - description: The dim light request send to the light controller. - message: - $ref: './components/messages.yml#/dimLight' - bindings: - nats: - is: requestReply - requestReply: - is: requester - queue: - name: smartylightingDim - bindingVersion: '0.1.0' - -components: - securitySchemes: - apiKey: - type: apiKey - in: user - description: Provide your API key as the user and leave the password empty. diff --git a/test/expected_comparators/latest/frontend/README.md b/test/expected_comparators/latest/frontend/README.md deleted file mode 100644 index 7d8ed191e..000000000 --- a/test/expected_comparators/latest/frontend/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Streetlights Nats API for lightning controllers - -The Smartylighting Streetlights API allows you to remotely manage the city lights. - -This is for the lighting controllers, which assumed are multiple instances to ensure availability. - -### Check out its awesome features: - -* Turn a specific streetlight on/off 🌃 -* Dim a specific streetlight 😎 -* Receive real-time information about environmental lighting conditions 📈 - - - - -Available nats encodings: -https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings diff --git a/test/expected_comparators/latest/frontend/package.json b/test/expected_comparators/latest/frontend/package.json deleted file mode 100644 index 3ffa6ee54..000000000 --- a/test/expected_comparators/latest/frontend/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - - - - "name": "streetlights-nats-api-for-lightning-controllers", - "description": "The Smartylighting Streetlights API allows you to remotely manage the city lights. This is for the lighting controllers, which assumed are multiple instances to ensure availability. ### Check out its awesome features: * Turn a specific streetlight on/off 🌃 * Dim a specific streetlight 😎 * Receive real-time information about environmental lighting conditions 📈 ", - "version": "1.0.0", - "main": "dist/index.js", - "types": "dist/index.d.ts", - "scripts": { - "watch": "tsc --watch", - "build": "tsc && npm run dopostinstall", - "start": "node src/api/index.js", - "dopostinstall": "link-module-alias", - "test": "mocha -r ts-node/register tests/**/*.spec.ts" - }, - "_moduleAliasIgnoreWarning": true, - "_moduleAliases": { - "#messages": "dist/messages/", - "#schemas": "dist/schema/", - "#channels": "dist/channels/", - "#testchannels": "dist/tests/testclient/testchannels/", - "#hooks": "dist/hooks.js", - "#testclient": "dist/tests/testclient/index.js" - }, - "dependencies": { - "@types/klaw-sync": "^6.0.0", - "@types/node": "13.9.5", - "klaw-sync": "6.0.0", - "link-module-alias": "^1.2.0", - "ts-nats": "1.2.4", - "typescript": "3.4.3", - "ts-nkeys":"1.0.16" - }, - "devDependencies": { - "@types/chai": "^4.2.11", - "@types/mocha": "^7.0.2", - "chai": "^4.2.0", - "mocha": "^7.1.1", - "ts-node": "^8.8.1" - } -} diff --git a/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdDim.ts b/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdDim.ts deleted file mode 100644 index cde192c51..000000000 --- a/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdDim.ts +++ /dev/null @@ -1,70 +0,0 @@ - -import {default as DimLightResponseMessage} from '#messages/DimLightResponse' -import {default as DimLightMessage} from '#messages/DimLight' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - -export function reply( - onRequest: (err?: NatsError, msg?: DimLightMessage, streetlightId?: string) =>Promise, - onReplyError: (err: NatsError) => void, - nc: Client, - - streetlightId: string - - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(`smartylighting.streetlights.1.0.action.${streetlightId}.dim`,async (err, msg) => { - if (err) { - onRequest(err); - } else { - const unmodifiedChannel = `smartylighting.streetlights.1.0.action.{streetlightId}.dim` - const receivedTopicParameters = { - streetlightId : msg.subject.slice(unmodifiedChannel.split("${streetlightId}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlightId}")[1].length) - } - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived : any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - let requestData = DimLightMessage.toMessage(processedDataReceived); - let responseObject =await onRequest(undefined, requestData, - receivedTopicParameters['streetlightId']); - if (msg.reply) { - try { - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var dataToPublish : any = responseObject; - for(let hook of publishDataHooks){ - dataToPublish = hook(dataToPublish); - } - nc.publish(msg.reply, dataToPublish); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts b/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts deleted file mode 100644 index e501516eb..000000000 --- a/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts +++ /dev/null @@ -1,70 +0,0 @@ - -import {default as TurnOnOffResponseMessage} from '#messages/TurnOnOffResponse' -import {default as TurnOnOffMessage} from '#messages/TurnOnOff' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - -export function reply( - onRequest: (err?: NatsError, msg?: TurnOnOffMessage, streetlightId?: string) =>Promise, - onReplyError: (err: NatsError) => void, - nc: Client, - - streetlightId: string - - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(`smartylighting.streetlights.1.0.action.${streetlightId}.turn.off`,async (err, msg) => { - if (err) { - onRequest(err); - } else { - const unmodifiedChannel = `smartylighting.streetlights.1.0.action.{streetlightId}.turn.off` - const receivedTopicParameters = { - streetlightId : msg.subject.slice(unmodifiedChannel.split("${streetlightId}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlightId}")[1].length) - } - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived : any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - let requestData = TurnOnOffMessage.toMessage(processedDataReceived); - let responseObject =await onRequest(undefined, requestData, - receivedTopicParameters['streetlightId']); - if (msg.reply) { - try { - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var dataToPublish : any = responseObject; - for(let hook of publishDataHooks){ - dataToPublish = hook(dataToPublish); - } - nc.publish(msg.reply, dataToPublish); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts b/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts deleted file mode 100644 index 236e7c7c9..000000000 --- a/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts +++ /dev/null @@ -1,70 +0,0 @@ - -import {default as TurnOnOffResponseMessage} from '#messages/TurnOnOffResponse' -import {default as TurnOnOffMessage} from '#messages/TurnOnOff' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - -export function reply( - onRequest: (err?: NatsError, msg?: TurnOnOffMessage, streetlightId?: string) =>Promise, - onReplyError: (err: NatsError) => void, - nc: Client, - - streetlightId: string - - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(`smartylighting.streetlights.1.0.action.${streetlightId}.turn.on`,async (err, msg) => { - if (err) { - onRequest(err); - } else { - const unmodifiedChannel = `smartylighting.streetlights.1.0.action.{streetlightId}.turn.on` - const receivedTopicParameters = { - streetlightId : msg.subject.slice(unmodifiedChannel.split("${streetlightId}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlightId}")[1].length) - } - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived : any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - let requestData = TurnOnOffMessage.toMessage(processedDataReceived); - let responseObject =await onRequest(undefined, requestData, - receivedTopicParameters['streetlightId']); - if (msg.reply) { - try { - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var dataToPublish : any = responseObject; - for(let hook of publishDataHooks){ - dataToPublish = hook(dataToPublish); - } - nc.publish(msg.reply, dataToPublish); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts b/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts deleted file mode 100644 index f22b47c33..000000000 --- a/test/expected_comparators/latest/frontend/src/channels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts +++ /dev/null @@ -1,32 +0,0 @@ - -import {default as LightMeasuredMessage} from '#messages/LightMeasured' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - - -export function publish( - requestMessage: LightMeasuredMessage, - nc: Client, - - streetlightId: string - - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var dataToPublish : any = requestMessage; - for(let hook of publishDataHooks){ - dataToPublish = hook(dataToPublish); - } - nc.publish(`smartylighting.streetlights.1.0.event.${streetlightId}.lighting.measured`, dataToPublish); - resolve(); - }catch(e){ - reject(e); - } - }else{ - reject(new Error("Nats client is not connected")); - } - }); -}; - diff --git a/test/expected_comparators/latest/frontend/src/hooks.ts b/test/expected_comparators/latest/frontend/src/hooks.ts deleted file mode 100644 index 51e71a158..000000000 --- a/test/expected_comparators/latest/frontend/src/hooks.ts +++ /dev/null @@ -1,60 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as walkSync from 'klaw-sync'; -export enum AvailableHooks { - RecievedData = 'RecievedData', - BeforeSendingData = 'BeforeSendingData' -} -export type RecievedDataHook = (receivedData: any) => string; -export type BeforeSendingDataHook = (messageToSend: any) => string; -export class Hooks { - private static instance: Hooks; - - private hooks: { - BeforeSendingData: BeforeSendingDataHook[]; - RecievedData: RecievedDataHook[]; - }; - private constructor() { - this.hooks = { - BeforeSendingData: [], - RecievedData: [] - } - } - public static getInstance(): Hooks { - if (!Hooks.instance) { - Hooks.instance = new Hooks(); - } - return Hooks.instance; - } - - - - /** - * Register a hook for BeforeSendingData - * @param hook - */ - public async registerBeforeSendingData(hook: BeforeSendingDataHook) { - this.hooks[AvailableHooks.BeforeSendingData] - ? this.hooks[AvailableHooks.BeforeSendingData].push(hook) - : [hook]; - } - - /** - * Register a hook for BeforeSendingData - * @param hook - */ - public async registerRecievedData(hook: RecievedDataHook) { - this.hooks[AvailableHooks.RecievedData] - ? this.hooks[AvailableHooks.RecievedData].push(hook) - : [hook]; - } - - - public getRecievedDataHook(): RecievedDataHook[] { - return this.hooks[AvailableHooks.RecievedData]; - } - - public getBeforeSendingDataHook(): BeforeSendingDataHook[] { - return this.hooks[AvailableHooks.BeforeSendingData]; - } -} \ No newline at end of file diff --git a/test/expected_comparators/latest/frontend/src/index.ts b/test/expected_comparators/latest/frontend/src/index.ts deleted file mode 100644 index 4e24e6775..000000000 --- a/test/expected_comparators/latest/frontend/src/index.ts +++ /dev/null @@ -1,240 +0,0 @@ - - -import { - Client, - NatsConnectionOptions, - connect, - Payload, - NatsError, - Subscription, - ServersChangedEvent, - SubEvent, - ServerInfo - } from 'ts-nats'; -import * as smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel from "#testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured"; -import * as smartylightingStreetlights10ActionStreetlightIdTurnOnChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn"; -import * as smartylightingStreetlights10ActionStreetlightIdTurnOffChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff"; -import * as smartylightingStreetlights10ActionStreetlightIdDimChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdDim"; -import {default as LightMeasuredMessage} from "#messages/LightMeasured"; -import {default as TurnOnOffResponseMessage} from "#messages/TurnOnOffResponse"; -import {default as TurnOnOffMessage} from "#messages/TurnOnOff"; -import {default as DimLightResponseMessage} from "#messages/DimLightResponse"; -import {default as DimLightMessage} from "#messages/DimLight"; -import {fromSeed} from 'ts-nkeys'; -import * as events from 'events'; -export enum AvailableEvents { - connectionError = 'connectionError', - permissionError = 'permissionError', - close = 'close', - connect = 'connect', - connecting = 'connecting', - disconnect = 'disconnect', - error = 'error', - pingcount = 'pingcount', - pingtimer = 'pingtimer', - reconnect = 'reconnect', - reconnecting = 'reconnecting', - serversChanged = 'serversChanged', - subscribe = 'subscribe', - unsubscribe = 'unsubscribe', - yield = 'yield' -} -export declare interface NatsAsyncApiTestClient { - on(event: AvailableEvents.connectionError, listener: (error: any) => void): this; - on(event: AvailableEvents.permissionError, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.close, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; - on(event: AvailableEvents.connecting, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; - on(event: AvailableEvents.error, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.pingcount, listener: () => void): this; - on(event: AvailableEvents.pingtimer, listener: () => void): this; - on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; - on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; - on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; - on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; - on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; - on(event: AvailableEvents.yield, listener: () => void): this; -} -export class NatsAsyncApiTestClient extends events.EventEmitter{ - public jsonClient?: Client; - public stringClient?: Client; - public binaryClient?: Client; - public options?: NatsConnectionOptions; - - /** - * - * @param options options to use, payload is omitted if sat in the AsyncAPI document. - */ - constructor() { - super(); - } - - /** - * Try to connect to the NATS server with the different payloads. - */ - async connect(options : NatsConnectionOptions){ - this.options = this.setDefaultOptions(options); - try{ - this.options.payload = Payload.JSON; - this.jsonClient = await connect(this.options); - this.chainEvents(this.jsonClient); - }catch(e){ - this.emit(AvailableEvents.connectionError, e) - } - } - - - /** - * Disconnect all clients from the server - */ - async disconnect(){ - this.jsonClient!.close() - } - - private chainEvents(ns: Client){ - ns.on('permissionError', (e: NatsError) => { - this.emit(AvailableEvents.permissionError, e) - }); - ns.on('close', (e: NatsError) => { - this.emit(AvailableEvents.close, e) - }); - ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { - this.emit(AvailableEvents.connect, connection, serverURL, info) - }); - ns.on('connecting', (serverURL: NatsError) => { - this.emit(AvailableEvents.connecting, serverURL) - }); - ns.on('disconnect', (serverURL: string) => { - this.emit(AvailableEvents.disconnect, serverURL) - }); - ns.on('error', (e: NatsError) => { - this.emit(AvailableEvents.error, e) - }); - ns.on('pingcount', () => { - this.emit(AvailableEvents.pingcount) - }); - ns.on('pingtimer', () => { - this.emit(AvailableEvents.pingtimer) - }); - ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { - this.emit(AvailableEvents.reconnect, connection, serverURL, info) - }); - ns.on('reconnecting', (serverURL: string) => { - this.emit(AvailableEvents.reconnecting, serverURL) - }); - ns.on('serversChanged', (e: ServersChangedEvent) => { - this.emit(AvailableEvents.serversChanged, e) - }); - ns.on('subscribe', (e: SubEvent) => { - this.emit(AvailableEvents.subscribe, e) - }); - ns.on('unsubscribe', (e: SubEvent) => { - this.emit(AvailableEvents.unsubscribe, e) - }); - ns.on('yield', () => { - this.emit(AvailableEvents.yield) - }); - } - /** - * Try to connect to the NATS server with nkey authentication - */ - async connectWithNkey(options : NatsConnectionOptions, publicNkey: string, seed: string){ - options.nkey = publicNkey; - options.nonceSigner = (nonce: string): Buffer => { - const sk = fromSeed(Buffer.from(seed)); - return sk.sign(Buffer.from(nonce)); - } - await this.connect(options); - } - /** - * Set the default options based on the AsyncAPI file. - * @param options to set - */ - private setDefaultOptions(options: NatsConnectionOptions){ - //If server binding options sat set the options - options.encoding = 'utf8'; - return options; - } - - - - /** - * Any measured values will be published through this method. - * @param onDataCallback Called when message recieved. - */ - public subscribeToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage, streetlightId?: string) => void - ,streetlightId: string - ): Promise { - const nc: Client = this.jsonClient!; - if(nc){ - return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.subscribe(onDataCallback, nc - - ,streetlightId - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10EventStreetlightIdLightingMeasured')) - } - } - - - /** - * Get notified when a streetlight should be turned on. This should only be handled by 1 subscriber but ensured by request reply. - * @param requestMessage The request message to send. - */ - public requestSmartylightingStreetlights10ActionStreetlightIdTurnOn(requestMessage: TurnOnOffMessage - - ,streetlightId: string - ): Promise { - const nc: Client = this.jsonClient!; - if(nc){ - return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.request(requestMessage, nc - - ,streetlightId - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdTurnOn')) - } - } - - - /** - * Get notified when a streetlight should be turned off. This should only be handled by 1 subscriber but ensured by request reply. - * @param requestMessage The request message to send. - */ - public requestSmartylightingStreetlights10ActionStreetlightIdTurnOff(requestMessage: TurnOnOffMessage - - ,streetlightId: string - ): Promise { - const nc: Client = this.jsonClient!; - if(nc){ - return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.request(requestMessage, nc - - ,streetlightId - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdTurnOff')) - } - } - - - /** - * Get notified when a streetlight should be dimmed. This should only be handled by 1 subscriber but ensured by request reply. - * @param requestMessage The request message to send. - */ - public requestSmartylightingStreetlights10ActionStreetlightIdDim(requestMessage: DimLightMessage - - ,streetlightId: string - ): Promise { - const nc: Client = this.jsonClient!; - if(nc){ - return smartylightingStreetlights10ActionStreetlightIdDimChannel.request(requestMessage, nc - - ,streetlightId - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdDim')) - } - } - -} diff --git a/test/expected_comparators/latest/frontend/src/messages/DimLight.ts b/test/expected_comparators/latest/frontend/src/messages/DimLight.ts deleted file mode 100644 index 019165814..000000000 --- a/test/expected_comparators/latest/frontend/src/messages/DimLight.ts +++ /dev/null @@ -1,29 +0,0 @@ - -import { default as DimLightPayloadserereSchema } from '#schemas/DimLightPayloadserere'; -import { default as ResponseSchema } from '#schemas/Response'; -export default class DimLight { - - - - dimLightPayloadserere:DimLightPayloadserereSchema; - - - - response:ResponseSchema; - - - constructor( - - ){ - - } - - /** - * Parses a JSON string to an object of DimLight message class. - * @param json any to be parsed as DimLight. - */ - public static toMessage(json: any): DimLight { - return JSON.parse(JSON.stringify(json)); - } - -} diff --git a/test/expected_comparators/latest/frontend/src/messages/DimLightResponse.ts b/test/expected_comparators/latest/frontend/src/messages/DimLightResponse.ts deleted file mode 100644 index a9733f541..000000000 --- a/test/expected_comparators/latest/frontend/src/messages/DimLightResponse.ts +++ /dev/null @@ -1,26 +0,0 @@ - -import { default as ResponseSchema } from '#schemas/Response'; -export default class DimLightResponse { - - - response:ResponseSchema; - - - constructor( - response: ResponseSchema - ){ - - - this.response = response; - - } - - /** - * Parses a JSON string to an object of DimLightResponse message class. - * @param json any to be parsed as DimLightResponse. - */ - public static toMessage(json: any): DimLightResponse { - return JSON.parse(JSON.stringify(json)); - } - -} diff --git a/test/expected_comparators/latest/frontend/src/messages/LightMeasured.ts b/test/expected_comparators/latest/frontend/src/messages/LightMeasured.ts deleted file mode 100644 index 39931197c..000000000 --- a/test/expected_comparators/latest/frontend/src/messages/LightMeasured.ts +++ /dev/null @@ -1,26 +0,0 @@ - -import { default as LightMeasuredPayloadSchema } from '#schemas/LightMeasuredPayload'; -export default class LightMeasured { - - - lightMeasuredPayload:LightMeasuredPayloadSchema; - - - constructor( - lightMeasuredPayload: LightMeasuredPayloadSchema - ){ - - - this.lightMeasuredPayload = lightMeasuredPayload; - - } - - /** - * Parses a JSON string to an object of LightMeasured message class. - * @param json any to be parsed as LightMeasured. - */ - public static toMessage(json: any): LightMeasured { - return JSON.parse(JSON.stringify(json)); - } - -} diff --git a/test/expected_comparators/latest/frontend/src/messages/TurnOnOff.ts b/test/expected_comparators/latest/frontend/src/messages/TurnOnOff.ts deleted file mode 100644 index 5d990599a..000000000 --- a/test/expected_comparators/latest/frontend/src/messages/TurnOnOff.ts +++ /dev/null @@ -1,26 +0,0 @@ - -import { default as TurnOnOffPayloadSchema } from '#schemas/TurnOnOffPayload'; -export default class TurnOnOff { - - - turnOnOffPayload:TurnOnOffPayloadSchema; - - - constructor( - turnOnOffPayload: TurnOnOffPayloadSchema - ){ - - - this.turnOnOffPayload = turnOnOffPayload; - - } - - /** - * Parses a JSON string to an object of TurnOnOff message class. - * @param json any to be parsed as TurnOnOff. - */ - public static toMessage(json: any): TurnOnOff { - return JSON.parse(JSON.stringify(json)); - } - -} diff --git a/test/expected_comparators/latest/frontend/src/messages/TurnOnOffResponse.ts b/test/expected_comparators/latest/frontend/src/messages/TurnOnOffResponse.ts deleted file mode 100644 index ba0b02f5e..000000000 --- a/test/expected_comparators/latest/frontend/src/messages/TurnOnOffResponse.ts +++ /dev/null @@ -1,26 +0,0 @@ - -import { default as ResponseSchema } from '#schemas/Response'; -export default class TurnOnOffResponse { - - - response:ResponseSchema; - - - constructor( - response: ResponseSchema - ){ - - - this.response = response; - - } - - /** - * Parses a JSON string to an object of TurnOnOffResponse message class. - * @param json any to be parsed as TurnOnOffResponse. - */ - public static toMessage(json: any): TurnOnOffResponse { - return JSON.parse(JSON.stringify(json)); - } - -} diff --git a/test/expected_comparators/latest/frontend/src/schema/DimLightPayloadserere.ts b/test/expected_comparators/latest/frontend/src/schema/DimLightPayloadserere.ts deleted file mode 100644 index 279439192..000000000 --- a/test/expected_comparators/latest/frontend/src/schema/DimLightPayloadserere.ts +++ /dev/null @@ -1,19 +0,0 @@ - - - -export default class dimLightPayloadserere { - - - percentage?: Number - sentAt?: string - - - - constructor( - - ){ - - - - } -} diff --git a/test/expected_comparators/latest/frontend/src/schema/LightMeasuredPayload.ts b/test/expected_comparators/latest/frontend/src/schema/LightMeasuredPayload.ts deleted file mode 100644 index e090e2247..000000000 --- a/test/expected_comparators/latest/frontend/src/schema/LightMeasuredPayload.ts +++ /dev/null @@ -1,19 +0,0 @@ - - - -export default class lightMeasuredPayload { - - - lumens?: Number - sentAt?: string - - - - constructor( - - ){ - - - - } -} diff --git a/test/expected_comparators/latest/frontend/src/schema/Response.ts b/test/expected_comparators/latest/frontend/src/schema/Response.ts deleted file mode 100644 index afc8c5d71..000000000 --- a/test/expected_comparators/latest/frontend/src/schema/Response.ts +++ /dev/null @@ -1,21 +0,0 @@ - - - -export default class response { - - - status?: Number - statusMessage?: string - sentAt?: string - - - - constructor( - - ){ - - - - - } -} diff --git a/test/expected_comparators/latest/frontend/src/schema/TurnOnOffPayload.ts b/test/expected_comparators/latest/frontend/src/schema/TurnOnOffPayload.ts deleted file mode 100644 index f35e771e2..000000000 --- a/test/expected_comparators/latest/frontend/src/schema/TurnOnOffPayload.ts +++ /dev/null @@ -1,19 +0,0 @@ - - - -export default class turnOnOffPayload { - - - command?: string - sentAt?: string - - - - constructor( - - ){ - - - - } -} diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/index.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/index.ts deleted file mode 100644 index 08d2dd055..000000000 --- a/test/expected_comparators/latest/frontend/src/tests/testclient/index.ts +++ /dev/null @@ -1,247 +0,0 @@ - - -import { - Client, - NatsConnectionOptions, - connect, - Payload, - NatsError, - Subscription, - ServersChangedEvent, - SubEvent, - ServerInfo - } from 'ts-nats'; -import * as smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel from "#testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured"; -import * as smartylightingStreetlights10ActionStreetlightIdTurnOnChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn"; -import * as smartylightingStreetlights10ActionStreetlightIdTurnOffChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff"; -import * as smartylightingStreetlights10ActionStreetlightIdDimChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdDim"; -import {default as LightMeasuredMessage} from "#messages/LightMeasured"; -import {default as TurnOnOffResponseMessage} from "#messages/TurnOnOffResponse"; -import {default as TurnOnOffMessage} from "#messages/TurnOnOff"; -import {default as DimLightResponseMessage} from "#messages/DimLightResponse"; -import {default as DimLightMessage} from "#messages/DimLight"; -import {fromSeed} from 'ts-nkeys'; -import * as events from 'events'; -export enum AvailableEvents { - connectionError = 'connectionError', - permissionError = 'permissionError', - close = 'close', - connect = 'connect', - connecting = 'connecting', - disconnect = 'disconnect', - error = 'error', - pingcount = 'pingcount', - pingtimer = 'pingtimer', - reconnect = 'reconnect', - reconnecting = 'reconnecting', - serversChanged = 'serversChanged', - subscribe = 'subscribe', - unsubscribe = 'unsubscribe', - yield = 'yield' -} -export declare interface NatsAsyncApiTestClient { - on(event: AvailableEvents.connectionError, listener: (error: any) => void): this; - on(event: AvailableEvents.permissionError, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.close, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; - on(event: AvailableEvents.connecting, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; - on(event: AvailableEvents.error, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.pingcount, listener: () => void): this; - on(event: AvailableEvents.pingtimer, listener: () => void): this; - on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; - on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; - on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; - on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; - on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; - on(event: AvailableEvents.yield, listener: () => void): this; -} -export class NatsAsyncApiTestClient extends events.EventEmitter{ - public jsonClient?: Client; - public stringClient?: Client; - public binaryClient?: Client; - public options?: NatsConnectionOptions; - - /** - * - * @param options options to use, payload is omitted if sat in the AsyncAPI document. - */ - constructor() { - super(); - } - - /** - * Try to connect to the NATS server with the different payloads. - */ - async connect(options : NatsConnectionOptions){ - this.options = this.setDefaultOptions(options); - try{ - this.options.payload = Payload.JSON; - this.jsonClient = await connect(this.options); - this.chainEvents(this.jsonClient); - }catch(e){ - this.emit(AvailableEvents.connectionError, e) - } - } - - - /** - * Disconnect all clients from the server - */ - async disconnect(){ - this.jsonClient!.close() - } - - private chainEvents(ns: Client){ - ns.on('permissionError', (e: NatsError) => { - this.emit(AvailableEvents.permissionError, e) - }); - ns.on('close', (e: NatsError) => { - this.emit(AvailableEvents.close, e) - }); - ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { - this.emit(AvailableEvents.connect, connection, serverURL, info) - }); - ns.on('connecting', (serverURL: NatsError) => { - this.emit(AvailableEvents.connecting, serverURL) - }); - ns.on('disconnect', (serverURL: string) => { - this.emit(AvailableEvents.disconnect, serverURL) - }); - ns.on('error', (e: NatsError) => { - this.emit(AvailableEvents.error, e) - }); - ns.on('pingcount', () => { - this.emit(AvailableEvents.pingcount) - }); - ns.on('pingtimer', () => { - this.emit(AvailableEvents.pingtimer) - }); - ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { - this.emit(AvailableEvents.reconnect, connection, serverURL, info) - }); - ns.on('reconnecting', (serverURL: string) => { - this.emit(AvailableEvents.reconnecting, serverURL) - }); - ns.on('serversChanged', (e: ServersChangedEvent) => { - this.emit(AvailableEvents.serversChanged, e) - }); - ns.on('subscribe', (e: SubEvent) => { - this.emit(AvailableEvents.subscribe, e) - }); - ns.on('unsubscribe', (e: SubEvent) => { - this.emit(AvailableEvents.unsubscribe, e) - }); - ns.on('yield', () => { - this.emit(AvailableEvents.yield) - }); - } - /** - * Try to connect to the NATS server with nkey authentication - */ - async connectWithNkey(options : NatsConnectionOptions, publicNkey: string, seed: string){ - options.nkey = publicNkey; - options.nonceSigner = (nonce: string): Buffer => { - const sk = fromSeed(Buffer.from(seed)); - return sk.sign(Buffer.from(nonce)); - } - await this.connect(options); - } - /** - * Set the default options based on the AsyncAPI file. - * @param options to set - */ - private setDefaultOptions(options: NatsConnectionOptions){ - //If server binding options sat set the options - options.encoding = 'utf8'; - return options; - } - - - - /** - * Any measured values will be published through this method. - * @param requestMessage The message to publish. - */ - public publishToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(requestMessage: LightMeasuredMessage - ,streetlightId: string - ): Promise { - const nc: Client = this.jsonClient!; - if(nc){ - return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.publish(requestMessage, nc - - ,streetlightId - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10EventStreetlightIdLightingMeasured')) - } - } - - - /** - * Get notified when a streetlight should be turned on. This should only be handled by 1 subscriber but ensured by request reply. - * @param onRequest Called when request recieved. - * @param onReplyError Called when it was not possible to send the reply. - */ - public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOn(onRequest : (err?: NatsError, msg?: TurnOnOffMessage, streetlightId?: string) =>Promise, onReplyError : (err: NatsError) => void - - ,streetlightId: string - ): Promise { - const nc: Client = this.jsonClient!; - - if(nc){ - return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.reply(onRequest, onReplyError, nc - - ,streetlightId - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdTurnOn')) - } - } - - - /** - * Get notified when a streetlight should be turned off. This should only be handled by 1 subscriber but ensured by request reply. - * @param onRequest Called when request recieved. - * @param onReplyError Called when it was not possible to send the reply. - */ - public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOff(onRequest : (err?: NatsError, msg?: TurnOnOffMessage, streetlightId?: string) =>Promise, onReplyError : (err: NatsError) => void - - ,streetlightId: string - ): Promise { - const nc: Client = this.jsonClient!; - - if(nc){ - return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.reply(onRequest, onReplyError, nc - - ,streetlightId - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdTurnOff')) - } - } - - - /** - * Get notified when a streetlight should be dimmed. This should only be handled by 1 subscriber but ensured by request reply. - * @param onRequest Called when request recieved. - * @param onReplyError Called when it was not possible to send the reply. - */ - public replyToSmartylightingStreetlights10ActionStreetlightIdDim(onRequest : (err?: NatsError, msg?: DimLightMessage, streetlightId?: string) =>Promise, onReplyError : (err: NatsError) => void - - ,streetlightId: string - ): Promise { - const nc: Client = this.jsonClient!; - - if(nc){ - return smartylightingStreetlights10ActionStreetlightIdDimChannel.reply(onRequest, onReplyError, nc - - ,streetlightId - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdDim')) - } - } - - -} \ No newline at end of file diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdDim.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdDim.ts deleted file mode 100644 index d1226a2e2..000000000 --- a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdDim.ts +++ /dev/null @@ -1,45 +0,0 @@ - -import {default as DimLightResponseMessage} from '#messages/DimLightResponse' -import {default as DimLightMessage} from '#messages/DimLight' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - -export function request( - requestMessage: DimLightMessage, - nc: Client, - - streetlightId: string - - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived : any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - resolve(DimLightResponseMessage.toMessage(processedDataReceived)); - } - }, { max: 1 }); - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var requestData : any = requestMessage; - for(let hook of publishDataHooks){ - requestData = hook(requestData); - } - nc.publish(`smartylighting.streetlights.1.0.action.${streetlightId}.dim`, requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts deleted file mode 100644 index 82264c772..000000000 --- a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts +++ /dev/null @@ -1,45 +0,0 @@ - -import {default as TurnOnOffResponseMessage} from '#messages/TurnOnOffResponse' -import {default as TurnOnOffMessage} from '#messages/TurnOnOff' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - -export function request( - requestMessage: TurnOnOffMessage, - nc: Client, - - streetlightId: string - - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived : any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - resolve(TurnOnOffResponseMessage.toMessage(processedDataReceived)); - } - }, { max: 1 }); - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var requestData : any = requestMessage; - for(let hook of publishDataHooks){ - requestData = hook(requestData); - } - nc.publish(`smartylighting.streetlights.1.0.action.${streetlightId}.turn.off`, requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts deleted file mode 100644 index 9b8d42c4e..000000000 --- a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts +++ /dev/null @@ -1,45 +0,0 @@ - -import {default as TurnOnOffResponseMessage} from '#messages/TurnOnOffResponse' -import {default as TurnOnOffMessage} from '#messages/TurnOnOff' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - -export function request( - requestMessage: TurnOnOffMessage, - nc: Client, - - streetlightId: string - - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived : any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - resolve(TurnOnOffResponseMessage.toMessage(processedDataReceived)); - } - }, { max: 1 }); - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var requestData : any = requestMessage; - for(let hook of publishDataHooks){ - requestData = hook(requestData); - } - nc.publish(`smartylighting.streetlights.1.0.action.${streetlightId}.turn.on`, requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts b/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts deleted file mode 100644 index 5b4233d67..000000000 --- a/test/expected_comparators/latest/frontend/src/tests/testclient/testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts +++ /dev/null @@ -1,42 +0,0 @@ - -import {default as LightMeasuredMessage} from '#messages/LightMeasured' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - -export function subscribe( - onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage, streetlightId?: string) => void, - nc: Client, - - streetlightId: string - - ): Promise { - return new Promise(async (resolve, reject) => { - try{ - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(`smartylighting.streetlights.1.0.event.${streetlightId}.lighting.measured`, (err, msg) => { - if(err){ - onDataCallback(err); - }else{ - const unmodifiedChannel = `smartylighting.streetlights.1.0.event.{streetlightId}.lighting.measured` - const receivedTopicParameters = { - streetlightId : msg.subject.slice(unmodifiedChannel.split("${streetlightId}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlightId}")[1].length) - } - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived: any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - let publishedData = LightMeasuredMessage.toMessage(processedDataReceived); - onDataCallback(undefined, publishedData, - receivedTopicParameters['streetlightId']); - } - }, subscribeOptions); - resolve(subscription); - }catch(e){ - reject(e); - } - }) -} - - diff --git a/test/expected_comparators/latest/frontend/tsconfig.json b/test/expected_comparators/latest/frontend/tsconfig.json deleted file mode 100644 index b1d6a9fac..000000000 --- a/test/expected_comparators/latest/frontend/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "declaration": true, - "strict": true, - "noImplicitAny": true, - "removeComments": true, - "preserveConstEnums": true, - "sourceMap": true, - "outDir": "dist/", - "baseUrl": "./src", - "paths": { - "#messages/*": ["messages/*"], - "#schemas/*": ["schema/*"], - "#channels/*": ["channels/*"], - "#testchannels/*": ["tests/testclient/testchannels/*"], - "#hooks": ["hooks"], - "#testclient": ["tests/testclient/index"], - "#client": ["index"] - } - }, - "include": ["src"], - "exclude": ["node_modules", "**/*.spec.ts"] -} diff --git a/test/expected_comparators/latest/light-controller/README.md b/test/expected_comparators/latest/light-controller/README.md deleted file mode 100644 index fb373e91a..000000000 --- a/test/expected_comparators/latest/light-controller/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Streetlights Nats API for the frontend - -The Smartylighting Streetlights API allows you to remotely manage the city lights. - -This is for the frontend where the lights can be controlled, which assumed are multiple instances to ensure availability. - -### Check out its awesome features: - -* Turn a specific streetlight on/off 🌃 -* Dim a specific streetlight 😎 -* Receive real-time information about environmental lighting conditions 📈 - - - - -Available nats encodings: -https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings diff --git a/test/expected_comparators/latest/light-controller/package.json b/test/expected_comparators/latest/light-controller/package.json deleted file mode 100644 index ef851e192..000000000 --- a/test/expected_comparators/latest/light-controller/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - - - - "name": "streetlights-nats-api-for-the-frontend", - "description": "The Smartylighting Streetlights API allows you to remotely manage the city lights. This is for the frontend where the lights can be controlled, which assumed are multiple instances to ensure availability. ### Check out its awesome features: * Turn a specific streetlight on/off 🌃 * Dim a specific streetlight 😎 * Receive real-time information about environmental lighting conditions 📈 ", - "version": "1.0.0", - "main": "dist/index.js", - "types": "dist/index.d.ts", - "scripts": { - "watch": "tsc --watch", - "build": "tsc && npm run dopostinstall", - "start": "node src/api/index.js", - "dopostinstall": "link-module-alias", - "test": "mocha -r ts-node/register tests/**/*.spec.ts" - }, - "_moduleAliasIgnoreWarning": true, - "_moduleAliases": { - "#messages": "dist/messages/", - "#schemas": "dist/schema/", - "#channels": "dist/channels/", - "#testchannels": "dist/tests/testclient/testchannels/", - "#hooks": "dist/hooks.js", - "#testclient": "dist/tests/testclient/index.js" - }, - "dependencies": { - "@types/klaw-sync": "^6.0.0", - "@types/node": "13.9.5", - "klaw-sync": "6.0.0", - "link-module-alias": "^1.2.0", - "ts-nats": "1.2.4", - "typescript": "3.4.3", - "ts-nkeys":"1.0.16" - }, - "devDependencies": { - "@types/chai": "^4.2.11", - "@types/mocha": "^7.0.2", - "chai": "^4.2.0", - "mocha": "^7.1.1", - "ts-node": "^8.8.1" - } -} diff --git a/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdDim.ts b/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdDim.ts deleted file mode 100644 index c6c715182..000000000 --- a/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdDim.ts +++ /dev/null @@ -1,45 +0,0 @@ - -import {default as DimLightMessage} from '#messages/DimLight' -import {default as DimLightResponseMessage} from '#messages/DimLightResponse' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - -export function request( - requestMessage: DimLightMessage, - nc: Client, - - streetlightId: string - - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived : any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - resolve(DimLightResponseMessage.toMessage(processedDataReceived)); - } - }, { max: 1 }); - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var requestData : any = requestMessage; - for(let hook of publishDataHooks){ - requestData = hook(requestData); - } - nc.publish(`smartylighting.streetlights.1.0.action.${streetlightId}.dim`, requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts b/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts deleted file mode 100644 index 5dbd4b06f..000000000 --- a/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts +++ /dev/null @@ -1,45 +0,0 @@ - -import {default as TurnOnOffMessage} from '#messages/TurnOnOff' -import {default as TurnOnOffResponseMessage} from '#messages/TurnOnOffResponse' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - -export function request( - requestMessage: TurnOnOffMessage, - nc: Client, - - streetlightId: string - - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived : any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - resolve(TurnOnOffResponseMessage.toMessage(processedDataReceived)); - } - }, { max: 1 }); - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var requestData : any = requestMessage; - for(let hook of publishDataHooks){ - requestData = hook(requestData); - } - nc.publish(`smartylighting.streetlights.1.0.action.${streetlightId}.turn.off`, requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts b/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts deleted file mode 100644 index 7a6fb17d6..000000000 --- a/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts +++ /dev/null @@ -1,45 +0,0 @@ - -import {default as TurnOnOffMessage} from '#messages/TurnOnOff' -import {default as TurnOnOffResponseMessage} from '#messages/TurnOnOffResponse' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - -export function request( - requestMessage: TurnOnOffMessage, - nc: Client, - - streetlightId: string - - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let inbox = nc.createInbox(); - await nc.subscribe(inbox, (err, msg) => { - if (err) { - reject(err); - } else { - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived : any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - resolve(TurnOnOffResponseMessage.toMessage(processedDataReceived)); - } - }, { max: 1 }); - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var requestData : any = requestMessage; - for(let hook of publishDataHooks){ - requestData = hook(requestData); - } - nc.publish(`smartylighting.streetlights.1.0.action.${streetlightId}.turn.on`, requestData, inbox); - }catch(e){ - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10Event.ts b/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10Event.ts deleted file mode 100644 index 3cb901a44..000000000 --- a/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10Event.ts +++ /dev/null @@ -1,35 +0,0 @@ - -import {default as LightMeasuredMessage} from '#messages/LightMeasured' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - -export function subscribe( - onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage) => void, - nc: Client, - - ): Promise { - return new Promise(async (resolve, reject) => { - try{ - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(`smartylighting.streetlights.1.0.event.*`, (err, msg) => { - if(err){ - onDataCallback(err); - }else{ - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived: any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - let publishedData = LightMeasuredMessage.toMessage(processedDataReceived); - onDataCallback(undefined, publishedData); - } - }, subscribeOptions); - resolve(subscription); - }catch(e){ - reject(e); - } - }) -} - - diff --git a/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts b/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts deleted file mode 100644 index 5b4233d67..000000000 --- a/test/expected_comparators/latest/light-controller/src/channels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts +++ /dev/null @@ -1,42 +0,0 @@ - -import {default as LightMeasuredMessage} from '#messages/LightMeasured' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - -export function subscribe( - onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage, streetlightId?: string) => void, - nc: Client, - - streetlightId: string - - ): Promise { - return new Promise(async (resolve, reject) => { - try{ - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(`smartylighting.streetlights.1.0.event.${streetlightId}.lighting.measured`, (err, msg) => { - if(err){ - onDataCallback(err); - }else{ - const unmodifiedChannel = `smartylighting.streetlights.1.0.event.{streetlightId}.lighting.measured` - const receivedTopicParameters = { - streetlightId : msg.subject.slice(unmodifiedChannel.split("${streetlightId}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlightId}")[1].length) - } - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived: any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - let publishedData = LightMeasuredMessage.toMessage(processedDataReceived); - onDataCallback(undefined, publishedData, - receivedTopicParameters['streetlightId']); - } - }, subscribeOptions); - resolve(subscription); - }catch(e){ - reject(e); - } - }) -} - - diff --git a/test/expected_comparators/latest/light-controller/src/hooks.ts b/test/expected_comparators/latest/light-controller/src/hooks.ts deleted file mode 100644 index 51e71a158..000000000 --- a/test/expected_comparators/latest/light-controller/src/hooks.ts +++ /dev/null @@ -1,60 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as walkSync from 'klaw-sync'; -export enum AvailableHooks { - RecievedData = 'RecievedData', - BeforeSendingData = 'BeforeSendingData' -} -export type RecievedDataHook = (receivedData: any) => string; -export type BeforeSendingDataHook = (messageToSend: any) => string; -export class Hooks { - private static instance: Hooks; - - private hooks: { - BeforeSendingData: BeforeSendingDataHook[]; - RecievedData: RecievedDataHook[]; - }; - private constructor() { - this.hooks = { - BeforeSendingData: [], - RecievedData: [] - } - } - public static getInstance(): Hooks { - if (!Hooks.instance) { - Hooks.instance = new Hooks(); - } - return Hooks.instance; - } - - - - /** - * Register a hook for BeforeSendingData - * @param hook - */ - public async registerBeforeSendingData(hook: BeforeSendingDataHook) { - this.hooks[AvailableHooks.BeforeSendingData] - ? this.hooks[AvailableHooks.BeforeSendingData].push(hook) - : [hook]; - } - - /** - * Register a hook for BeforeSendingData - * @param hook - */ - public async registerRecievedData(hook: RecievedDataHook) { - this.hooks[AvailableHooks.RecievedData] - ? this.hooks[AvailableHooks.RecievedData].push(hook) - : [hook]; - } - - - public getRecievedDataHook(): RecievedDataHook[] { - return this.hooks[AvailableHooks.RecievedData]; - } - - public getBeforeSendingDataHook(): BeforeSendingDataHook[] { - return this.hooks[AvailableHooks.BeforeSendingData]; - } -} \ No newline at end of file diff --git a/test/expected_comparators/latest/light-controller/src/index.ts b/test/expected_comparators/latest/light-controller/src/index.ts deleted file mode 100644 index 6f81c6998..000000000 --- a/test/expected_comparators/latest/light-controller/src/index.ts +++ /dev/null @@ -1,262 +0,0 @@ - - -import { - Client, - NatsConnectionOptions, - connect, - Payload, - NatsError, - Subscription, - ServersChangedEvent, - SubEvent, - ServerInfo - } from 'ts-nats'; -import * as smartylightingStreetlights10EventChannel from "#testchannels/SmartylightingStreetlights10Event"; -import * as smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel from "#testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured"; -import * as smartylightingStreetlights10ActionStreetlightIdTurnOnChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn"; -import * as smartylightingStreetlights10ActionStreetlightIdTurnOffChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff"; -import * as smartylightingStreetlights10ActionStreetlightIdDimChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdDim"; -import {default as LightMeasuredMessage} from "#messages/LightMeasured"; -import {default as TurnOnOffMessage} from "#messages/TurnOnOff"; -import {default as TurnOnOffResponseMessage} from "#messages/TurnOnOffResponse"; -import {default as DimLightMessage} from "#messages/DimLight"; -import {default as DimLightResponseMessage} from "#messages/DimLightResponse"; -import {fromSeed} from 'ts-nkeys'; -import * as events from 'events'; -export enum AvailableEvents { - connectionError = 'connectionError', - permissionError = 'permissionError', - close = 'close', - connect = 'connect', - connecting = 'connecting', - disconnect = 'disconnect', - error = 'error', - pingcount = 'pingcount', - pingtimer = 'pingtimer', - reconnect = 'reconnect', - reconnecting = 'reconnecting', - serversChanged = 'serversChanged', - subscribe = 'subscribe', - unsubscribe = 'unsubscribe', - yield = 'yield' -} -export declare interface NatsAsyncApiTestClient { - on(event: AvailableEvents.connectionError, listener: (error: any) => void): this; - on(event: AvailableEvents.permissionError, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.close, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; - on(event: AvailableEvents.connecting, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; - on(event: AvailableEvents.error, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.pingcount, listener: () => void): this; - on(event: AvailableEvents.pingtimer, listener: () => void): this; - on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; - on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; - on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; - on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; - on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; - on(event: AvailableEvents.yield, listener: () => void): this; -} -export class NatsAsyncApiTestClient extends events.EventEmitter{ - public jsonClient?: Client; - public stringClient?: Client; - public binaryClient?: Client; - public options?: NatsConnectionOptions; - - /** - * - * @param options options to use, payload is omitted if sat in the AsyncAPI document. - */ - constructor() { - super(); - } - - /** - * Try to connect to the NATS server with the different payloads. - */ - async connect(options : NatsConnectionOptions){ - this.options = this.setDefaultOptions(options); - try{ - this.options.payload = Payload.JSON; - this.jsonClient = await connect(this.options); - this.chainEvents(this.jsonClient); - }catch(e){ - this.emit(AvailableEvents.connectionError, e) - } - } - - - /** - * Disconnect all clients from the server - */ - async disconnect(){ - this.jsonClient!.close() - } - - private chainEvents(ns: Client){ - ns.on('permissionError', (e: NatsError) => { - this.emit(AvailableEvents.permissionError, e) - }); - ns.on('close', (e: NatsError) => { - this.emit(AvailableEvents.close, e) - }); - ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { - this.emit(AvailableEvents.connect, connection, serverURL, info) - }); - ns.on('connecting', (serverURL: NatsError) => { - this.emit(AvailableEvents.connecting, serverURL) - }); - ns.on('disconnect', (serverURL: string) => { - this.emit(AvailableEvents.disconnect, serverURL) - }); - ns.on('error', (e: NatsError) => { - this.emit(AvailableEvents.error, e) - }); - ns.on('pingcount', () => { - this.emit(AvailableEvents.pingcount) - }); - ns.on('pingtimer', () => { - this.emit(AvailableEvents.pingtimer) - }); - ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { - this.emit(AvailableEvents.reconnect, connection, serverURL, info) - }); - ns.on('reconnecting', (serverURL: string) => { - this.emit(AvailableEvents.reconnecting, serverURL) - }); - ns.on('serversChanged', (e: ServersChangedEvent) => { - this.emit(AvailableEvents.serversChanged, e) - }); - ns.on('subscribe', (e: SubEvent) => { - this.emit(AvailableEvents.subscribe, e) - }); - ns.on('unsubscribe', (e: SubEvent) => { - this.emit(AvailableEvents.unsubscribe, e) - }); - ns.on('yield', () => { - this.emit(AvailableEvents.yield) - }); - } - /** - * Try to connect to the NATS server with nkey authentication - */ - async connectWithNkey(options : NatsConnectionOptions, publicNkey: string, seed: string){ - options.nkey = publicNkey; - options.nonceSigner = (nonce: string): Buffer => { - const sk = fromSeed(Buffer.from(seed)); - return sk.sign(Buffer.from(nonce)); - } - await this.connect(options); - } - /** - * Set the default options based on the AsyncAPI file. - * @param options to set - */ - private setDefaultOptions(options: NatsConnectionOptions){ - //If server binding options sat set the options - options.encoding = 'utf8'; - return options; - } - - - - /** - * Topic for which one can subscribe to all measurements regardless of id. - * @param requestMessage The message to publish. - */ - public publishToSmartylightingStreetlights10Event(requestMessage: LightMeasuredMessage ): Promise { - const nc: Client = this.jsonClient!; - if(nc){ - return smartylightingStreetlights10EventChannel.publish(requestMessage, nc - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10Event')) - } - } - - - /** - * Topic for which one can subscribe to measurements on a specific streetlightId. - * @param requestMessage The message to publish. - */ - public publishToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(requestMessage: LightMeasuredMessage - ,streetlightId: string - ): Promise { - const nc: Client = this.jsonClient!; - if(nc){ - return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.publish(requestMessage, nc - - ,streetlightId - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10EventStreetlightIdLightingMeasured')) - } - } - - - /** - * - * @param onRequest Called when request recieved. - * @param onReplyError Called when it was not possible to send the reply. - */ - public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOn(onRequest : (err?: NatsError, msg?: TurnOnOffMessage, streetlightId?: string) =>Promise, onReplyError : (err: NatsError) => void - - ,streetlightId: string - ): Promise { - const nc: Client = this.jsonClient!; - - if(nc){ - return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.reply(onRequest, onReplyError, nc - - ,streetlightId - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdTurnOn')) - } - } - - - /** - * - * @param onRequest Called when request recieved. - * @param onReplyError Called when it was not possible to send the reply. - */ - public replyToSmartylightingStreetlights10ActionStreetlightIdTurnOff(onRequest : (err?: NatsError, msg?: TurnOnOffMessage, streetlightId?: string) =>Promise, onReplyError : (err: NatsError) => void - - ,streetlightId: string - ): Promise { - const nc: Client = this.jsonClient!; - - if(nc){ - return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.reply(onRequest, onReplyError, nc - - ,streetlightId - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdTurnOff')) - } - } - - - /** - * - * @param onRequest Called when request recieved. - * @param onReplyError Called when it was not possible to send the reply. - */ - public replyToSmartylightingStreetlights10ActionStreetlightIdDim(onRequest : (err?: NatsError, msg?: DimLightMessage, streetlightId?: string) =>Promise, onReplyError : (err: NatsError) => void - - ,streetlightId: string - ): Promise { - const nc: Client = this.jsonClient!; - - if(nc){ - return smartylightingStreetlights10ActionStreetlightIdDimChannel.reply(onRequest, onReplyError, nc - - ,streetlightId - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdDim')) - } - } - -} diff --git a/test/expected_comparators/latest/light-controller/src/messages/DimLight.ts b/test/expected_comparators/latest/light-controller/src/messages/DimLight.ts deleted file mode 100644 index 019165814..000000000 --- a/test/expected_comparators/latest/light-controller/src/messages/DimLight.ts +++ /dev/null @@ -1,29 +0,0 @@ - -import { default as DimLightPayloadserereSchema } from '#schemas/DimLightPayloadserere'; -import { default as ResponseSchema } from '#schemas/Response'; -export default class DimLight { - - - - dimLightPayloadserere:DimLightPayloadserereSchema; - - - - response:ResponseSchema; - - - constructor( - - ){ - - } - - /** - * Parses a JSON string to an object of DimLight message class. - * @param json any to be parsed as DimLight. - */ - public static toMessage(json: any): DimLight { - return JSON.parse(JSON.stringify(json)); - } - -} diff --git a/test/expected_comparators/latest/light-controller/src/messages/DimLightResponse.ts b/test/expected_comparators/latest/light-controller/src/messages/DimLightResponse.ts deleted file mode 100644 index a9733f541..000000000 --- a/test/expected_comparators/latest/light-controller/src/messages/DimLightResponse.ts +++ /dev/null @@ -1,26 +0,0 @@ - -import { default as ResponseSchema } from '#schemas/Response'; -export default class DimLightResponse { - - - response:ResponseSchema; - - - constructor( - response: ResponseSchema - ){ - - - this.response = response; - - } - - /** - * Parses a JSON string to an object of DimLightResponse message class. - * @param json any to be parsed as DimLightResponse. - */ - public static toMessage(json: any): DimLightResponse { - return JSON.parse(JSON.stringify(json)); - } - -} diff --git a/test/expected_comparators/latest/light-controller/src/messages/LightMeasured.ts b/test/expected_comparators/latest/light-controller/src/messages/LightMeasured.ts deleted file mode 100644 index 39931197c..000000000 --- a/test/expected_comparators/latest/light-controller/src/messages/LightMeasured.ts +++ /dev/null @@ -1,26 +0,0 @@ - -import { default as LightMeasuredPayloadSchema } from '#schemas/LightMeasuredPayload'; -export default class LightMeasured { - - - lightMeasuredPayload:LightMeasuredPayloadSchema; - - - constructor( - lightMeasuredPayload: LightMeasuredPayloadSchema - ){ - - - this.lightMeasuredPayload = lightMeasuredPayload; - - } - - /** - * Parses a JSON string to an object of LightMeasured message class. - * @param json any to be parsed as LightMeasured. - */ - public static toMessage(json: any): LightMeasured { - return JSON.parse(JSON.stringify(json)); - } - -} diff --git a/test/expected_comparators/latest/light-controller/src/messages/TurnOnOff.ts b/test/expected_comparators/latest/light-controller/src/messages/TurnOnOff.ts deleted file mode 100644 index 5d990599a..000000000 --- a/test/expected_comparators/latest/light-controller/src/messages/TurnOnOff.ts +++ /dev/null @@ -1,26 +0,0 @@ - -import { default as TurnOnOffPayloadSchema } from '#schemas/TurnOnOffPayload'; -export default class TurnOnOff { - - - turnOnOffPayload:TurnOnOffPayloadSchema; - - - constructor( - turnOnOffPayload: TurnOnOffPayloadSchema - ){ - - - this.turnOnOffPayload = turnOnOffPayload; - - } - - /** - * Parses a JSON string to an object of TurnOnOff message class. - * @param json any to be parsed as TurnOnOff. - */ - public static toMessage(json: any): TurnOnOff { - return JSON.parse(JSON.stringify(json)); - } - -} diff --git a/test/expected_comparators/latest/light-controller/src/messages/TurnOnOffResponse.ts b/test/expected_comparators/latest/light-controller/src/messages/TurnOnOffResponse.ts deleted file mode 100644 index ba0b02f5e..000000000 --- a/test/expected_comparators/latest/light-controller/src/messages/TurnOnOffResponse.ts +++ /dev/null @@ -1,26 +0,0 @@ - -import { default as ResponseSchema } from '#schemas/Response'; -export default class TurnOnOffResponse { - - - response:ResponseSchema; - - - constructor( - response: ResponseSchema - ){ - - - this.response = response; - - } - - /** - * Parses a JSON string to an object of TurnOnOffResponse message class. - * @param json any to be parsed as TurnOnOffResponse. - */ - public static toMessage(json: any): TurnOnOffResponse { - return JSON.parse(JSON.stringify(json)); - } - -} diff --git a/test/expected_comparators/latest/light-controller/src/schema/DimLightPayloadserere.ts b/test/expected_comparators/latest/light-controller/src/schema/DimLightPayloadserere.ts deleted file mode 100644 index 279439192..000000000 --- a/test/expected_comparators/latest/light-controller/src/schema/DimLightPayloadserere.ts +++ /dev/null @@ -1,19 +0,0 @@ - - - -export default class dimLightPayloadserere { - - - percentage?: Number - sentAt?: string - - - - constructor( - - ){ - - - - } -} diff --git a/test/expected_comparators/latest/light-controller/src/schema/LightMeasuredPayload.ts b/test/expected_comparators/latest/light-controller/src/schema/LightMeasuredPayload.ts deleted file mode 100644 index e090e2247..000000000 --- a/test/expected_comparators/latest/light-controller/src/schema/LightMeasuredPayload.ts +++ /dev/null @@ -1,19 +0,0 @@ - - - -export default class lightMeasuredPayload { - - - lumens?: Number - sentAt?: string - - - - constructor( - - ){ - - - - } -} diff --git a/test/expected_comparators/latest/light-controller/src/schema/Response.ts b/test/expected_comparators/latest/light-controller/src/schema/Response.ts deleted file mode 100644 index afc8c5d71..000000000 --- a/test/expected_comparators/latest/light-controller/src/schema/Response.ts +++ /dev/null @@ -1,21 +0,0 @@ - - - -export default class response { - - - status?: Number - statusMessage?: string - sentAt?: string - - - - constructor( - - ){ - - - - - } -} diff --git a/test/expected_comparators/latest/light-controller/src/schema/TurnOnOffPayload.ts b/test/expected_comparators/latest/light-controller/src/schema/TurnOnOffPayload.ts deleted file mode 100644 index f35e771e2..000000000 --- a/test/expected_comparators/latest/light-controller/src/schema/TurnOnOffPayload.ts +++ /dev/null @@ -1,19 +0,0 @@ - - - -export default class turnOnOffPayload { - - - command?: string - sentAt?: string - - - - constructor( - - ){ - - - - } -} diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/index.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/index.ts deleted file mode 100644 index bc69bdd47..000000000 --- a/test/expected_comparators/latest/light-controller/src/tests/testclient/index.ts +++ /dev/null @@ -1,257 +0,0 @@ - - -import { - Client, - NatsConnectionOptions, - connect, - Payload, - NatsError, - Subscription, - ServersChangedEvent, - SubEvent, - ServerInfo - } from 'ts-nats'; -import * as smartylightingStreetlights10EventChannel from "#testchannels/SmartylightingStreetlights10Event"; -import * as smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel from "#testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured"; -import * as smartylightingStreetlights10ActionStreetlightIdTurnOnChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn"; -import * as smartylightingStreetlights10ActionStreetlightIdTurnOffChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff"; -import * as smartylightingStreetlights10ActionStreetlightIdDimChannel from "#testchannels/SmartylightingStreetlights10ActionStreetlightIdDim"; -import {default as LightMeasuredMessage} from "#messages/LightMeasured"; -import {default as TurnOnOffMessage} from "#messages/TurnOnOff"; -import {default as TurnOnOffResponseMessage} from "#messages/TurnOnOffResponse"; -import {default as DimLightMessage} from "#messages/DimLight"; -import {default as DimLightResponseMessage} from "#messages/DimLightResponse"; -import {fromSeed} from 'ts-nkeys'; -import * as events from 'events'; -export enum AvailableEvents { - connectionError = 'connectionError', - permissionError = 'permissionError', - close = 'close', - connect = 'connect', - connecting = 'connecting', - disconnect = 'disconnect', - error = 'error', - pingcount = 'pingcount', - pingtimer = 'pingtimer', - reconnect = 'reconnect', - reconnecting = 'reconnecting', - serversChanged = 'serversChanged', - subscribe = 'subscribe', - unsubscribe = 'unsubscribe', - yield = 'yield' -} -export declare interface NatsAsyncApiTestClient { - on(event: AvailableEvents.connectionError, listener: (error: any) => void): this; - on(event: AvailableEvents.permissionError, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.close, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.connect, listener: (connection: Client, serverURL: string, info: ServerInfo) => void): this; - on(event: AvailableEvents.connecting, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.disconnect, listener: (serverURL: string) => void): this; - on(event: AvailableEvents.error, listener: (error: NatsError) => void): this; - on(event: AvailableEvents.pingcount, listener: () => void): this; - on(event: AvailableEvents.pingtimer, listener: () => void): this; - on(event: AvailableEvents.reconnect, listener: (connection: Client, serverURL: string, info: ServerInfo)=> void): this; - on(event: AvailableEvents.reconnecting, listener: (serverURL: string) => void): this; - on(event: AvailableEvents.serversChanged, listener: (e: ServersChangedEvent) => void): this; - on(event: AvailableEvents.subscribe, listener: (e: SubEvent) => void): this; - on(event: AvailableEvents.unsubscribe, listener: (e: SubEvent) => void): this; - on(event: AvailableEvents.yield, listener: () => void): this; -} -export class NatsAsyncApiTestClient extends events.EventEmitter{ - public jsonClient?: Client; - public stringClient?: Client; - public binaryClient?: Client; - public options?: NatsConnectionOptions; - - /** - * - * @param options options to use, payload is omitted if sat in the AsyncAPI document. - */ - constructor() { - super(); - } - - /** - * Try to connect to the NATS server with the different payloads. - */ - async connect(options : NatsConnectionOptions){ - this.options = this.setDefaultOptions(options); - try{ - this.options.payload = Payload.JSON; - this.jsonClient = await connect(this.options); - this.chainEvents(this.jsonClient); - }catch(e){ - this.emit(AvailableEvents.connectionError, e) - } - } - - - /** - * Disconnect all clients from the server - */ - async disconnect(){ - this.jsonClient!.close() - } - - private chainEvents(ns: Client){ - ns.on('permissionError', (e: NatsError) => { - this.emit(AvailableEvents.permissionError, e) - }); - ns.on('close', (e: NatsError) => { - this.emit(AvailableEvents.close, e) - }); - ns.on('connect', (connection: Client, serverURL: string, info: ServerInfo) => { - this.emit(AvailableEvents.connect, connection, serverURL, info) - }); - ns.on('connecting', (serverURL: NatsError) => { - this.emit(AvailableEvents.connecting, serverURL) - }); - ns.on('disconnect', (serverURL: string) => { - this.emit(AvailableEvents.disconnect, serverURL) - }); - ns.on('error', (e: NatsError) => { - this.emit(AvailableEvents.error, e) - }); - ns.on('pingcount', () => { - this.emit(AvailableEvents.pingcount) - }); - ns.on('pingtimer', () => { - this.emit(AvailableEvents.pingtimer) - }); - ns.on('reconnect', (connection: Client, serverURL: string, info: ServerInfo) => { - this.emit(AvailableEvents.reconnect, connection, serverURL, info) - }); - ns.on('reconnecting', (serverURL: string) => { - this.emit(AvailableEvents.reconnecting, serverURL) - }); - ns.on('serversChanged', (e: ServersChangedEvent) => { - this.emit(AvailableEvents.serversChanged, e) - }); - ns.on('subscribe', (e: SubEvent) => { - this.emit(AvailableEvents.subscribe, e) - }); - ns.on('unsubscribe', (e: SubEvent) => { - this.emit(AvailableEvents.unsubscribe, e) - }); - ns.on('yield', () => { - this.emit(AvailableEvents.yield) - }); - } - /** - * Try to connect to the NATS server with nkey authentication - */ - async connectWithNkey(options : NatsConnectionOptions, publicNkey: string, seed: string){ - options.nkey = publicNkey; - options.nonceSigner = (nonce: string): Buffer => { - const sk = fromSeed(Buffer.from(seed)); - return sk.sign(Buffer.from(nonce)); - } - await this.connect(options); - } - /** - * Set the default options based on the AsyncAPI file. - * @param options to set - */ - private setDefaultOptions(options: NatsConnectionOptions){ - //If server binding options sat set the options - options.encoding = 'utf8'; - return options; - } - - - - /** - * Topic for which one can subscribe to all measurements regardless of id. - * @param onDataCallback Called when message recieved. - */ - public subscribeToSmartylightingStreetlights10Event(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage) => void ): Promise { - const nc: Client = this.jsonClient!; - if(nc){ - return smartylightingStreetlights10EventChannel.subscribe(onDataCallback, nc - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10Event')) - } - } - - - /** - * Topic for which one can subscribe to measurements on a specific streetlightId. - * @param onDataCallback Called when message recieved. - */ - public subscribeToSmartylightingStreetlights10EventStreetlightIdLightingMeasured(onDataCallback : (err?: NatsError, msg?: LightMeasuredMessage, streetlightId?: string) => void - ,streetlightId: string - ): Promise { - const nc: Client = this.jsonClient!; - if(nc){ - return smartylightingStreetlights10EventStreetlightIdLightingMeasuredChannel.subscribe(onDataCallback, nc - - ,streetlightId - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10EventStreetlightIdLightingMeasured')) - } - } - - - /** - * - * @param requestMessage The request message to send. - */ - public requestSmartylightingStreetlights10ActionStreetlightIdTurnOn(requestMessage: TurnOnOffMessage - - ,streetlightId: string - ): Promise { - const nc: Client = this.jsonClient!; - if(nc){ - return smartylightingStreetlights10ActionStreetlightIdTurnOnChannel.request(requestMessage, nc - - ,streetlightId - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdTurnOn')) - } - } - - - /** - * - * @param requestMessage The request message to send. - */ - public requestSmartylightingStreetlights10ActionStreetlightIdTurnOff(requestMessage: TurnOnOffMessage - - ,streetlightId: string - ): Promise { - const nc: Client = this.jsonClient!; - if(nc){ - return smartylightingStreetlights10ActionStreetlightIdTurnOffChannel.request(requestMessage, nc - - ,streetlightId - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdTurnOff')) - } - } - - - /** - * - * @param requestMessage The request message to send. - */ - public requestSmartylightingStreetlights10ActionStreetlightIdDim(requestMessage: DimLightMessage - - ,streetlightId: string - ): Promise { - const nc: Client = this.jsonClient!; - if(nc){ - return smartylightingStreetlights10ActionStreetlightIdDimChannel.request(requestMessage, nc - - ,streetlightId - ); - }else{ - return Promise.reject(new Error('Nats client is not connected, could not send message on channel smartylightingStreetlights10ActionStreetlightIdDim')) - } - } - - -} \ No newline at end of file diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdDim.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdDim.ts deleted file mode 100644 index 002a5d646..000000000 --- a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdDim.ts +++ /dev/null @@ -1,70 +0,0 @@ - -import {default as DimLightMessage} from '#messages/DimLight' -import {default as DimLightResponseMessage} from '#messages/DimLightResponse' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - -export function reply( - onRequest: (err?: NatsError, msg?: DimLightMessage, streetlightId?: string) =>Promise, - onReplyError: (err: NatsError) => void, - nc: Client, - - streetlightId: string - - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(`smartylighting.streetlights.1.0.action.${streetlightId}.dim`,async (err, msg) => { - if (err) { - onRequest(err); - } else { - const unmodifiedChannel = `smartylighting.streetlights.1.0.action.{streetlightId}.dim` - const receivedTopicParameters = { - streetlightId : msg.subject.slice(unmodifiedChannel.split("${streetlightId}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlightId}")[1].length) - } - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived : any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - let requestData = DimLightMessage.toMessage(processedDataReceived); - let responseObject =await onRequest(undefined, requestData, - receivedTopicParameters['streetlightId']); - if (msg.reply) { - try { - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var dataToPublish : any = responseObject; - for(let hook of publishDataHooks){ - dataToPublish = hook(dataToPublish); - } - nc.publish(msg.reply, dataToPublish); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts deleted file mode 100644 index 72032ae2b..000000000 --- a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOff.ts +++ /dev/null @@ -1,70 +0,0 @@ - -import {default as TurnOnOffMessage} from '#messages/TurnOnOff' -import {default as TurnOnOffResponseMessage} from '#messages/TurnOnOffResponse' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - -export function reply( - onRequest: (err?: NatsError, msg?: TurnOnOffMessage, streetlightId?: string) =>Promise, - onReplyError: (err: NatsError) => void, - nc: Client, - - streetlightId: string - - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(`smartylighting.streetlights.1.0.action.${streetlightId}.turn.off`,async (err, msg) => { - if (err) { - onRequest(err); - } else { - const unmodifiedChannel = `smartylighting.streetlights.1.0.action.{streetlightId}.turn.off` - const receivedTopicParameters = { - streetlightId : msg.subject.slice(unmodifiedChannel.split("${streetlightId}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlightId}")[1].length) - } - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived : any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - let requestData = TurnOnOffMessage.toMessage(processedDataReceived); - let responseObject =await onRequest(undefined, requestData, - receivedTopicParameters['streetlightId']); - if (msg.reply) { - try { - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var dataToPublish : any = responseObject; - for(let hook of publishDataHooks){ - dataToPublish = hook(dataToPublish); - } - nc.publish(msg.reply, dataToPublish); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts deleted file mode 100644 index dc3224e15..000000000 --- a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10ActionStreetlightIdTurnOn.ts +++ /dev/null @@ -1,70 +0,0 @@ - -import {default as TurnOnOffMessage} from '#messages/TurnOnOff' -import {default as TurnOnOffResponseMessage} from '#messages/TurnOnOffResponse' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - -export function reply( - onRequest: (err?: NatsError, msg?: TurnOnOffMessage, streetlightId?: string) =>Promise, - onReplyError: (err: NatsError) => void, - nc: Client, - - streetlightId: string - - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try { - let subscribeOptions: SubscriptionOptions = {}; - - let subscription = nc.subscribe(`smartylighting.streetlights.1.0.action.${streetlightId}.turn.on`,async (err, msg) => { - if (err) { - onRequest(err); - } else { - const unmodifiedChannel = `smartylighting.streetlights.1.0.action.{streetlightId}.turn.on` - const receivedTopicParameters = { - streetlightId : msg.subject.slice(unmodifiedChannel.split("${streetlightId}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlightId}")[1].length) - } - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived : any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - let requestData = TurnOnOffMessage.toMessage(processedDataReceived); - let responseObject =await onRequest(undefined, requestData, - receivedTopicParameters['streetlightId']); - if (msg.reply) { - try { - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var dataToPublish : any = responseObject; - for(let hook of publishDataHooks){ - dataToPublish = hook(dataToPublish); - } - nc.publish(msg.reply, dataToPublish); - } catch (e) { - if (onReplyError) { - onReplyError(e) - } else { - console.error(e) - } - } - } else { - let error = new NatsError('Expected request to need a reply, did not..', '000'); - if (onReplyError) { - onReplyError(error) - } else { - } - } - } - }, subscribeOptions); - resolve(subscription); - } catch (e) { - reject(e); - } - } else { - reject(new Error("Nats client is not connected")); - } - }) -} - - diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10Event.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10Event.ts deleted file mode 100644 index e65ed585c..000000000 --- a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10Event.ts +++ /dev/null @@ -1,30 +0,0 @@ - -import {default as LightMeasuredMessage} from '#messages/LightMeasured' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - - -export function publish( - requestMessage: LightMeasuredMessage, - nc: Client, - - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var dataToPublish : any = requestMessage; - for(let hook of publishDataHooks){ - dataToPublish = hook(dataToPublish); - } - nc.publish(`smartylighting.streetlights.1.0.event.*`, dataToPublish); - resolve(); - }catch(e){ - reject(e); - } - }else{ - reject(new Error("Nats client is not connected")); - } - }); -}; - diff --git a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts b/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts deleted file mode 100644 index f22b47c33..000000000 --- a/test/expected_comparators/latest/light-controller/src/tests/testclient/testchannels/SmartylightingStreetlights10EventStreetlightIdLightingMeasured.ts +++ /dev/null @@ -1,32 +0,0 @@ - -import {default as LightMeasuredMessage} from '#messages/LightMeasured' -import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; -import { Hooks } from '#hooks'; - - -export function publish( - requestMessage: LightMeasuredMessage, - nc: Client, - - streetlightId: string - - ): Promise { - return new Promise(async (resolve, reject) => { - if (nc) { - try{ - let publishDataHooks = Hooks.getInstance().getBeforeSendingDataHook(); - var dataToPublish : any = requestMessage; - for(let hook of publishDataHooks){ - dataToPublish = hook(dataToPublish); - } - nc.publish(`smartylighting.streetlights.1.0.event.${streetlightId}.lighting.measured`, dataToPublish); - resolve(); - }catch(e){ - reject(e); - } - }else{ - reject(new Error("Nats client is not connected")); - } - }); -}; - diff --git a/test/expected_comparators/latest/light-controller/tsconfig.json b/test/expected_comparators/latest/light-controller/tsconfig.json deleted file mode 100644 index b1d6a9fac..000000000 --- a/test/expected_comparators/latest/light-controller/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "declaration": true, - "strict": true, - "noImplicitAny": true, - "removeComments": true, - "preserveConstEnums": true, - "sourceMap": true, - "outDir": "dist/", - "baseUrl": "./src", - "paths": { - "#messages/*": ["messages/*"], - "#schemas/*": ["schema/*"], - "#channels/*": ["channels/*"], - "#testchannels/*": ["tests/testclient/testchannels/*"], - "#hooks": ["hooks"], - "#testclient": ["tests/testclient/index"], - "#client": ["index"] - } - }, - "include": ["src"], - "exclude": ["node_modules", "**/*.spec.ts"] -} diff --git a/test/template.js b/test/template.js deleted file mode 100644 index 668925374..000000000 --- a/test/template.js +++ /dev/null @@ -1,26 +0,0 @@ -const dircompare = require('dir-compare'); -const path = require('path'); -const expect = require('chai').expect; -describe('template', () => { - describe('should be usable with latest generator', () => { - describe('and should support 0.1.0 bindings', () => { - it('for frontend', () => { - const path1 = path.resolve('./test/actual_comparators/latest/frontend'); - const path2 = path.resolve('./test/expected_comparators/latest/frontend'); - const res = compareDir(path1, path2); - expect(res.same).to.be.true; - }); - it('for light-controller', () => { - const path1 = path.resolve('./test/actual_comparators/latest/light-controller'); - const path2 = path.resolve('./test/expected_comparators/latest/light-controller'); - const res = compareDir(path1, path2); - expect(res.same).to.be.true; - }); - }); - }); -}); - -function compareDir(path1, path2){ - const options = { compareSize: true }; - return dircompare.compareSync(path1, path2, options); -} \ No newline at end of file From 5275ed5a94893134647450ca2ef4d4bbd57b954c Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 23 Jul 2020 04:01:37 +0200 Subject: [PATCH 069/110] Fixed event emitter types from the internal ts-nats library are not exported. --- template/src/index.ts.njk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index f64a641f8..f62eef4dd 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -25,7 +25,7 @@ import { SubEvent, ServerInfo } from 'ts-nats'; - +export {Client, ServerInfo, ServersChangedEvent, SubEvent} {%- for channelName, message in asyncapi.channels() %} import * as {{ channelName | camelCase }}Channel from "./channels/{{ channelName | pascalCase | firstUpperCase }}"; export {% raw %}{{% endraw %}{{ channelName | camelCase }}Channel}; From 7d1e65e6ebf9df33ec3cda908b9bcc17d2c7ca06 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 23 Jul 2020 04:05:08 +0200 Subject: [PATCH 070/110] Updated README.md --- README.md | 211 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 170 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 4090d156f..d72224f7f 100644 --- a/README.md +++ b/README.md @@ -3,28 +3,40 @@ This is a TypeScript/Node.js NATS template for the AsyncAPI generator.

-The template is based on the [nats-ts](https://github.com/nats-io/nats.ts) library and can be used as both a TypeScript and Node.js library. +This template is for generating a TypeScript/Node.js NATS client based on an AsyncAPI document. The template is based on the [nats-ts](https://github.com/nats-io/nats.ts) library and can be used as both a TypeScript and Node.js library. Example generations can be found under [examples](./examples) which includes [publish and subscribe](./examples/publish%20subscribe) example as well as [request and reply](./examples/request%20reply). +# How to use ## Requirements * @asyncapi/generator v1.0.0 Install the generator through [npm or run it from docker official installer](https://github.com/asyncapi/generator#install). ## Example usage -The leading examples are both in TypeScript and in Node.js since this template can be used for both. The example code will be used later in the documentation for to explain the different features. +The leading examples are both in TypeScript and in Node.js since this template can be used for both. The example code will be used later in the documentation for to explain the different features. -### TypeScript - - -### Node.js Given any AsyncAPI file (`AsyncAPI.yml`) first generate the client with the [AsyncAPI generator](https://github.com/asyncapi/generator) such as - ```bash ag --install --output ./nats-client ./AsyncAPI.yml @asyncapi/ts-nats-template --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" ``` -Afterwards `cd` into the generated folder `nats-client` and run the commands `npm i` and `npm run build`. The generated NATS client is now ready to be used. To use the generated code either create a client wrapper such as the following file: +Afterwards `cd` into the generated folder `nats-client` and run the commands `npm i` and `npm run build`. The generated NATS client is now ready to be used in either TypeScript or Node.js. + +### TypeScript + +```js +import * as GeneratedClient from "./nats-client"; +const natsClient = new GeneratedClient.NatsAsyncApiClient(); +async function connect(){ + try{ + await natsClient.connect({url: "nats://demo.nats.io:4222", reconnectTimeWait: 1000, reconnect: true, maxReconnectAttempts: -1}); + }catch(e){ + console.log(e); + } +} +connect(); +``` +### Node.js ```js const GeneratedClient = require("./nats-client"); const natsClient = new GeneratedClient.NatsAsyncApiClient(); @@ -36,50 +48,159 @@ async function connect(){ } } connect(); -module.exports = natsClient ``` or use it directly where needed. -## Features +# Features * Supports wildcard channels. AsyncAPI describes the channel path to be defined as [RFC 6570 URI](https://www.asyncapi.com/docs/specifications/2.0.0/#a-name-channelsobject-a-channels-object). So a channel containing a wildcard needs to be defined as `smartylighting/streetlights/*`. This also works with parameters such as `smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured`, ensure to define the type of the parameter as a String if you want to use wildcards. * Supports [test/mirror client](###test-client) for testing or other useful scenarios. -* This template can be used as a javascript library as well since the generated code works directly in node-js. Has not been tested as a pure javascript library. +* This template can be used as a javascript library as well since the generated code works directly in Node.js. + -## Available events -[All the events from nats-ts](https://github.com/nats-io/nats.ts#notifications) library are supported. -### TypeScript example +# Available events +The generated client can emit multiple events, all of these are directly from the [nats-ts](https://github.com/nats-io/nats.ts#notifications) library. Where the errors are wrapped in a custom `NatsTypescriptTemplateError` type. -### Node.js example +## TypeScript example ```js -const GeneratedClient = require("./nats-client"); -const natsClient = new GeneratedClient.NatsAsyncApiClient(); +import {AvailableEvents, NatsAsyncApiClient, NatsTypescriptTemplateError, Client, ServerInfo, ServersChangedEvent, SubEvent} from "nats-client"; +const natsClient = new NatsAsyncApiClient(); -//Listen for the permissionError event from the nats-ts library -natsClient.on(Nats.AvailableEvents.permissionError, (e) => { - console.log("permissionError"); +natsClient.on(AvailableEvents.permissionError, (e: NatsTypescriptTemplateError) => { + console.log("NatsAsyncApiClient permissionError"); + console.log(e); +}); +natsClient.on(AvailableEvents.close, (e: NatsTypescriptTemplateError) => { + console.log("NatsAsyncApiClient close"); + console.log(e); +}); +natsClient.on(AvailableEvents.connect, (connection: Client, serverURL: string, info: ServerInfo) => { + console.log("NatsAsyncApiTestClient connect"); + console.log({connection, serverURL, info}); +}); +natsClient.on(AvailableEvents.connecting, (serverURL: string) => { + console.log("NatsAsyncApiClient connecting"); + console.log(serverURL); +}); +natsClient.on(AvailableEvents.disconnect, (serverURL: string) => { + console.log("NatsAsyncApiClient disconnect"); + console.log(serverURL); +}); +natsClient.on(AvailableEvents.error, (e: NatsTypescriptTemplateError) => { + console.log("NatsAsyncApiClient error"); + console.log(e); +}); +natsClient.on(AvailableEvents.pingcount, () => { + console.log("NatsAsyncApiClient pingcount"); +}); +natsClient.on(AvailableEvents.pingtimer, () => { + console.log("NatsAsyncApiClient pingtimer"); +}); +natsClient.on(AvailableEvents.reconnect, (connection: Client, serverURL: string, info: ServerInfo) => { + console.log("NatsAsyncApiClient reconnect"); + console.log({connection, serverURL, info}); +}); +natsClient.on(AvailableEvents.reconnecting, (serverURL: string) => { + console.log("NatsAsyncApiClient reconnecting"); + console.log(serverURL); +}); +natsClient.on(AvailableEvents.serversChanged, (e: ServersChangedEvent) => { + console.log("NatsAsyncApiClient serversChanged"); + console.log(e); +}); +natsClient.on(AvailableEvents.subscribe, (e: SubEvent) => { + console.log("NatsAsyncApiClient subscribe"); console.log(e); }); +natsClient.on(AvailableEvents.unsubscribe, (e: SubEvent) => { + console.log("NatsAsyncApiClient unsubscribe"); + console.log(e); +}); +natsClient.on(AvailableEvents.yield, () => { + console.log("NatsAsyncApiClient yield"); +}); +``` +## Node.js example +```js +const {AvailableEvents, NatsAsyncApiClient} = require("nats-client"); +const natsClient = new NatsAsyncApiClient(); +natsClient.on(AvailableEvents.permissionError, (e) => { + console.log("NatsAsyncApiClient permissionError"); + console.log(e); +}); +natsClient.on(AvailableEvents.close, (e) => { + console.log("NatsAsyncApiClient close"); + console.log(e); +}); +natsTestClient.on(AvailableEvents.connect, async (connection, serverURL, info) => { + console.log("NatsAsyncApiTestClient connect"); + console.log({connection, serverURL, info}); +}); +natsClient.on(AvailableEvents.connect, (connection, serverURL, info) => { + console.log("NatsAsyncApiClient connect"); + console.log({connection, serverURL, info}); +}); +natsClient.on(AvailableEvents.connecting, (serverURL) => { + console.log("NatsAsyncApiClient connecting"); + console.log(serverURL); +}); +natsClient.on(AvailableEvents.disconnect, (serverURL) => { + console.log("NatsAsyncApiClient disconnect"); + console.log(serverURL); +}); +natsClient.on(AvailableEvents.error, (e) => { + console.log("NatsAsyncApiClient error"); + console.log(e); +}); +natsClient.on(AvailableEvents.pingcount, () => { + console.log("NatsAsyncApiClient pingcount"); +}); +natsClient.on(AvailableEvents.pingtimer, () => { + console.log("NatsAsyncApiClient pingtimer"); +}); +natsClient.on(AvailableEvents.reconnect, (connection, serverURL, info) => { + console.log("NatsAsyncApiClient reconnect"); + console.log({connection, serverURL, info}); +}); +natsClient.on(AvailableEvents.reconnecting, (serverURL) => { + console.log("NatsAsyncApiClient reconnecting"); + console.log(serverURL); +}); +natsClient.on(AvailableEvents.serversChanged, (e) => { + console.log("NatsAsyncApiClient serversChanged"); + console.log(e); +}); +natsClient.on(AvailableEvents.subscribe, (e) => { + console.log("NatsAsyncApiClient subscribe"); + console.log(e); +}); +natsClient.on(AvailableEvents.unsubscribe, (e) => { + console.log("NatsAsyncApiClient unsubscribe"); + console.log(e); +}); +natsClient.on(AvailableEvents.yield, () => { + console.log("NatsAsyncApiClient yield"); +}); ``` -## Available Parameters +# Template Parameters These are the available template parameters: |Parameter|Type|Description| |---|---|---| | generateTestClient | Boolean | Use this parameter to generate the [test client](###test-client). Add the following to the CLI when generating your code `--param "generateTestClient=true"` | promisifyReplyCallback | Boolean | Use this parameter to change from the default regular callback when using the request operation. Add the following to the CLI when generating your code `--param "promisifyReplyCallback=true"` -## Test Client -The test client is like a mirror client. It does everything the opposite, when you define a subscription operation it will generate a subscription operation in the test client. This is opposite to what the specification dictates. This client can be used to create integration tests or other useful scenarios. +# Test Client +The test client is like a mirror client. It does everything the opposite, when you define a subscription operation it will generate a subscription operation in the test client. This is opposite to what the specification dictates. This client can be used to create integration tests or other useful scenarios. -## Supported Content Types +# Supported Content Types The following payload types are supported, this is limited to the underlying NATS TypeScript library: * For binary payloads use: `binary` content type * For json payloads use: `json` content type * For string payloads use: `string` content type -## Client Hooks +# Client Hooks The generated client support custom hooks used to control the flow of information outside the generated code. The hooks can be used to alter the payload before sending or after recieving any data i.e. encrypt, compress data, etc. It is possible to register as many hooks as you want, however remember that after the first call subsequently calls will include the already changed data and not the original. Also when using these hooks you are responsible for complying with the content type for the message being changed. @@ -87,21 +208,29 @@ These are the available hooks: |Hookname|Callback type|Description| |---|---|---| | BeforeSendingData | (messageToSend: any) => any | Called before sending any data. -| RecievedData | (receivedData: any) => any | Called after data is recieved. - -### TypeScript example -```ts -import {Hooks, BeforeSendingDataHook} from './nats-client/hooks' -Hooks.getInstance().registerBeforeSendingData((messageToSend: any) => { - return "AlwaysThis"; -}); -``` - -### Node.js example - - - - +| RecievedData | (receivedData: any) => any | Hook is called after data is recieved before the client tries to peace the message back together. +## Node.js example +This example uses the msgpack library to encode and decode the message before sending and receiving data. +```js +const {AvailableEvents, NatsAsyncApiClient, Hooks} = require("nats-client"); +const natsClient = new NatsAsyncApiClient(); +const msgpack = require("msgpack-lite"); +function encode(msg){ + console.log("encode"); + console.log(msg); + // encode from JS Object to MessagePack (Buffer) + return msgpack.encode(msg); +} +function decode(msg){ + // decode from MessagePack (Buffer) to JS Object + console.log("Decoding"); + console.log(msg); + return msgpack.decode(msg.data); // => {"foo": "bar"} +} +Hooks.getInstance().registerBeforeSendingData(encode); +Hooks.getInstance().registerRecievedData(decode); +``` -CANNOT HAVE EMPTY OBJECTS use null instead \ No newline at end of file +# Restrictions +* Empty objects are not supported, use `null` types as work around. From 730403b2ea918b13eff0cf8f73b639de902df023 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 23 Jul 2020 04:15:02 +0200 Subject: [PATCH 071/110] Fixed Subscribe couldn't find channel parameter. --- partials/channel/Subscribe.njk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/partials/channel/Subscribe.njk b/partials/channel/Subscribe.njk index e4ae946e0..8ec7b6c10 100644 --- a/partials/channel/Subscribe.njk +++ b/partials/channel/Subscribe.njk @@ -30,7 +30,7 @@ export function subscribe( const receivedTopicParameters = { {%- set counter = 1 %} {%- for parameterName, parameter in channelParameters %} - {{parameterName}} : msg.subject.slice(unmodifiedChannel.split("${{'{'+ parameterName+ '}'}}")[0].length, msg.subject.length-unmodifiedChannel.split("${{'{'+parameterName+'}'}}")[1].length){%- if counter < (channelParameters | length) %},{%- endif %} + {{parameterName}} : msg.subject.slice(unmodifiedChannel.split("{{'{'+ parameterName+ '}'}}")[0].length, msg.subject.length-unmodifiedChannel.split("{{'{'+parameterName+'}'}}")[1].length){%- if counter < (channelParameters | length) %},{%- endif %} {%- set counter = counter+1 %} {%- endfor %} } From 74a69893785dabbcfd6462087f00cf1c165ba549 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 23 Jul 2020 04:29:57 +0200 Subject: [PATCH 072/110] Updated README.md --- README.md | 2 ++ examples/publish subscribe/README.md | 11 +++++++++++ examples/request reply/README.md | 16 ++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/README.md b/README.md index d72224f7f..844820c79 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,8 @@ or use it directly where needed. * Supports [test/mirror client](###test-client) for testing or other useful scenarios. * This template can be used as a javascript library as well since the generated code works directly in Node.js. +# Connection options +Currently the generated client offers 4 standard methods of connecting to your NATS server `connectWithUserCreds`, `connectWithUserPass`, `connectToHost` and `connectWithNkey`. If you need something customized use the standard `connect` method with your custom options. Currently the template does not care which security details you have defined in your AsyncAPI document. # Available events The generated client can emit multiple events, all of these are directly from the [nats-ts](https://github.com/nats-io/nats.ts#notifications) library. Where the errors are wrapped in a custom `NatsTypescriptTemplateError` type. diff --git a/examples/publish subscribe/README.md b/examples/publish subscribe/README.md index e69de29bb..fd48154d5 100644 --- a/examples/publish subscribe/README.md +++ b/examples/publish subscribe/README.md @@ -0,0 +1,11 @@ +

Streetlight example

+

+ Publish and subscribe +

+ +## Channels +This example contains two channels are: + +`streetlight/{streetlight_id}/command/turnon` which are for subscribing to the command `turnon`. The generated client interprets this as the NATS topic `streetlight.{streetlight_id}.command.turnon`. The `{streetlight_id}` is the channel parameter which are not realized before actually subscribing to anything. When a message is recieved on channel `streetlight.1.command.turnon` it can automatically interpret what the `streetlight_id` parameter is. + +`streetlight/{streetlight_id}/event/turnon` which are for publishing when the light is acutally turned on. diff --git a/examples/request reply/README.md b/examples/request reply/README.md index e69de29bb..b6b989405 100644 --- a/examples/request reply/README.md +++ b/examples/request reply/README.md @@ -0,0 +1,16 @@ +

Streetlight example

+

+ Request and reply +

+ +This example contains two channels are: + +`streetlight/{streetlight_id}/command/turnon` which are for replying to the command `turnon`. The generated client interprets this as the NATS topic `streetlight.{streetlight_id}.command.turnon`. The `{streetlight_id}` is the channel parameter which are not realized before actually subscribing to anything. When a message is recieved on channel `streetlight.1.command.turnon` it can automatically interpret what the `streetlight_id` parameter is. + +`streetlight/{streetlight_id}/event/turnon` which are for requesting another application when the light is acutally turned on. + + + +One very important thing to keep in mind here when looking at the streetlight [AsyncAPI document](./streetlight.json) you might notice that the publish and subscribe operations look weird and reversed. If not, great skip the following explaination. The request/reply pattern uses the existing publish and subscribe operations to define what is replied and what is requested. This is determined by the NATS bindings provided by the AsyncAPI spec. As observed for the channel `streetlight/{streetlight_id}/command/turnon` its bindings are defined as being a `replier`. This means that the publish operation are used to describe what is being published to the application and the subscribe operation describes the corresponding reply. + +For the request channel `streetlight/{streetlight_id}/event/turnon` it has the binding `requester` which means that the publish operation are used to describe what is being published to it and the subscribe operation are used to describe what the request the application are to send. \ No newline at end of file From a288b9d80359ad0db0e3f619712919b2730b9460 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 23 Jul 2020 04:30:08 +0200 Subject: [PATCH 073/110] Updated README.md --- examples/publish subscribe/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/publish subscribe/README.md b/examples/publish subscribe/README.md index fd48154d5..a3abb6b46 100644 --- a/examples/publish subscribe/README.md +++ b/examples/publish subscribe/README.md @@ -3,7 +3,6 @@ Publish and subscribe

-## Channels This example contains two channels are: `streetlight/{streetlight_id}/command/turnon` which are for subscribing to the command `turnon`. The generated client interprets this as the NATS topic `streetlight.{streetlight_id}.command.turnon`. The `{streetlight_id}` is the channel parameter which are not realized before actually subscribing to anything. When a message is recieved on channel `streetlight.1.command.turnon` it can automatically interpret what the `streetlight_id` parameter is. From 5536c31b3c0835f8ddfd61142aa9198c342bf779 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 23 Jul 2020 04:30:53 +0200 Subject: [PATCH 074/110] Removed unused scripts --- scripts/generate_new_actual_comparators.sh | 36 -------------------- scripts/generate_new_expected_comparators.sh | 33 ------------------ 2 files changed, 69 deletions(-) delete mode 100644 scripts/generate_new_actual_comparators.sh delete mode 100644 scripts/generate_new_expected_comparators.sh diff --git a/scripts/generate_new_actual_comparators.sh b/scripts/generate_new_actual_comparators.sh deleted file mode 100644 index aa8b125af..000000000 --- a/scripts/generate_new_actual_comparators.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash -set -x -unameOut="$(uname -s)" -case "${unameOut}" in - Linux*) machine="Linux";; - Darwin*) machine="Mac";; - CYGWIN*) machine="Cygwin";; - MINGW*) machine="MinGw";; - *) machine="UNKNOWN:${unameOut}" -esac -currentDir=${PWD} -echo ${machine} -if [ $machine == "MinGw" ]; then - # Convert /c/ to C:/ - currentDir="${currentDir:1:1}:" - currentDir="${currentDir^}" - currentDir="${currentDir}${PWD:2}" -fi -mkdir ${currentDir}/test/actual_comparators/latest/frontend -mkdir ${currentDir}/test/actual_comparators/latest/light-controller - - -docker run --rm -it \ - -v ${currentDir}/test/docs/0.1.0/frontend.yml:/app/asyncapi.yml \ - -v ${currentDir}/test/docs/0.1.0/components:/app/components \ - -v ${currentDir}/test/actual_comparators/latest/frontend:/app/output \ - -v ${currentDir}:/app/template \ - asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --install --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" - -docker run --rm -it \ - -v ${currentDir}/test/docs/0.1.0/light-controller.yml:/app/asyncapi.yml \ - -v ${currentDir}/test/docs/0.1.0/components:/app/components \ - -v ${currentDir}/test/actual_comparators/latest/light-controller:/app/output \ - -v ${currentDir}:/app/template \ - asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --install --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" - diff --git a/scripts/generate_new_expected_comparators.sh b/scripts/generate_new_expected_comparators.sh deleted file mode 100644 index 6fd145902..000000000 --- a/scripts/generate_new_expected_comparators.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash -set -x -unameOut="$(uname -s)" -case "${unameOut}" in - Linux*) machine="Linux";; - Darwin*) machine="Mac";; - CYGWIN*) machine="Cygwin";; - MINGW*) machine="MinGw";; - *) machine="UNKNOWN:${unameOut}" -esac -currentDir=${PWD} -echo ${machine} -if [ $machine == "MinGw" ]; then - # Convert /c/ to C:/ - currentDir="${currentDir:1:1}:" - currentDir="${currentDir^}" - currentDir="${currentDir}${PWD:2}" -fi - -docker run --rm -it \ - -v ${currentDir}/test/docs/0.1.0/frontend.yml:/app/asyncapi.yml \ - -v ${currentDir}/test/docs/0.1.0/components:/app/components \ - -v ${currentDir}/test/expected_comparators/latest/frontend:/app/output \ - -v ${currentDir}:/app/template \ - asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --install --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" - -docker run --rm -it \ - -v ${currentDir}/test/docs/0.1.0/light-controller.yml:/app/asyncapi.yml \ - -v ${currentDir}/test/docs/0.1.0/components:/app/components \ - -v ${currentDir}/test/expected_comparators/latest/light-controller:/app/output \ - -v ${currentDir}:/app/template \ - asyncapi/generator:latest -o ./output ./asyncapi.yml ./template --install --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" - From 5f767b89564fce713f9afabf1a07140488f7ca1f Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 23 Jul 2020 04:36:39 +0200 Subject: [PATCH 075/110] Updated README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 844820c79..9ef321f71 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ or use it directly where needed. * Supports wildcard channels. AsyncAPI describes the channel path to be defined as [RFC 6570 URI](https://www.asyncapi.com/docs/specifications/2.0.0/#a-name-channelsobject-a-channels-object). So a channel containing a wildcard needs to be defined as `smartylighting/streetlights/*`. This also works with parameters such as `smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured`, ensure to define the type of the parameter as a String if you want to use wildcards. * Supports [test/mirror client](###test-client) for testing or other useful scenarios. * This template can be used as a javascript library as well since the generated code works directly in Node.js. +* This template uses [quicktype](https://quicktype.io/) to generate the corresponding message payloads. # Connection options Currently the generated client offers 4 standard methods of connecting to your NATS server `connectWithUserCreds`, `connectWithUserPass`, `connectToHost` and `connectWithNkey`. If you need something customized use the standard `connect` method with your custom options. Currently the template does not care which security details you have defined in your AsyncAPI document. @@ -236,3 +237,4 @@ Hooks.getInstance().registerRecievedData(decode); # Restrictions * Empty objects are not supported, use `null` types as work around. +* This template has not been tested with different specs other then JSON Schema draft 7. From 644220b2918f100dbcfa418d42c4118ba49c32ed Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 23 Jul 2020 04:38:15 +0200 Subject: [PATCH 076/110] Removed test dependencies. --- package-lock.json | 962 ---------------------------------------------- package.json | 8 +- 2 files changed, 1 insertion(+), 969 deletions(-) diff --git a/package-lock.json b/package-lock.json index aa1e8e788..5ecfdd256 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,37 +28,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==" }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -67,43 +36,6 @@ "sprintf-js": "~1.0.2" } }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, "brfs": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/brfs/-/brfs-1.6.1.tgz", @@ -120,158 +52,16 @@ "resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-1.3.0.tgz", "integrity": "sha512-0F2z/VSnLbmEeBcUrSuDH5l0HxTXdQQzLjkmBR4cYfvg1zJrKSlmIZFqyFR8oX0NrwPhy3c3HQ6i3OxMbew4Tg==" }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", - "dev": true - }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, "collection-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collection-utils/-/collection-utils-1.0.1.tgz", "integrity": "sha512-LA2YTIlR7biSpXkKYwwuzGjwL5rjWEZVOSnvdUc7gObvWe4WkjxOpfrdhoP7Hs09YWDVfg0Mal9BpAqLfVEzQg==" }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, "concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", @@ -296,82 +86,11 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "dir-compare": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-2.2.0.tgz", - "integrity": "sha512-cmOgS23lSolrsdrDSwWdu/USalfXEwQ/4r3MyIur2U/td2pIp8TnO71ME4M8siaE49xg43tIVX3XzriDOgfdow==", - "dev": true, - "requires": { - "buffer-equal": "1.0.0", - "colors": "1.0.3", - "commander": "2.9.0", - "minimatch": "3.0.2" - }, - "dependencies": { - "commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "dev": true, - "requires": { - "graceful-readlink": ">= 1.0.0" - } - }, - "minimatch": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz", - "integrity": "sha1-DzmKcwDqRB6cNIyD2Yq4ydv5xAo=", - "dev": true, - "requires": { - "brace-expansion": "^1.0.0" - } - } - } - }, "duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", @@ -380,12 +99,6 @@ "readable-stream": "^2.0.2" } }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, "encoding": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", @@ -399,36 +112,6 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" }, - "es-abstract": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", - "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -506,103 +189,16 @@ "trim-repeated": "^1.0.0" } }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } - }, "foreach": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", - "dev": true, - "optional": true - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -611,24 +207,6 @@ "function-bind": "^1.1.1" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, "iconv-lite": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", @@ -637,98 +215,16 @@ "safer-buffer": ">= 2.1.2 < 3.0.0" } }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - }, - "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", - "dev": true - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, "is-url": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", @@ -739,12 +235,6 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, "isomorphic-fetch": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", @@ -759,16 +249,6 @@ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.3.tgz", "integrity": "sha512-fiUvdfCaAXoQTHdKMgTvg6IkecXDcVz6V5rlftUTclF9IKBjMizvSdQaCl/z/6TApDeby5NL+axYou3i0mu1Pg==" }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, "json-pointer": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/json-pointer/-/json-pointer-0.6.0.tgz", @@ -794,30 +274,11 @@ "uc.micro": "^1.0.1" } }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, "magic-string": { "version": "0.22.5", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", @@ -858,77 +319,11 @@ } } }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, - "mkdirp": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", - "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.1.tgz", - "integrity": "sha512-3qQsu3ijNS3GkWcccT5Zw0hf/rWvu1fTN9sPvEd81hlwsr30GX2GcDSSoBxo24IR8FelmrAydGC6/1J5QQP4WA==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.3", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, "node-fetch": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", @@ -938,54 +333,11 @@ "is-stream": "^1.0.1" } }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", - "dev": true - }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, "openapi-sampler": { "version": "1.0.0-beta.15", "resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.0.0-beta.15.tgz", @@ -1007,64 +359,16 @@ "word-wrap": "~1.2.3" } }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, "pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", @@ -1144,27 +448,6 @@ } } }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -1183,18 +466,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, "shallow-copy": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz", @@ -1275,58 +546,6 @@ } } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.0.tgz", - "integrity": "sha512-EEJnGqa/xNfIg05SxiPSqRS7S9qwDhYts1TSLR1BQfYUfPe1stofgGKvwERK9+9yf+PpfBMlpBaCHucXGPQfUA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimleft": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", - "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimstart": "^1.0.0" - } - }, - "string.prototype.trimright": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", - "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimend": "^1.0.0" - } - }, - "string.prototype.trimstart": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.0.tgz", - "integrity": "sha512-iCP8g01NFYiiBOnwG1Xc3WZLyoo+RuBymwIlWncShXDDJYWN6DbnM3odslBJdgCdRlq94B5s63NWAZlcn2CS4w==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -1335,21 +554,6 @@ "safe-buffer": "~5.1.0" } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, "strip-outer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", @@ -1358,15 +562,6 @@ "escape-string-regexp": "^1.0.2" } }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", @@ -1397,15 +592,6 @@ "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==" }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, "trim-repeated": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", @@ -1422,12 +608,6 @@ "prelude-ls": "~1.1.2" } }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -1474,30 +654,6 @@ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.2.0.tgz", "integrity": "sha512-SdGPoQMMnzVYThUbSrEvqTlkvC1Ux27NehaJ/GUHBfNrh5Mjg+1/uRyFMwVnxO2MrikMWvWAqUGgQOfVU4hT7w==" }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -1508,133 +664,15 @@ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, "yaml": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==" - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } } } } diff --git a/package.json b/package.json index 32562aa02..7eb746bb1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@asyncapi/ts-nats-template", "version": "0.1.0", - "description": "Nats typescript template for the AsyncAPI generator.", + "description": "NATS TypeScript/Node.js template for the AsyncAPI generator.", "keywords": [ "asyncapi", "generator", @@ -10,7 +10,6 @@ "template" ], "scripts": { - "test": "mocha", "gen": "node ./generatorComparators" }, "author": "Jonas Lagoni (jonas-lt@live.dk)", @@ -22,11 +21,6 @@ "quicktype-core": "6.0.66", "is-url": "1.2.4" }, - "devDependencies": { - "chai": "^4.2.0", - "dir-compare": "^2.2.0", - "mocha": "^7.1.1" - }, "generator": { "supportedProtocols": [ "nats" From 65e07a68aaf36aeb4c209da9c833c14700496f3e Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 27 Jul 2020 01:14:12 +0200 Subject: [PATCH 077/110] Added examples and changed readme. Fixed occurring bugs. --- README.md | 31 +- docs/img/binary_recieve_hooks.png | Bin 0 -> 7203 bytes docs/img/binary_send_hooks.png | Bin 0 -> 7205 bytes examples/docker-compose.yml | 7 + examples/publish subscribe/README.md | 2 +- .../bin/StreetlightController.js | 46 + examples/publish subscribe/bin/streetlight.js | 46 + examples/publish subscribe/generate.sh | 2 +- examples/publish subscribe/package-lock.json | 1346 +++++++++++++++++ examples/publish subscribe/package.json | 14 + examples/publish subscribe/streetlight.json | 2 +- .../streetlight/package.json | 22 +- .../StreetlightStreetlightIdCommandTurnon.ts | 43 +- .../StreetlightStreetlightIdEventTurnon.ts | 9 +- .../streetlight/src/hooks.ts | 18 +- .../streetlight/src/index.ts | 61 +- .../streetlight/src/messages/TurnonCommand.ts | 162 ++ .../streetlight/src/tests/testclient/index.ts | 56 +- .../StreetlightStreetlightIdCommandTurnon.ts | 13 +- .../StreetlightStreetlightIdEventTurnon.ts | 41 +- examples/request reply/README.md | 2 +- .../bin/StreetlightController.js | 46 + examples/request reply/bin/streetlight.js | 49 + examples/request reply/generate.sh | 2 +- examples/request reply/package-lock.json | 1346 +++++++++++++++++ examples/request reply/package.json | 14 + examples/request reply/streetlight.json | 2 +- .../request reply/streetlight/package.json | 22 +- .../StreetlightStreetlightIdCommandTurnon.ts | 33 +- .../StreetlightStreetlightIdEventTurnon.ts | 16 +- .../request reply/streetlight/src/hooks.ts | 18 +- .../request reply/streetlight/src/index.ts | 76 +- .../streetlight/src/messages/TurnonCommand.ts | 162 ++ .../streetlight/src/tests/testclient/index.ts | 73 +- .../StreetlightStreetlightIdCommandTurnon.ts | 20 +- .../StreetlightStreetlightIdEventTurnon.ts | 31 +- partials/channel/OnReceivingData.njk | 24 +- partials/channel/OnSendingData.njk | 21 +- partials/channel/Publish.njk | 12 +- partials/channel/Reply.njk | 45 +- partials/channel/Request.njk | 18 +- partials/channel/Subscribe.njk | 30 +- partials/index/Publish.njk | 9 +- partials/index/Reply.njk | 38 +- partials/index/Request.njk | 29 +- partials/index/Standard.njk | 56 +- partials/index/Subscribe.njk | 23 +- template/src/channels/$$channel$$.ts.njk | 8 +- template/src/hooks.ts | 18 +- template/src/index.ts.njk | 10 +- template/src/tests/testclient/index.ts.njk | 8 +- .../testchannels/$$channel$$.ts.njk | 8 +- 52 files changed, 3819 insertions(+), 371 deletions(-) create mode 100644 docs/img/binary_recieve_hooks.png create mode 100644 docs/img/binary_send_hooks.png create mode 100644 examples/docker-compose.yml create mode 100644 examples/publish subscribe/bin/StreetlightController.js create mode 100644 examples/publish subscribe/bin/streetlight.js create mode 100644 examples/publish subscribe/package-lock.json create mode 100644 examples/publish subscribe/package.json create mode 100644 examples/publish subscribe/streetlight/src/messages/TurnonCommand.ts create mode 100644 examples/request reply/bin/StreetlightController.js create mode 100644 examples/request reply/bin/streetlight.js create mode 100644 examples/request reply/package-lock.json create mode 100644 examples/request reply/package.json create mode 100644 examples/request reply/streetlight/src/messages/TurnonCommand.ts diff --git a/README.md b/README.md index 9ef321f71..962d37ffd 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,10 @@ This is a TypeScript/Node.js NATS template for the AsyncAPI generator.

-This template is for generating a TypeScript/Node.js NATS client based on an AsyncAPI document. The template is based on the [nats-ts](https://github.com/nats-io/nats.ts) library and can be used as both a TypeScript and Node.js library. Example generations can be found under [examples](./examples) which includes [publish and subscribe](./examples/publish%20subscribe) example as well as [request and reply](./examples/request%20reply). +This template is for generating a TypeScript/Node.js NATS client based on an AsyncAPI document. The template is based on the [nats-ts](https://github.com/nats-io/nats.ts) library and can be used as both a TypeScript and Node.js library. # How to use +Example generations can be found under [examples](./examples) which includes [publish and subscribe](./examples/publish%20subscribe) example as well as [request and reply](./examples/request%20reply). ## Requirements * @asyncapi/generator v1.0.0 @@ -54,7 +55,7 @@ or use it directly where needed. # Features * Supports wildcard channels. AsyncAPI describes the channel path to be defined as [RFC 6570 URI](https://www.asyncapi.com/docs/specifications/2.0.0/#a-name-channelsobject-a-channels-object). So a channel containing a wildcard needs to be defined as `smartylighting/streetlights/*`. This also works with parameters such as `smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured`, ensure to define the type of the parameter as a String if you want to use wildcards. -* Supports [test/mirror client](###test-client) for testing or other useful scenarios. +* Supports [test/mirror client](#test-client) for testing or other useful scenarios. * This template can be used as a javascript library as well since the generated code works directly in Node.js. * This template uses [quicktype](https://quicktype.io/) to generate the corresponding message payloads. @@ -205,16 +206,17 @@ The following payload types are supported, this is limited to the underlying NAT # Client Hooks -The generated client support custom hooks used to control the flow of information outside the generated code. The hooks can be used to alter the payload before sending or after recieving any data i.e. encrypt, compress data, etc. It is possible to register as many hooks as you want, however remember that after the first call subsequently calls will include the already changed data and not the original. Also when using these hooks you are responsible for complying with the content type for the message being changed. +Sometimes to you want to change the data before sending or reciving it. For this purpose hooks has been added to control the flow of information outside the generated code. The hooks can be used to alter the payload before sending or after recieving any data i.e. encrypt, compress data, etc. It is possible to register as many hooks as you want however there are certain restrictions. + These are the available hooks: |Hookname|Callback type|Description| |---|---|---| | BeforeSendingData | (messageToSend: any) => any | Called before sending any data. -| RecievedData | (receivedData: any) => any | Hook is called after data is recieved before the client tries to peace the message back together. +| receivedData | (receivedData: any) => any | Hook is called after data is received before the client tries to peace the message back together. ## Node.js example -This example uses the msgpack library to encode and decode the message before sending and receiving data. +This example uses the msgpack library to encode and decode the message before sending and receiving data. ```js const {AvailableEvents, NatsAsyncApiClient, Hooks} = require("nats-client"); const natsClient = new NatsAsyncApiClient(); @@ -232,9 +234,22 @@ function decode(msg){ return msgpack.decode(msg.data); // => {"foo": "bar"} } Hooks.getInstance().registerBeforeSendingData(encode); -Hooks.getInstance().registerRecievedData(decode); +Hooks.getInstance().registerreceivedData(decode); ``` +## Hook restrictions +There are different hook restrictions based on the payload type. + +### Binary payloads +Binary payloads are a bit special since you are required to at least provide 1. hook for both receiving data and when sending data since no standard way of converting a message type to a buffer has been implemented. The first hook always receive the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return the buffer representation of the message. + +### JSON payloads +The first hook always receive the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return the correct message type. + +### String payloads +The first hook always receive the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return a string representation of the message. + # Restrictions -* Empty objects are not supported, use `null` types as work around. -* This template has not been tested with different specs other then JSON Schema draft 7. +* Empty objects are not supported, use `null` types instead. +* This template has not been tested with payloads with different specs other then JSON Schema draft 7. +* \ No newline at end of file diff --git a/docs/img/binary_recieve_hooks.png b/docs/img/binary_recieve_hooks.png new file mode 100644 index 0000000000000000000000000000000000000000..2549720b1097e440d7d75b503d82c52309f69613 GIT binary patch literal 7203 zcmd6McTiJZv@akkMNzs9r58a+p#;T3NFX7UkWd2B5(puL1VS2JR1grPh*Fd;sE8s> z5RhU3QHml~KtxecdQ%V(yob;4&fJ-M=lyrzdoyQF*4caQwcA?j_uD)1SR0F-V*A7d z1O#@XQ3#xXfM7Zxb40cQZ@Nc^gn+Xh&rU&~_{mBAqP_w_18U*AUz+$UG5o!kTK?EO~<0)l{!fQ*hn^zFe0YEV-U7E0z+yH6>7zTaB2Ap28kWZ=hw>_rRMY+~jc6hH?`%whVvAYFa1zL74> z7%0aReTYHS|6*lxGF);HiyFZAI~Ooi*FYEgchqDyk@B}RFwho{#Rd9WGr15L1cnZV zvS5F8*dc-BzdDqF0E$1*Cqxa31lIE3MFZ?p|6L}3(@>{CHrv>mZE3+WwGY4=LO6fb zp^n}*e#QYjBo+kb5RF3Y@TOiNAdHbOn8@S=IvHYJf{^y!JVP(CoiiRwB6x#BEz}@z zFEbt$Z07{=H!_7mLa^4rWZ-0%U^Ihc4NNfzVSsUf;K?`#TO)mvKiY`rZ50fZ6Bsle z5oSU6B|3*?`50H@pF%n>*zw0IN*u#)017jjB5J%)$*jRJWV4z!PeFnzK&kh5{830`bn1$MeTGPqYP-_EgXBLi$ zz~HGiAX77c7h5l2zu@K$wxEC@K!62;jd?BvcA&8l;1=fA-V_*}NJQB}oXub)9>d4k zB7{c7B5;ltSZbgh9qDICw8Qw?24YNoeT>PzW>gvkm><*uPGtMQz!qpE%@oVCGZ$&16X^b0le-CRaI1B3PkTd**I427bt?YLAB zFUZgg;z(sXGmuaU6>Y<_3-yOvk}aLAIb=4NNQAS{)(lgi0m0hB($^V5@Zov+`TN62 z4nagTk-^mGLW6v<4i*>|hRxtPApF3PkbnRi8jg%|whLjip(wl^)mA?+loe=0v~{AJ zqMQsJgAue)APnFxXpFZL$dv7bMA7ZZ6c<(q+1V0sdLXFaHb%xweKUQCK@gg3AHpND zkx;a^c@UK1#K3stfE_WnVw1oKe*;92kvSz0f+OQ>>_Q=IvbB{ToLxw-tF~EDkn4iMPp zp=cY&AQ&77W8mXIBl(}O2EPBzl2ByTZPUvF0&>M@gsFY7`*e;i%B@4bLnA?0zfH_i za}PW?uU&$GBkSk#Y9)xVDtGLUVcy_B{Ic7G2j8ET+4rBEg3!v@`k? z_nCThA6(lf4PI%v@a5R(qhZ)=6YtwlSO+g}HcV+Z$7klli|nu_*7NS`wX^GM%d@h2 zQi_6`4=S$Zgct^{+P_0IML;wqO8peEKxtDF5LLB|;$POZF*FxaJq0|(f}JusEnmMD z?Nd+41VuYdfg zo|v4(8yFZc8C~_NpRNkTv}?N?&cFruLK;o=_1Bo0rp+vB>FZ7zWt~xe(d#EE>phzT zagfP5mC_ph^!KkX$$oUYwSm6A@5}LtiN1*G>1hWj6ndwy5dO#C++=LHjT+$Z|2;^m zATw1YGQeE#MecFDf`Y=tNPEJ>jpP%Zzwg!6Iq#H^nBd;IbB8@VFgOS$`F@-%z2DR~ zdg9lo^9t)Sy+O$uwz=OaA@d_hbyCHe2^d_UvUhRi`n7BN@~+>t2OdADtSr27$Xyld zFC>#rN*0*CAEV^aw(w*8RpNP|`wyu{&$YU_yT481g@qkc5z9NX5n?W)2}P`s%er+%xm({e~+^^*RzkTW7+Jt<9fK`{(?eDR~RWUM0ihT!SoxkZmN>%}*3 z-h4ebSAM6ow96$Aq_PVZxe^i?=|0R)#1%Cjiu`37u{^|Eo!xz-Bl!>osiQ2SsX|jB zEVlfS{G5MKH=fb`RIIsnP4b!l3h)6v&W_6#!}-RH)CX0>Z1VCkBSb%O9kbQB+FwfcycUycg>*1GHDhYE?a&f&fL5_A^cy?yIb zD3Y~~d7VPLgsg!kWM(D&DdP*B1-*lL)1Q3wj%xaP+AH$2kyC`{Imd1>hU$xV<+g3LNYtJ}t-zLtdg^7;hl+Z_WD|f63135o zb%ad$By%lT14dacT<;m+;H8o4Kb<1#1Df!cMyo)+;(t0QW-cx+Kh~Q!Rwui8O)cYR z7M^JwYuaL7D0E=Fvb;QhmK^z3?OjQ$(|vab7K^n?6PT-$%{IMI^|bfG0f-j8i)k=M z!JZp1XqOxIP`RafW~rZ&NceT4_@Y3JnnSDI$DC)f6>%zt$ZdS(j_Xfv^)g$Evd7iN zm8z_-v}SpZ+5LWzck;!7d&i8CkrK|%4EULFu$t9 z5#n36Y!Q=;o-SuL7ZmUuEC>fq}l^H09?fJ=#d- za+RN5gs&!ID?Hc(|&!3J%XT0AM<`guQb;g#f;^KhNuhR?=Gb=Ml51%GAnk&N=qrJ*1 z=5j2hfqZt&{6_bhRP_^5q;_FraGtiT&&+N3QPD{aRNCjt7`5Tm#4NGaT6>a)oUWwU z;uTW%&ZQos;oBaOD{9h@KZSG;5pUDPFlBB;;&i9vpNAS73Maxd8~B~SfnEFZ&#q0q zD3cNi+Au9C&%Y!{R4~AM5y>k&srMMb+ry~(D>_>x%bU@V+d%|G+T?}0rk|Dh5|tp) zE1JOQ;w26=SZ{(MRSnpu$*1KWo4|3Aafm4Q?pjiZfo7z2<*2q)N zios3A6h|QXs*`rCAvbNP0qBY=+|t2F+f;NB#S;3CLZ;+5ZT#QwOl%utxG6&GJMw75 z+{XGEn|oI{6xq;u996B|yv>R@-}SD90~6R6YIrz^3CYWjd8)T(XI)#BcE*5=oV;aj zS8wmQKzQb!>5JUa)-u1=kA_Q4%e&@h{7KolZ=37F&xYh^xIIe;4@v|COp$ zak)v@k`;%|z76Da@7#jgTBn}w?%VI~dz79%E6Djd;qa!n_tQcmQjZ0I7iVe8ne)B3 zpruK5R6t!r!yzJ~abjv}M}*Inb^{3HvX=PFr=vzjxBUG4;DhDjk3tsB0oHM6W`@D} z{cHZ*35vc|hExKpz)SZ-$TW;i6p>v(|)hsNm!Ntw((vLD(h1bMyJPo7-3 zmYLZL4U{ZwZ%6i=D$D_>!DK(ItTlF5>AidRx~D#TiyD3uf_G~QcWw+@wlPJ3N{zOv zCzU^~di&3LcMDO?`53bS>xIH{PeE;p+x5~&2=EH}3&JeO(xolt} zIt}~x?HiE1_qjhKBZG70NH>4R>HBcRfb6Q?Y$t$>Mc1xf%YO0_N$6}ZOA!QVJYD$s z^w_>1O)Wm3T0LzwY_fZsy1WB?SgIo>ckjNg0Wf<^zhp;M6{tb1G`abfBVo!u6LvpC z&tqn{+zw&>Gk_;{D;_in#-3bDRk66@e30DsQsH>0{iREnN^)}#I-EW|dA#vLSiasv zi36~5Gf#jVN*PC2?q=>_33$eUGxPGCdU|>W0+rlBp>u|HgQF>8t+MYbfK0dXd-27o zWBh3Kr!#Y5t|+7&L{3-FuME;OWtsg4AjeftPI{c7I{nFG_osnR6Xu{F)dqcRa!pF; zBIDj6!=STrk5kD4uOl{ohp6XV%4?{vx0lkY3FltbE)Ez#x)b*vI`qzXd8jG(L`1#W zII_RsX_PKaN2)^jUSnpJwOu$2v#05+0U3MR#pQKh-(~(He4RHr(0r!(XvAu@i-(8a z#d1ZCj|b_>o-O!2pM0Z-_&d1ff#k)uk);iZaM81v}Uq@aF<)t$%c z+2fb%xzpEjs}=blr?o{JARYTB={3?_KdpRJY3W+q8_u0Mt9VKv=pJ}LS^}Y1)AL^1 z&3Vn_%*LZ6&+Z4`6eS-EJFZGr*GRuP*j@&t6omnVpNibEXqncT$w_fpxgDS=QVsd$ zbAMv0>2dBKCFM&yqH?lx_zMF@kd*nzUeCP;-N+B?<1%ygAa*}E(8&ozw>$lxTnY9kX; z6`mvKy5p(PrEO|>0^`HOR2JV6B8jor*jJmIb6rQDbT;a#|NhCtmp3Y7wysCBf`82w zaD|$*H|WrNj5wJ1-i^a~@DU_g6MSg&hTzJ_ zcu+%7NFGj0M_0l2j+N`TZ+*$-5uee<*fr;cVm&^N2zvXlfj4rrzv$t^L^~Xr>s6>6 z@ssMb5*@?6dga0IcS$`1t}5t}MbDTeLm-O`XrCsg{@CY}*S?X0(>jWk|8nv4&DRf6 zN&9JG?SUeOv$!wv@7!G{Z^dI$dSp%$T#d)Hooe`(g&!3SpwbF7ep;cc&2;BAFMEJa z2E|jHbRPgiyJC`2Q1D9d7YIBcJKY)UR#%NCG7G-e?NAU;K}7 zVDJB1RhhNm;1|jAr6C90UTE(V9B^PTs!M$hM_m&5BbFCO0U8cG*&JoQ$!}e4Zg_>P6?F(45F-vkhIwd)e;ZTGf`>rO#&ex`Ve3c4=!U;J9?YSK{`}-y`#0)8By! zz3i{JNfBZv&I_b@m_*)H$N`Aa(PM9aSVbj)4|*;nbR<8x0US;cl#Xk;qP^fJTde+% zgX7QiS5fZVxM6lYWI+{Q`9Grc?g*LA>am}b@7@5qZwky}g+za`6VuYt?ld*I1D6sP z`YfDXRa8{6D$B(a*FJp6zEe^nN^jMj8|&F`0E6AGZ)n)O(-1G4#XZ(InXx8c)&2K! zgXSm?+!(x>nD8qCYmY5XjWxD@#AGyK2?wG_Kh&`%-rhUyV!~}zdbs0*yC&YwuHa)+ zM5(Up!~6@eu~ouPGQ6U(iAhO!u3nWD>v9JbrBF1zrR=uB;D^9djXUV4w2;JjB^>~h zvf@Tx-mvgvvG9$-^KiPq|LypA(c`VMN-nOhuX&e!zX78Qtx1@i``qeBqiI9ej%3Jx z9_zV2u`t>-G1R~lQ$Dx%kroIoo{)%ibITda^=>0QPa!AHpBs@oD1AO z(C^dfbeps^5=-mr2646+b6Q4jJFx;!968|L6kcaW@XQyfs;#YsK8cw7WEv5xVv(d- zWzrd^VjTM8_P+i5@yCxJzf)6FbGMHc>>l`-^Qq;mf)L)pp*TF}`RTae*kV2?y*zbg zCFISA4|f$L+QgrWEqM;axJi_NTs6=CxD%J!)wSR8W_C2PZBUN038_zn<@@qU+c(eQ zCsmGUeYp@{D3VmvV7I)o_${kiGje8P0vC3qJ$<&Z`)a-6H28jbVsi4NNszIJZQh9? z@RrMacljI!nLB%>#;N&EwoM*DLov}M`W9D?rHqUW# zaO}_ilkO|lG3T&g<;DxNcYlbltZI)54Hp+D~jxn za-}&esR~Joe5}A^=$6plm2I{8?!9yR_sZhYbKrM`^9bQIm2r#Sf#>eQ$)k;rBG$Oy zzko>0IKot~i_ejWh=>BdP-|?#Q1cm&tP<#HLfiXfg=05&k3Q5n9Gk=tm3c2N*#+!9 zXP>>Y1k>`>t5+_b-R$`HNh0DGL{j?!%#`wIqqHpyi+hTTtA{?_eJTzl+M@dWW1N>* z*QNbNL1HIW(mgfIh+06ZxI|D?gj{d0zgX1lPc$|9lzH$(`0bsI2LM3K2>S;RoA=Xn z#;_V$VhR6XBJ)yJt4@Y!Mq0VZ`Emm}t?j0p_d&O8a{AI>@i5TAUwh9fm4J$F|AoMx zEsgb0F3&cyv+m=7*!c$p?e}DF+aW8yDzE2mf8V{a&-^e{i#4f|IAl>a)V}+oox1;W zylqEjQTZkmcGsnBJWRT38(9{CGOJUp84J}=XDaKwdGjXpGi^V|#2pWG9M5mW0w` zS1BRcmqd{^Nw$;}!i0Kn^}NUL_s8$}9mo6E_dSmLxbJhW`<(N)T07y7z?#1MU5Euh81 z-=9f!p^|OrfOnK0)Ib}m4>W7qpdE2obsbAUX3`l{;9*7eVz9UVVo3{Rvw#*9OjjGM ztqajL(1sZT?G7YwQXu{Rva&T89yO3dXZ!sb3k0gIrw#qnYbuxI^QV;q@o=`X_VdES zuzD0boCk*PO#7q54fUt~(eYukeVBkx9d#%Yh~>XQ1MJiP4HKRn3^BBHrf^}-UNnC= z!snQu>mPMJXA0iekmG~214DQWvXw8*&MyeB&wx7N0-c=#m}Isg2ZM0s;%Q_!oecCD z#bY5X(6AsDokD;G;_baKL1Z|>S{LdIL+b={s4zf<6GCGVAxujYjt4`bxilvZ&l2t$ z!mxwckP!Cva7P^8-#XX_;fkcXSmTLgB*L2wcZO3D6p{^`?(5@E@b$vk+E}mvTS!Zc ztrrJ|*VS<&6JR7=rXv=K2t-irgMxhQd>9Tau%mD2R=k6)8DS1#w!wDZVYZI;SYNUQ zmTikc+q>BZ*r)6I^^43^p>10pURX?YI;qn@!LG6yZ2G3$_D8SI?56W9#G=q!VD_>!i!J z=Y#}f19@0F3uz5E46mj>XTTG6qGfWs|TzZloQU`%bs9h zWk}!vrmcyLAQqXyaU|Gcur7gUl)gRG8;Y``IAhS504ID1hQdIB@rHhQKN|-_R|~hW z05@A?C`-q|KnLoGWB3FF`GxRoz`oWPU|GPazC^>VV4xhWtg%=Yho)zXrEz`H1av3| z2fRmdLolH*OK(8bweYquv;hQt2-};B3=E+1Al`ItpbyWBi*TV}z*qvt--+j_XJJ9r z0VD9CTzyoiE`ea}5Nu5%B7I3t_EblHW4gp@lJRsrWczg)V58;X+1M3Tp33MYvb?s4J)Ic^<7tIbvZ-vyEJi!A4{yU3*r!?^UUxb7rNs;+%0Rh>Y7=(pm$m#ifTbh%Vd`D;8 z87(*EA%aM?1)3Lg4yoMT3d*#*0T;tTx{F12^DV)8?NM#}9ZJb+e|fdV<@s8xc2IAg znuQA=y8zc$e<>mB)NE`ja=D zyNwa+E4L?*LTct)*G|b%I0=)WmZvNzbx2U^sfZ>>S7b{%6oc4lN0e&s?m$P20GB4H zF6OyZ&ZSHC2M->+A2mEY?91ahJ2^XRjCj;V@fWFYzl=Q$A08hs@(U-E;jDK}Ce`a` zO9q1x`c`;zZS6z4bi{O^}5CKG$bkHe|`vDkb31=473{bjAs_l3ON+~>Ato0Ia@De37}zMV(yZr;4eqhI4$~*EVr;Zy$!c)Ze)?SND9t?3aQj$bXH0=fghPWgkC3 z{5xT};;MAhALw1Z?B>m~FK-&I{`xi1zH9R?&@D%^cmuM9@xFcg+)5CRg9axIj!U8C z1;uP$p<*|?_wLOAyL|C4k;-a$lzs8yr@~)rA0+0BBX^eEJq`lR zI`}R$|7!a2^|3^){?a#t9m?8#tOUOH;op1$M#Pe%98)I=#E*p-EqpHhwXC=?ekb9V zz~@6dVH)P7fZaL$a!P`1-MGV(sIYIT&_YckU^rafEzIxa8n=vYh1YJSlAsj&fF>4~rz*O3rFp=&mG`Lvq^4Z;FPoIgYgevVC|OM- zh3Lw_xO&l5N@A@#U~rMf;lt3%qMhhIgL#7|B;%S>Ux}a z;d)V78R~ryWU)aiaqmVGbo+dPaWEc-!+i|Cbj8f)$z^*vZTF|Fu3oi=*LwTTQyZF+ zQKpuvg~|NM^S1k|VYSx!3UNR$#Pmi2;DltgNiQ;JfAmU%R;&iA$_v zcMlJbY3W7(vEJTZqrY_WoB6r>1AYz^n!Qk}K*&ouz5nIEINb{tM429Z_wr>qQfxDF zV=Z8MzIXA&bT3pncj#^rZ%Uev7Pa>HilRi?4J8`Z4DJUI3Nl{pTO+cuLhM7g9R+2o zNY5Nkd-Hjp$kpa%539YW<5Sn)mu6qRdiBS?m5Gi1ACc?(Ek1%Au78bkPhj?;(Q`eF z_0oZc6`MZZ!&SUaefDQsO+5jaX|1V2+n2SXrLAg5T8vvMONx@o2Bj3#j%hh+_b1Oo zpy_F|%lxjcgt@snLP&L~f%x_lk;PN{M3->AnLO!1ICts$3y)8_IgJxao7urB%3>L- z5pnfLGtM=*+LADrBx{Xx1>)k)p8HEEvUMUA)*6d!>L4oc>>>=E&eFy!n|}_8inj4* zl8Aj>LQ@5%5xIPQG_+>#;H&1S=CNlPk45z*Z7O&Ns!KZDUuGz5L3sM}y=WEkH?d^? zLyfV7Z4%la4fxZjs%-X-ZC`&CUiV=YmtF=InXjJomHTL(I8I?F zhJ(r>B;KTlkc@0D+;_*?e02_6Z{=B1Fx5tm#-^DZ9t?SjfeINFzgp%QZP9g6#d8UlLXyNi73Uw>Y&?4= zE;&UYuC#0Wg>=iUB#Yaco#h>0e*&_a9R(OVQorbLg{_p+)CH39idFRL;jLn(q6#S1 z2u^)CC$RIJ`4ynFiJ1sBn(YLB${YX`GsHEO;V!>n3Wvg!~ls})CE9)64RUy z`)!{FU>`hPV8M3FH4+6VQiOXtw<>20T)L=ACQKwG>bGkhKv6~B&UDXj`@rOuK2>d5 zKfmQV0{|46m(hy>TR>2>Rd3@I1;+}vTqglTQ{N_hpW2%(v#gSTDr9|yWn_G3XBhH< zn4;RNtdqiJRrjVC!$t}M;t?iC0;_cjTi}y3>1W+1US{D~V#(s_omAQ^S3nz^!b3g? zB)RCb2t=l)p|+){x#)On8_lKes2q>_Oe3!SY~}|YuE75;)w0vX>6sa)h=|SmK6F1n zXDAeUqp|VLwBatd>7J~kbF+h2eLK?*Hf^GN1XEH|%afAChR4Pfe>7?)GeSaO4m>&? zlm7>?kQ4Xs+$q~GD(d9pbM3~>o4e*Mi7_Sja#kNf@6^|q%NzKq4RsC=I}N{kSJ?oN zn6oB?;;46;4|=XWEA@4WOlcdDm6g?r`ts$Av$V9d@A}Go46#&E>@q9>e$X%w!76Fq zReMxE9R08=MJeepu+1O!Mv)u$j3Rz48^vH+W6tygBxD$v35`uZ7e zq;Gju8kB`Y$~6s~nKZ?eD_4|*##;pAhJo!&eQtjK@cA)!i!QOETeq;rIcLvqKN`;z z9zHq!s-7`7*?oSlKhHo+<;?meA!#dO?BfEH@MYHd6k;E3@WGIj@?#TZ-$qACW##e5 zW*)qNduwlZZOR`wFnF{D;6?bLpdk7K@B#Sc0F&?)?EKh6%f}MJlii8|sdxn5ek8zl-`6F><13*i4?J zrT;)|BEyCVFuuCxm}WTlIC*GvG^hLN7Hs4hu)SZZ7PCe(Uqq394)pgU3mDVT*q2$U z5oLHHrI;U=GM1S7s3lG?v$?*mZnh9Y+^>5f^v5zC<*!C1Rfs*^9{FW<)?YTT6{E~L z!+3p%P>((s_0i~y>_X^V*5~qbw=-cQ~-gkBvwYBx9J1V!X z%CqxM0YcPPy;@{>-!ry**w+=|=Cx zU^P0axdaZ?Wnx3QYV2FODyW_2(h!S`HSg(C+5KVuFo+xlfN^Aho!K`J zA|j9TtmEVB3*A%~3$2LSx0hRWjErs^?nJqRVbXQ)Odh65pZ~Ek|Jq0*^y84ahv=d8 z?ZD!HcGDXA?&HO~x}tB`?86vYfXX?=?>RVhG*xZP?{Z~T*W8=GHApr0?&YZO_SdB; zZ8tG7$=`P%5uKRvSkfePQEl;b>hj_47ft^h|Ix&LXZmn<@9UUU8?LhbO+@qFc2Nn% z+2$7`BfcjsL!oA0PGz0h=A3^|(Jb<^BsoB4?O}>^sm8pKTj&zL7^lF36)M%<~YL+2ALf9ji>7ErsS<{x2_s>Xv8 zTK6cKDlq;z(Vc*l-JPyz(t{Plod5Fnfx*#(zGA(=WGzp=1&U(WOn&f4sm;UIGxzt( zxbNK$?N=66$C9dXr?&S~E=ndJ2$)s{%`%=|*^6MeQ(PKO-10E;fUT^oOz*2UCvNN+ z$stoYw8M^)KaY*;lB?%qlLJZNpg>#fr`l{x;m)c+l9X)Sxe~l?c0~y zQ#RgV_0~&UJq_gFH@AN7@z%bkP3|71n{|Hd$0b*NepPQXQ}NE;HXw|i2^ON zRmwna&rFVO)JBJimbUkgZujABNYd$RbBC>mJgN;!M%C^wy>4D#dCeXMR&&r1{qp|s zi@YgoVp4xaYixU7lg?_Ix{Z+1@bl*-w#nN8-*@GM)-?MnlJLY0#V%vP#yqnAUiXVT zjpYh12!A(z<2k+Za1d9KuN5VhIQ^p!!F?i)Z7TFJxWut|8YX&Rqu^2LsVS*! z_d%P{D|=r#xih#PW_=aRu&Qzu*#+Umi4T)WB@#oLAd+x~tmt1O1F1j5uQVi}$CtDF z;{!H}<-iH>IIt_O7lkwwjnEVq{JuM z)wx^cF7d$m!M*cIys6d-=BtvbQM*9*vwNcVw8SM2R?u9uKlha3{*=*Kfms3foc;ef zRrjX3R{<~b4GP;{?1U{)tl8!O3D^&ifUBhd3Fsa9O;08PdSdO@#c$c7C*#=yaqY)E z?%=oBiMkcQP692Th-z%@KkfoF!;fDR^qZU*0^}r9KF}1rMNaOi0~?v%i?@GslWu^U zTzGSCDQ3%f%P~Q*>jEnrXR?XuA_Gdp6pFsqTIzpnmk1Lvuq~W7mrScClj5N$U_e+5J?H@W{4FVjj zxYi5TDKfkNgP=xp$Oh5)-~H3a9D##gCt4=u(v=uihs}ZMOVc|jUF4M_nzJ$S&1-%Z za69<2y39+6oAOQIyvK>iTL<$2?qp;d~lRMMvuL7J5;nSI$w(}{ZLm2!2 z>s+SjgFgog%@ru%3?Uad=9rqA3a#rXcByc;w@O!ZGUk2$8uxw(lJeMNkQn8GG_i^he{o*|xrMGVbixfohd-3+|Z4C{L=K#J7KREQ= zZoDl~daf%&^@ih2&}d`b0jsT5Sg6B?l_lKO{NbB3Tj|m4+?lTAa?Q5z^kHy?f@;T? z&o67|0O$jlX06VSww9LY+{>38fxT9bb4xYY{q*UPka(W(MNWKY=!WiVb; zl%GFrd&7V|rkSv#;H^wfNgT3+4jhu?+GGMy+8^f9r9!!PE#XpO|MK_m)X%DkF*dm# zQW1e~QQD;P8#jiQ#FnJ&ixV(jUS1l~gU_B_^&4v}f589z5?UX=`UNX8nSZV7YC}T< zqO(s=DR1TRbSX|=CR^b`oAO%R(3q2Wij3TDm!Bg;L&Z^NB_HS5Pk(%N?Z6|8BimHG zDzg7ne9c5V1?k|RAg5ZORihl;UdnqUn6rI$b>nnrY}U~H>$^dbD?_C=KtydSdDzDn z8aJxFI=LcV(=nTi4bzCPuU~781iZW-bkm4Cd+xM&8IpL;Xz8?$cXD#FYisoEwiQ9h zrGkPdNhyeuHbaYqf)k-qp_LjJ#V<^}*y9P>AdtF*y5Ixy)gn7>SgiT`n}4MkP8)XE z>+C9Rb)BBtTwk?3C83%ft0G&Xk3yliT%k@O`^fKePDNGj55x4HUILT(QP#{_1V}>3 z^m)d0ghEa9ekG-WKy#^7G8NQ%=G}Wk;LYVVjmUBosH`fdFFZVaDT#Op6e+5!mg?H4 z#keMEa~+h0j;S({eI#Jf5V?8ZDCBFAzGour+?SRC?<2bDROQADN`G-^~=B^JF*lb%O2y1i6MxF7ARnqxOZy$nbOJg zLEQs)B;-$Nf4)~u5eCZvM}Nzhwj#&a&|v}Z-OJ*GFyAiuBE0c05V-k2$VhapM|sk5!RZQH>SN&N4a { + setTimeout(() => { + natsTestClient.disconnect(); + }, 1000) +}; +natsTestClient.on(AvailableEvents.connect, async (connection, serverURL, info) => { + console.log("StreetLightController: connected"); + + //Listen for when the streetlight turns on. + natsTestClient.subscribeToStreetlightStreetlightIdEventTurnon( + (err, msg, streetlight_id) => { + return new Promise((resolve, reject) => { + console.log(`StreetLightController: Received message that streetlight ${streetlight_id} is turned on message was: ${JSON.stringify(msg)}`); + stopApplication(); + }); + }, + streetlight, + { + max: 1 + } + ); +}); + +async function connect(){ + console.log("Connecting client"); + try{ + await natsTestClient.connectToHost("localhost:4222", {reconnectTimeWait: 1000, reconnect: true, waitOnFirstConnect: true, maxReconnectAttempts: -1}); + }catch(e){ + console.log("Could not connect client") + console.log(e); + } +} +connect(); + +// Wait a bit before sending the request. +const timeoutFunction = setTimeout(async () => { + if(!natsTestClient.isClosed()){ + clearTimeout(timeoutFunction); + console.log(`StreetLightController: Publishing to turn on the streetlight`) + const publishMessage = TurnonCommandMessage.Convert.toTurnonCommand(JSON.stringify({lumen: 100})); + await natsTestClient.publishToStreetlightStreetlightIdCommandTurnon(publishMessage, streetlight); + } +}, 5000); \ No newline at end of file diff --git a/examples/publish subscribe/bin/streetlight.js b/examples/publish subscribe/bin/streetlight.js new file mode 100644 index 000000000..31c8f7ee5 --- /dev/null +++ b/examples/publish subscribe/bin/streetlight.js @@ -0,0 +1,46 @@ +const {AvailableEvents, NatsAsyncApiClient, AnonymousMessage1Message} = require("nats-client"); +const natsClient = new NatsAsyncApiClient(); +const streetlight = "test_1"; +const stopApplication = () => { + setTimeout(() => { + natsClient.disconnect(); + }, 1000) +}; +natsClient.on(AvailableEvents.connect, (connection, serverURL, info) => { + console.log("NatsAsyncApiClient connected"); + + //Listen for when the controller want to turn on the streetlight + natsClient.subscribeToStreetlightStreetlightIdCommandTurnon( + async (err, msg, streetlight_id) => { + console.log(`Streetlight: Received message to turn on the streetlight ${streetlight_id}, publish message was: ${JSON.stringify(msg)}`) + + //lets publish that the light is turned on. + const publish = async (lumen) => { + try{ + console.log(`Streetlight: publishing that the light is turned on`); + const publishMessage = new AnonymousMessage1Message.Convert.toAnonymousMessage1(JSON.stringify({lumen: lumen})); + await natsClient.publishToStreetlightStreetlightIdEventTurnon(publishMessage, streetlight); + stopApplication(); + }catch(e){ + console.log("Streetlight: Something went wrong when requesting the event StreetlightStreetlightIdEventTurnon"); + console.log(e); + } + } + publish(msg.lumen); + }, + streetlight, + { + max: 1 + } + ); +}); +async function connect(){ + console.log("Connecting client"); + try{ + await natsClient.connectToHost("localhost:4222", {reconnectTimeWait: 1000, reconnect: true, waitOnFirstConnect: true, maxReconnectAttempts: -1}); + }catch(e){ + console.log("Could not connect client") + console.log(e); + } +} +connect(); diff --git a/examples/publish subscribe/generate.sh b/examples/publish subscribe/generate.sh index 56e9bcac5..26222ece6 100644 --- a/examples/publish subscribe/generate.sh +++ b/examples/publish subscribe/generate.sh @@ -1,3 +1,3 @@ #!/bin/sh -ag --install --output "./streetlight" "./streetlight.json" "../../" --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" \ No newline at end of file +ag --install --output "./streetlight" "./streetlight.json" "../../" --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" && cd ./streetlight && npm i && npm run build && cd .. \ No newline at end of file diff --git a/examples/publish subscribe/package-lock.json b/examples/publish subscribe/package-lock.json new file mode 100644 index 000000000..637f7eeea --- /dev/null +++ b/examples/publish subscribe/package-lock.json @@ -0,0 +1,1346 @@ +{ + "name": "publish-subscribe", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "concurrently": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.2.0.tgz", + "integrity": "sha512-XxcDbQ4/43d6CxR7+iV8IZXhur4KbmEJk1CetVMUqCy34z9l0DkszbY+/9wvmSnToTej0SYomc2WSRH+L0zVJw==", + "requires": { + "chalk": "^2.4.2", + "date-fns": "^2.0.1", + "lodash": "^4.17.15", + "read-pkg": "^4.0.1", + "rxjs": "^6.5.2", + "spawn-command": "^0.0.2-1", + "supports-color": "^6.1.0", + "tree-kill": "^1.2.2", + "yargs": "^13.3.0" + } + }, + "date-fns": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.15.0.tgz", + "integrity": "sha512-ZCPzAMJZn3rNUvvQIMlXhDr4A+Ar07eLeGsGREoWU19a3Pqf5oYa+ccd+B3F6XVtQY6HANMFdOQ8A+ipFnvJdQ==" + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + }, + "nats-client": { + "version": "file:streetlight", + "requires": { + "@types/klaw-sync": "^6.0.0", + "@types/node": "13.9.5", + "ts-nats": "1.2.4", + "ts-nkeys": "1.0.16", + "typescript": "3.4.3" + }, + "dependencies": { + "@types/chai": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz", + "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==" + }, + "@types/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@types/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-Ibfb2jgpjYUxnl7RSVvUzOrv/vhkTVKEfPwQf9ZlDDsSyWVDp/2JtTBxO4eRrKBYtxc3cZQabdR38i8R0o1uww==", + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", + "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==" + }, + "@types/node": { + "version": "13.9.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.5.tgz", + "integrity": "sha512-hkzMMD3xu6BrJpGVLeQ3htQQNAcOrJjX7WFmtK8zWQpz2UJf13LCFF2ALA7c9OVdvc2vQJeDdjfR35M0sBCxvw==" + }, + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" + }, + "chokidar": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "requires": { + "type-detect": "^4.0.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "requires": { + "is-buffer": "~2.0.3" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "requires": { + "chalk": "^2.4.2" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "mocha": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", + "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "chokidar": "3.3.0", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "3.0.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.5", + "ms": "2.1.1", + "node-environment-flags": "1.0.6", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "nuid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/nuid/-/nuid-1.1.4.tgz", + "integrity": "sha512-PXiYyHhGfrq8H4g5HyC8enO1lz6SBe5z6x1yx/JG4tmADzDGJVQy3l1sRf3VtEvPsN8dGn9hRFRwDKWL62x0BA==" + }, + "object-inspect": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=" + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + }, + "readdirp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "requires": { + "picomatch": "^2.0.4" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "ts-nats": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/ts-nats/-/ts-nats-1.2.4.tgz", + "integrity": "sha512-bIC+PlwHplRqhooa9kE+QPcQ9RPGUXD2ruvdf6LoFpP6MjE6exVoRhYSydm0e5wk7VfuXpTbH1NoopTKHwlOKA==", + "requires": { + "nuid": "^1.1.0", + "ts-nkeys": "^1.0.12" + } + }, + "ts-nkeys": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/ts-nkeys/-/ts-nkeys-1.0.16.tgz", + "integrity": "sha512-1qrhAlavbm36wtW+7NtKOgxpzl+70NTF8xlz9mEhiA5zHMlMxjj3sEVKWm3pGZhHXE0Q3ykjrj+OSRVaYw+Dqg==", + "requires": { + "tweetnacl": "^1.0.3" + } + }, + "ts-node": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + } + } + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "typescript": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.3.tgz", + "integrity": "sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + } + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "read-pkg": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", + "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", + "requires": { + "normalize-package-data": "^2.3.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "rxjs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz", + "integrity": "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==", + "requires": { + "tslib": "^1.9.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=" + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/examples/publish subscribe/package.json b/examples/publish subscribe/package.json new file mode 100644 index 000000000..acd3a1839 --- /dev/null +++ b/examples/publish subscribe/package.json @@ -0,0 +1,14 @@ +{ + "name": "publish-subscribe", + "version": "1.0.0", + "description": "Publish and subscribe example", + "scripts": { + "start": "concurrently \"node ./bin/streetlight\" \"node ./bin/streetlightController\"" + }, + "dependencies": { + "nats-client": "file:./streetlight", + "concurrently": "5.2.0" + }, + "author": "", + "license": "ISC" +} diff --git a/examples/publish subscribe/streetlight.json b/examples/publish subscribe/streetlight.json index 975d08951..b619ce0cb 100644 --- a/examples/publish subscribe/streetlight.json +++ b/examples/publish subscribe/streetlight.json @@ -19,7 +19,7 @@ "publish": { "operationId": "Listen when to turn on the streetlight", "message": { - "name": "subscribeToTurnonCommand", + "name": "TurnonCommand", "payload": { "type": "object", "required": ["lumen"], diff --git a/examples/publish subscribe/streetlight/package.json b/examples/publish subscribe/streetlight/package.json index 66239b020..395761267 100644 --- a/examples/publish subscribe/streetlight/package.json +++ b/examples/publish subscribe/streetlight/package.json @@ -1,6 +1,4 @@ { - - "name": "streetlight", "description": "", "version": "1.0.0", @@ -13,17 +11,17 @@ "test": "mocha -r ts-node/register tests/**/*.spec.ts" }, "dependencies": { - "@types/klaw-sync": "^6.0.0", - "@types/node": "13.9.5", + "@types/klaw-sync": "^6.0.0", + "@types/node": "13.9.5", "ts-nats": "1.2.4", "typescript": "3.4.3", - "ts-nkeys":"1.0.16" + "ts-nkeys": "1.0.16" }, - "devDependencies": { - "@types/chai": "^4.2.11", - "@types/mocha": "^7.0.2", - "chai": "^4.2.0", - "mocha": "^7.1.1", - "ts-node": "^8.8.1" - } + "devDependencies": { + "@types/chai": "^4.2.11", + "@types/mocha": "^7.0.2", + "chai": "^4.2.0", + "mocha": "^7.1.1", + "ts-node": "^8.8.1" + } } diff --git a/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts b/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts index b411ad58b..d12852cde 100644 --- a/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts +++ b/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts @@ -1,18 +1,19 @@ -import * as SubscribeToTurnonCommandMessage from '../messages/SubscribeToTurnonCommand' +import * as TurnonCommandMessage from '../messages/TurnonCommand' import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; import {ErrorCode, NatsTypescriptTemplateError} from '../NatsTypescriptTemplateError'; import { Hooks } from '../hooks'; export function subscribe( - onDataCallback : (err?: NatsTypescriptTemplateError, msg?: SubscribeToTurnonCommandMessage.SubscribeToTurnonCommand, streetlight_id?: string) => void, - nc: Client, - - streetlight_id: string - + onDataCallback : (err?: NatsTypescriptTemplateError, msg?: TurnonCommandMessage.TurnonCommand, streetlight_id?: string) => void, + nc: Client + + ,streetlight_id: string + , + options?: SubscriptionOptions ): Promise { return new Promise(async (resolve, reject) => { - let subscribeOptions: SubscriptionOptions = {}; + let subscribeOptions: SubscriptionOptions = {... options}; try{ let subscription = nc.subscribe(`streetlight.${streetlight_id}.command.turnon`, (err, msg) => { @@ -21,20 +22,22 @@ export function subscribe( }else{ const unmodifiedChannel = `streetlight.{streetlight_id}.command.turnon` const receivedTopicParameters = { - streetlight_id : msg.subject.slice(unmodifiedChannel.split("${streetlight_id}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlight_id}")[1].length) - } - try{ - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived: any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - }catch(e){ - reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); - return; + streetlight_id : msg.subject.slice(unmodifiedChannel.split("{streetlight_id}")[0].length, msg.subject.length-unmodifiedChannel.split("{streetlight_id}")[1].length) } - let publishedData = SubscribeToTurnonCommandMessage.Convert.toSubscribeToTurnonCommand(processedDataReceived); - onDataCallback(undefined, publishedData, + +try { + let receivedDataHooks = Hooks.getInstance().getreceivedDataHook(); + var receivedData : any = msg.data; + for(let hook of receivedDataHooks){ + receivedData = hook(receivedData); + } +} catch (e) { + const error = NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e); + reject(error); + return; +} + + onDataCallback(undefined, receivedData, receivedTopicParameters['streetlight_id']); } }, subscribeOptions); diff --git a/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts b/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts index 812a45e75..5f3276c8e 100644 --- a/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts +++ b/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts @@ -6,9 +6,9 @@ import { Hooks } from '../hooks'; export function publish( message: AnonymousMessage1Message.AnonymousMessage1, - nc: Client, + nc: Client - streetlight_id: string + ,streetlight_id: string ): Promise { return new Promise(async (resolve, reject) => { @@ -21,11 +21,12 @@ try{ dataToSend = hook(dataToSend); } }catch(e){ - reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + const error = NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e); + reject(error); return; } - nc.publish(`streetlight.${streetlight_id}.event.turnon`, dataToSend); + await nc.publish(`streetlight.${streetlight_id}.event.turnon`, dataToSend); resolve(); }catch(e){ reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); diff --git a/examples/publish subscribe/streetlight/src/hooks.ts b/examples/publish subscribe/streetlight/src/hooks.ts index 321b9085c..d4528c513 100644 --- a/examples/publish subscribe/streetlight/src/hooks.ts +++ b/examples/publish subscribe/streetlight/src/hooks.ts @@ -1,20 +1,20 @@ export enum AvailableHooks { - RecievedData = 'RecievedData', + receivedData = 'receivedData', BeforeSendingData = 'BeforeSendingData' } -export type RecievedDataHook = (receivedData: any) => string; +export type receivedDataHook = (receivedData: any) => string; export type BeforeSendingDataHook = (messageToSend: any) => string; export class Hooks { private static instance: Hooks; private hooks: { BeforeSendingData: BeforeSendingDataHook[]; - RecievedData: RecievedDataHook[]; + receivedData: receivedDataHook[]; }; private constructor() { this.hooks = { BeforeSendingData: [], - RecievedData: [] + receivedData: [] } } public static getInstance(): Hooks { @@ -40,15 +40,15 @@ export class Hooks { * Register a hook for BeforeSendingData * @param hook */ - public async registerRecievedData(hook: RecievedDataHook) { - this.hooks[AvailableHooks.RecievedData] - ? this.hooks[AvailableHooks.RecievedData].push(hook) + public async registerreceivedData(hook: receivedDataHook) { + this.hooks[AvailableHooks.receivedData] + ? this.hooks[AvailableHooks.receivedData].push(hook) : [hook]; } - public getRecievedDataHook(): RecievedDataHook[] { - return this.hooks[AvailableHooks.RecievedData]; + public getreceivedDataHook(): receivedDataHook[] { + return this.hooks[AvailableHooks.receivedData]; } public getBeforeSendingDataHook(): BeforeSendingDataHook[] { diff --git a/examples/publish subscribe/streetlight/src/index.ts b/examples/publish subscribe/streetlight/src/index.ts index f62a6d5fc..9545944d0 100644 --- a/examples/publish subscribe/streetlight/src/index.ts +++ b/examples/publish subscribe/streetlight/src/index.ts @@ -3,8 +3,8 @@ import {fromSeed} from 'ts-nkeys'; -import {AvailableHooks, RecievedDataHook, BeforeSendingDataHook, Hooks} from './hooks'; -export {AvailableHooks, RecievedDataHook, BeforeSendingDataHook, Hooks} +import {AvailableHooks, receivedDataHook, BeforeSendingDataHook, Hooks} from './hooks'; +export {AvailableHooks, receivedDataHook, BeforeSendingDataHook, Hooks} import * as TestClient from './tests/testclient/'; export { TestClient }; import {ErrorCode, NatsTypescriptTemplateError} from './NatsTypescriptTemplateError'; @@ -18,14 +18,17 @@ import { Subscription, ServersChangedEvent, SubEvent, - ServerInfo + ServerInfo, + SubscriptionOptions } from 'ts-nats'; + +export {Client, ServerInfo, ServersChangedEvent, SubEvent} import * as streetlightStreetlightIdCommandTurnonChannel from "./channels/StreetlightStreetlightIdCommandTurnon"; export {streetlightStreetlightIdCommandTurnonChannel}; import * as streetlightStreetlightIdEventTurnonChannel from "./channels/StreetlightStreetlightIdEventTurnon"; export {streetlightStreetlightIdEventTurnonChannel}; -import * as SubscribeToTurnonCommandMessage from "./messages/SubscribeToTurnonCommand"; -export {SubscribeToTurnonCommandMessage}; +import * as TurnonCommandMessage from "./messages/TurnonCommand"; +export {TurnonCommandMessage}; import * as AnonymousMessage1Message from "./messages/AnonymousMessage1"; export {AnonymousMessage1Message}; @@ -85,9 +88,11 @@ export class NatsAsyncApiClient extends events.EventEmitter{ return new Promise(async (resolve: () => void, reject: (error: any) => void) => { this.options = this.setDefaultOptions(options); try{ - this.options.payload = Payload.JSON; - this.jsonClient = await connect(this.options); - this.chainEvents(this.jsonClient); + if(!this.jsonClient || this.jsonClient!.isClosed()){ + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); + } resolve(); }catch(e){ reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); @@ -95,12 +100,22 @@ export class NatsAsyncApiClient extends events.EventEmitter{ }) } + /** + * Returns whether or not any of the clients are closed + */ + isClosed(){ + if (!this.jsonClient || this.jsonClient!.isClosed()){ + return true; + } + } /** * Disconnect all clients from the server */ async disconnect(){ - this.jsonClient!.close() + if(this.jsonClient && !this.jsonClient!.isClosed()){ + this.jsonClient!.close(); + } } private chainEvents(ns: Client){ @@ -205,16 +220,23 @@ export class NatsAsyncApiClient extends events.EventEmitter{ /** * Channel for the turn on command which should turn on the streetlight - * @param onDataCallback Called when message recieved. + * @param onDataCallback Called when message received. */ - public subscribeToStreetlightStreetlightIdCommandTurnon(onDataCallback : (err?: NatsTypescriptTemplateError, msg?: SubscribeToTurnonCommandMessage.SubscribeToTurnonCommand, streetlight_id?: string) => void - ,streetlight_id: string - ): Promise { + public subscribeToStreetlightStreetlightIdCommandTurnon( + onDataCallback : (err?: NatsTypescriptTemplateError, msg?: TurnonCommandMessage.TurnonCommand, streetlight_id?: string) => void + + ,streetlight_id: string + , + options?: SubscriptionOptions + ): Promise { const nc: Client = this.jsonClient!; if(nc){ - return streetlightStreetlightIdCommandTurnonChannel.subscribe(onDataCallback, nc - - ,streetlight_id + return streetlightStreetlightIdCommandTurnonChannel.subscribe( + onDataCallback, nc + + ,streetlight_id + , + options ); }else{ return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); @@ -226,8 +248,11 @@ export class NatsAsyncApiClient extends events.EventEmitter{ * Channel for when the streetlight is turned on * @param requestMessage The message to publish. */ - public publishToStreetlightStreetlightIdEventTurnon(requestMessage: AnonymousMessage1Message.AnonymousMessage1 - ,streetlight_id: string + public publishToStreetlightStreetlightIdEventTurnon( + requestMessage: AnonymousMessage1Message.AnonymousMessage1 + + ,streetlight_id: string + ): Promise { const nc: Client = this.jsonClient!; if(nc){ diff --git a/examples/publish subscribe/streetlight/src/messages/TurnonCommand.ts b/examples/publish subscribe/streetlight/src/messages/TurnonCommand.ts new file mode 100644 index 000000000..27c30978c --- /dev/null +++ b/examples/publish subscribe/streetlight/src/messages/TurnonCommand.ts @@ -0,0 +1,162 @@ +// To parse this data: +// +// import { Convert, TurnonCommand } from "./file"; +// +// const turnonCommand = Convert.toTurnonCommand(json); +// +// These functions will throw an error if the JSON doesn't +// match the expected interface, even if the JSON is valid. + +export interface TurnonCommand { + /** + * How bright should the light be. + */ + lumen: number; +} + +// Converts JSON strings to/from your types +// and asserts the results of JSON.parse at runtime +export class Convert { + public static toTurnonCommand(json: string): TurnonCommand { + return cast(JSON.parse(json), r("TurnonCommand")); + } + + public static turnonCommandToJson(value: TurnonCommand): string { + return JSON.stringify(uncast(value, r("TurnonCommand")), null, 2); + } +} + +function invalidValue(typ: any, val: any): never { + throw Error(`Invalid value ${JSON.stringify(val)} for type ${JSON.stringify(typ)}`); +} + +function jsonToJSProps(typ: any): any { + if (typ.jsonToJS === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ }); + typ.jsonToJS = map; + } + return typ.jsonToJS; +} + +function jsToJSONProps(typ: any): any { + if (typ.jsToJSON === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ }); + typ.jsToJSON = map; + } + return typ.jsToJSON; +} + +function transform(val: any, typ: any, getProps: any): any { + function transformPrimitive(typ: string, val: any): any { + if (typeof typ === typeof val) return val; + return invalidValue(typ, val); + } + + function transformUnion(typs: any[], val: any): any { + // val must validate against one typ in typs + const l = typs.length; + for (let i = 0; i < l; i++) { + const typ = typs[i]; + try { + return transform(val, typ, getProps); + } catch (_) {} + } + return invalidValue(typs, val); + } + + function transformEnum(cases: string[], val: any): any { + if (cases.indexOf(val) !== -1) return val; + return invalidValue(cases, val); + } + + function transformArray(typ: any, val: any): any { + // val must be an array with no invalid elements + if (!Array.isArray(val)) return invalidValue("array", val); + return val.map(el => transform(el, typ, getProps)); + } + + function transformDate(val: any): any { + if (val === null) { + return null; + } + const d = new Date(val); + if (isNaN(d.valueOf())) { + return invalidValue("Date", val); + } + return d; + } + + function transformObject(props: { [k: string]: any }, additional: any, val: any): any { + if (val === null || typeof val !== "object" || Array.isArray(val)) { + return invalidValue("object", val); + } + const result: any = {}; + Object.getOwnPropertyNames(props).forEach(key => { + const prop = props[key]; + const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined; + result[prop.key] = transform(v, prop.typ, getProps); + }); + Object.getOwnPropertyNames(val).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(props, key)) { + result[key] = transform(val[key], additional, getProps); + } + }); + return result; + } + + if (typ === "any") return val; + if (typ === null) { + if (val === null) return val; + return invalidValue(typ, val); + } + if (typ === false) return invalidValue(typ, val); + while (typeof typ === "object" && typ.ref !== undefined) { + typ = typeMap[typ.ref]; + } + if (Array.isArray(typ)) return transformEnum(typ, val); + if (typeof typ === "object") { + return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) + : invalidValue(typ, val); + } + // Numbers can be parsed by Date but shouldn't be. + if (typ === Date && typeof val !== "number") return transformDate(val); + return transformPrimitive(typ, val); +} + +function cast(val: any, typ: any): T { + return transform(val, typ, jsonToJSProps); +} + +function uncast(val: T, typ: any): any { + return transform(val, typ, jsToJSONProps); +} + +function a(typ: any) { + return { arrayItems: typ }; +} + +function u(...typs: any[]) { + return { unionMembers: typs }; +} + +function o(props: any[], additional: any) { + return { props, additional }; +} + +function m(additional: any) { + return { props: [], additional }; +} + +function r(name: string) { + return { ref: name }; +} + +const typeMap: any = { + "TurnonCommand": o([ + { json: "lumen", js: "lumen", typ: 0 }, + ], "any"), +}; diff --git a/examples/publish subscribe/streetlight/src/tests/testclient/index.ts b/examples/publish subscribe/streetlight/src/tests/testclient/index.ts index d8d97e7a1..6bf56380d 100644 --- a/examples/publish subscribe/streetlight/src/tests/testclient/index.ts +++ b/examples/publish subscribe/streetlight/src/tests/testclient/index.ts @@ -11,14 +11,15 @@ import { Subscription, ServersChangedEvent, SubEvent, - ServerInfo + ServerInfo, + SubscriptionOptions } from 'ts-nats'; import * as streetlightStreetlightIdCommandTurnonChannel from "./testchannels/StreetlightStreetlightIdCommandTurnon"; export {streetlightStreetlightIdCommandTurnonChannel}; import * as streetlightStreetlightIdEventTurnonChannel from "./testchannels/StreetlightStreetlightIdEventTurnon"; export {streetlightStreetlightIdEventTurnonChannel}; -import * as SubscribeToTurnonCommandMessage from "../../messages/SubscribeToTurnonCommand"; -export {SubscribeToTurnonCommandMessage}; +import * as TurnonCommandMessage from "../../messages/TurnonCommand"; +export {TurnonCommandMessage}; import * as AnonymousMessage1Message from "../../messages/AnonymousMessage1"; export {AnonymousMessage1Message}; @@ -59,7 +60,6 @@ export declare interface NatsAsyncApiTestClient { } export class NatsAsyncApiTestClient extends events.EventEmitter{ - public jsonClient?: Client; public stringClient?: Client; @@ -80,9 +80,11 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ return new Promise(async (resolve: () => void, reject: (error: any) => void) => { this.options = this.setDefaultOptions(options); try{ - this.options.payload = Payload.JSON; - this.jsonClient = await connect(this.options); - this.chainEvents(this.jsonClient); + if(!this.jsonClient || this.jsonClient!.isClosed()){ + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); + } resolve(); }catch(e){ reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); @@ -90,12 +92,22 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ }) } + /** + * Returns whether or not any of the clients are closed + */ + isClosed(){ + if (!this.jsonClient || this.jsonClient!.isClosed()){ + return true; + } + } /** * Disconnect all clients from the server */ async disconnect(){ - this.jsonClient!.close() + if(this.jsonClient && !this.jsonClient!.isClosed()){ + this.jsonClient!.close(); + } } private chainEvents(ns: Client){ @@ -202,8 +214,11 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ * Channel for the turn on command which should turn on the streetlight * @param requestMessage The message to publish. */ - public publishToStreetlightStreetlightIdCommandTurnon(requestMessage: SubscribeToTurnonCommandMessage.SubscribeToTurnonCommand - ,streetlight_id: string + public publishToStreetlightStreetlightIdCommandTurnon( + requestMessage: TurnonCommandMessage.TurnonCommand + + ,streetlight_id: string + ): Promise { const nc: Client = this.jsonClient!; if(nc){ @@ -219,16 +234,23 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ /** * Channel for when the streetlight is turned on - * @param onDataCallback Called when message recieved. + * @param onDataCallback Called when message received. */ - public subscribeToStreetlightStreetlightIdEventTurnon(onDataCallback : (err?: NatsTypescriptTemplateError, msg?: AnonymousMessage1Message.AnonymousMessage1, streetlight_id?: string) => void - ,streetlight_id: string - ): Promise { + public subscribeToStreetlightStreetlightIdEventTurnon( + onDataCallback : (err?: NatsTypescriptTemplateError, msg?: AnonymousMessage1Message.AnonymousMessage1, streetlight_id?: string) => void + + ,streetlight_id: string + , + options?: SubscriptionOptions + ): Promise { const nc: Client = this.jsonClient!; if(nc){ - return streetlightStreetlightIdEventTurnonChannel.subscribe(onDataCallback, nc - - ,streetlight_id + return streetlightStreetlightIdEventTurnonChannel.subscribe( + onDataCallback, nc + + ,streetlight_id + , + options ); }else{ return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); diff --git a/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts b/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts index 6040ea8ec..646636ffe 100644 --- a/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts +++ b/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts @@ -1,14 +1,14 @@ -import * as SubscribeToTurnonCommandMessage from '../../../messages/SubscribeToTurnonCommand'; +import * as TurnonCommandMessage from '../../../messages/TurnonCommand'; import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; import {ErrorCode, NatsTypescriptTemplateError} from '../../../NatsTypescriptTemplateError'; import { Hooks } from '../../../hooks'; export function publish( - message: SubscribeToTurnonCommandMessage.SubscribeToTurnonCommand, - nc: Client, + message: TurnonCommandMessage.TurnonCommand, + nc: Client - streetlight_id: string + ,streetlight_id: string ): Promise { return new Promise(async (resolve, reject) => { @@ -21,11 +21,12 @@ try{ dataToSend = hook(dataToSend); } }catch(e){ - reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + const error = NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e); + reject(error); return; } - nc.publish(`streetlight.${streetlight_id}.command.turnon`, dataToSend); + await nc.publish(`streetlight.${streetlight_id}.command.turnon`, dataToSend); resolve(); }catch(e){ reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); diff --git a/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts b/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts index c6d3c174b..58dcfc4f8 100644 --- a/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts +++ b/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts @@ -5,14 +5,15 @@ import {ErrorCode, NatsTypescriptTemplateError} from '../../../NatsTypescriptTem import { Hooks } from '../../../hooks'; export function subscribe( - onDataCallback : (err?: NatsTypescriptTemplateError, msg?: AnonymousMessage1Message.AnonymousMessage1, streetlight_id?: string) => void, - nc: Client, - - streetlight_id: string - + onDataCallback : (err?: NatsTypescriptTemplateError, msg?: AnonymousMessage1Message.AnonymousMessage1, streetlight_id?: string) => void, + nc: Client + + ,streetlight_id: string + , + options?: SubscriptionOptions ): Promise { return new Promise(async (resolve, reject) => { - let subscribeOptions: SubscriptionOptions = {}; + let subscribeOptions: SubscriptionOptions = {... options}; try{ let subscription = nc.subscribe(`streetlight.${streetlight_id}.event.turnon`, (err, msg) => { @@ -21,20 +22,22 @@ export function subscribe( }else{ const unmodifiedChannel = `streetlight.{streetlight_id}.event.turnon` const receivedTopicParameters = { - streetlight_id : msg.subject.slice(unmodifiedChannel.split("${streetlight_id}")[0].length, msg.subject.length-unmodifiedChannel.split("${streetlight_id}")[1].length) - } - try{ - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived: any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - }catch(e){ - reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); - return; + streetlight_id : msg.subject.slice(unmodifiedChannel.split("{streetlight_id}")[0].length, msg.subject.length-unmodifiedChannel.split("{streetlight_id}")[1].length) } - let publishedData = AnonymousMessage1Message.Convert.toAnonymousMessage1(processedDataReceived); - onDataCallback(undefined, publishedData, + +try { + let receivedDataHooks = Hooks.getInstance().getreceivedDataHook(); + var receivedData : any = msg.data; + for(let hook of receivedDataHooks){ + receivedData = hook(receivedData); + } +} catch (e) { + const error = NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e); + reject(error); + return; +} + + onDataCallback(undefined, receivedData, receivedTopicParameters['streetlight_id']); } }, subscribeOptions); diff --git a/examples/request reply/README.md b/examples/request reply/README.md index b6b989405..9355a8fce 100644 --- a/examples/request reply/README.md +++ b/examples/request reply/README.md @@ -5,7 +5,7 @@ This example contains two channels are: -`streetlight/{streetlight_id}/command/turnon` which are for replying to the command `turnon`. The generated client interprets this as the NATS topic `streetlight.{streetlight_id}.command.turnon`. The `{streetlight_id}` is the channel parameter which are not realized before actually subscribing to anything. When a message is recieved on channel `streetlight.1.command.turnon` it can automatically interpret what the `streetlight_id` parameter is. +`streetlight/{streetlight_id}/command/turnon` which are for replying to the command `turnon`. The generated client interprets this as the NATS topic `streetlight.{streetlight_id}.command.turnon`. The `{streetlight_id}` is the channel parameter which are not realized before actually subscribing to anything. When a message is received on channel `streetlight.1.command.turnon` it can automatically interpret what the `streetlight_id` parameter is. `streetlight/{streetlight_id}/event/turnon` which are for requesting another application when the light is acutally turned on. diff --git a/examples/request reply/bin/StreetlightController.js b/examples/request reply/bin/StreetlightController.js new file mode 100644 index 000000000..958289245 --- /dev/null +++ b/examples/request reply/bin/StreetlightController.js @@ -0,0 +1,46 @@ +const {AvailableEvents, TestClient, GeneralReplyMessage, TurnonCommandMessage} = require("nats-client"); +const natsTestClient = new TestClient.NatsAsyncApiTestClient(); +const streetlight = "test_1"; +const stopApplication = () => { + setTimeout(() => { + natsTestClient.disconnect(); + }, 1000); +} +natsTestClient.on(AvailableEvents.connect, async (connection, serverURL, info) => { + console.log("StreetLightController: connected"); + + //Listen for when the streetlight turns on. + natsTestClient.replyToStreetlightStreetlightIdEventTurnon((err, msg, streetlight_id) => { + return new Promise((resolve, reject) => { + console.log(`StreetLightController: Received request that streetlight ${streetlight_id} is turned on message was: ${JSON.stringify(msg)}`); + const replyMessage = new GeneralReplyMessage.Convert.toGeneralReply(JSON.stringify({status_code: 200, status_message: "Ok"})); + resolve(replyMessage); + stopApplication(); + }); + }, (err) => { + console.log("StreetLightController: Could not setup reply"); + console.log(err); + }, streetlight); +}); + +async function connect(){ + console.log("Connecting all client"); + try{ + await natsTestClient.connectToHost("localhost:4222", {reconnectTimeWait: 1000, reconnect: true, waitOnFirstConnect: true, maxReconnectAttempts: -1}); + }catch(e){ + console.log("Could not connect client") + console.log(e); + } +} +connect(); + +// Wait a bit before sending the request. +const timeoutFunction = setTimeout(async () => { + if(!natsTestClient.isClosed()){ + clearTimeout(timeoutFunction); + console.log(`StreetLightController: Requesting to turn on the streetlight`) + const requestMessage = TurnonCommandMessage.Convert.toTurnonCommand(JSON.stringify({lumen: 100})); + const replyMessage = await natsTestClient.requestStreetlightStreetlightIdCommandTurnon(requestMessage, streetlight); + console.log(`StreetLightController: got reply from our request to streetlight ${streetlight}, response message was: ${JSON.stringify(replyMessage)}`) + } +}, 5000); \ No newline at end of file diff --git a/examples/request reply/bin/streetlight.js b/examples/request reply/bin/streetlight.js new file mode 100644 index 000000000..bea45ce28 --- /dev/null +++ b/examples/request reply/bin/streetlight.js @@ -0,0 +1,49 @@ +const {AvailableEvents, NatsAsyncApiClient, GeneralReplyMessage, AnonymousMessage3Message} = require("nats-client"); +const natsClient = new NatsAsyncApiClient(); +const streetlight = "test_1"; +const stopApplication = () => { + natsClient.disconnect(); +} +natsClient.on(AvailableEvents.connect, (connection, serverURL, info) => { + console.log("NatsAsyncApiClient connected"); + + //Listen for when the controller want to turn on the streetlight + natsClient.replyToStreetlightStreetlightIdCommandTurnon( + (err, msg, streetlight_id) => { + return new Promise(async (resolve, reject) => { + console.log(`NatsClient: Received request to turn on the streetlight ${streetlight_id}, request message was: ${JSON.stringify(msg)}`) + const replyMessage = new GeneralReplyMessage.Convert.toGeneralReply(JSON.stringify({status_code: 200, status_message: "Ok"})); + resolve(replyMessage); + + //lets request that the light is turned on. + const request = async (lumen) => { + try{ + console.log(`NatsClient: requesting that the light is turned on`) + const newRequestMessage = new AnonymousMessage3Message.Convert.toAnonymousMessage3(JSON.stringify({lumen: lumen})); + const replyFromRequest = await natsClient.requestStreetlightStreetlightIdEventTurnon(newRequestMessage, streetlight); + console.log(`NatsClient: received reply to our request. Reply was: ${JSON.stringify(replyFromRequest)}`); + stopApplication(); + }catch(e){ + console.log("NatsClient: Something went wrong when requesting the event StreetlightStreetlightIdEventTurnon"); + console.log(e); + } + } + request(msg.lumen); + }); + }, (err) => { + console.log("NatsClient: Could not setup reply"); + console.log(err); + }, + streetlight + ); +}); +async function connect(){ + console.log("Connecting client"); + try{ + await natsClient.connectToHost("localhost:4222", {reconnectTimeWait: 1000, reconnect: true, waitOnFirstConnect: true, maxReconnectAttempts: -1}); + }catch(e){ + console.log("Could not connect client") + console.log(e); + } +} +connect(); diff --git a/examples/request reply/generate.sh b/examples/request reply/generate.sh index 56e9bcac5..26222ece6 100644 --- a/examples/request reply/generate.sh +++ b/examples/request reply/generate.sh @@ -1,3 +1,3 @@ #!/bin/sh -ag --install --output "./streetlight" "./streetlight.json" "../../" --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" \ No newline at end of file +ag --install --output "./streetlight" "./streetlight.json" "../../" --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" && cd ./streetlight && npm i && npm run build && cd .. \ No newline at end of file diff --git a/examples/request reply/package-lock.json b/examples/request reply/package-lock.json new file mode 100644 index 000000000..e7d445d33 --- /dev/null +++ b/examples/request reply/package-lock.json @@ -0,0 +1,1346 @@ +{ + "name": "request-reply", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "concurrently": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.2.0.tgz", + "integrity": "sha512-XxcDbQ4/43d6CxR7+iV8IZXhur4KbmEJk1CetVMUqCy34z9l0DkszbY+/9wvmSnToTej0SYomc2WSRH+L0zVJw==", + "requires": { + "chalk": "^2.4.2", + "date-fns": "^2.0.1", + "lodash": "^4.17.15", + "read-pkg": "^4.0.1", + "rxjs": "^6.5.2", + "spawn-command": "^0.0.2-1", + "supports-color": "^6.1.0", + "tree-kill": "^1.2.2", + "yargs": "^13.3.0" + } + }, + "date-fns": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.15.0.tgz", + "integrity": "sha512-ZCPzAMJZn3rNUvvQIMlXhDr4A+Ar07eLeGsGREoWU19a3Pqf5oYa+ccd+B3F6XVtQY6HANMFdOQ8A+ipFnvJdQ==" + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + }, + "nats-client": { + "version": "file:streetlight", + "requires": { + "@types/klaw-sync": "^6.0.0", + "@types/node": "13.9.5", + "ts-nats": "1.2.4", + "ts-nkeys": "1.0.16", + "typescript": "3.4.3" + }, + "dependencies": { + "@types/chai": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz", + "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==" + }, + "@types/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@types/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-Ibfb2jgpjYUxnl7RSVvUzOrv/vhkTVKEfPwQf9ZlDDsSyWVDp/2JtTBxO4eRrKBYtxc3cZQabdR38i8R0o1uww==", + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", + "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==" + }, + "@types/node": { + "version": "13.9.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.5.tgz", + "integrity": "sha512-hkzMMD3xu6BrJpGVLeQ3htQQNAcOrJjX7WFmtK8zWQpz2UJf13LCFF2ALA7c9OVdvc2vQJeDdjfR35M0sBCxvw==" + }, + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" + }, + "chokidar": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "requires": { + "type-detect": "^4.0.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "requires": { + "is-buffer": "~2.0.3" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "requires": { + "chalk": "^2.4.2" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "mocha": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", + "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "chokidar": "3.3.0", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "3.0.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.5", + "ms": "2.1.1", + "node-environment-flags": "1.0.6", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "nuid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/nuid/-/nuid-1.1.4.tgz", + "integrity": "sha512-PXiYyHhGfrq8H4g5HyC8enO1lz6SBe5z6x1yx/JG4tmADzDGJVQy3l1sRf3VtEvPsN8dGn9hRFRwDKWL62x0BA==" + }, + "object-inspect": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=" + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + }, + "readdirp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "requires": { + "picomatch": "^2.0.4" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "ts-nats": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/ts-nats/-/ts-nats-1.2.4.tgz", + "integrity": "sha512-bIC+PlwHplRqhooa9kE+QPcQ9RPGUXD2ruvdf6LoFpP6MjE6exVoRhYSydm0e5wk7VfuXpTbH1NoopTKHwlOKA==", + "requires": { + "nuid": "^1.1.0", + "ts-nkeys": "^1.0.12" + } + }, + "ts-nkeys": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/ts-nkeys/-/ts-nkeys-1.0.16.tgz", + "integrity": "sha512-1qrhAlavbm36wtW+7NtKOgxpzl+70NTF8xlz9mEhiA5zHMlMxjj3sEVKWm3pGZhHXE0Q3ykjrj+OSRVaYw+Dqg==", + "requires": { + "tweetnacl": "^1.0.3" + } + }, + "ts-node": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + } + } + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "typescript": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.3.tgz", + "integrity": "sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + } + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "read-pkg": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", + "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", + "requires": { + "normalize-package-data": "^2.3.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "rxjs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz", + "integrity": "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==", + "requires": { + "tslib": "^1.9.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=" + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/examples/request reply/package.json b/examples/request reply/package.json new file mode 100644 index 000000000..959fdca05 --- /dev/null +++ b/examples/request reply/package.json @@ -0,0 +1,14 @@ +{ + "name": "request-reply", + "version": "1.0.0", + "description": "Request and reply example", + "scripts": { + "start": "concurrently \"node ./bin/streetlight\" \"node ./bin/streetlightController\"" + }, + "dependencies": { + "nats-client": "file:./streetlight", + "concurrently": "5.2.0" + }, + "author": "", + "license": "ISC" +} diff --git a/examples/request reply/streetlight.json b/examples/request reply/streetlight.json index e13794936..101711a36 100644 --- a/examples/request reply/streetlight.json +++ b/examples/request reply/streetlight.json @@ -24,7 +24,7 @@ "publish": { "operationId": "Listen when to turn on the streetlight", "message": { - "name": "subscribeToTurnonCommand", + "name": "turnonCommand", "payload": { "type": "object", "required": ["lumen"], diff --git a/examples/request reply/streetlight/package.json b/examples/request reply/streetlight/package.json index 66239b020..395761267 100644 --- a/examples/request reply/streetlight/package.json +++ b/examples/request reply/streetlight/package.json @@ -1,6 +1,4 @@ { - - "name": "streetlight", "description": "", "version": "1.0.0", @@ -13,17 +11,17 @@ "test": "mocha -r ts-node/register tests/**/*.spec.ts" }, "dependencies": { - "@types/klaw-sync": "^6.0.0", - "@types/node": "13.9.5", + "@types/klaw-sync": "^6.0.0", + "@types/node": "13.9.5", "ts-nats": "1.2.4", "typescript": "3.4.3", - "ts-nkeys":"1.0.16" + "ts-nkeys": "1.0.16" }, - "devDependencies": { - "@types/chai": "^4.2.11", - "@types/mocha": "^7.0.2", - "chai": "^4.2.0", - "mocha": "^7.1.1", - "ts-node": "^8.8.1" - } + "devDependencies": { + "@types/chai": "^4.2.11", + "@types/mocha": "^7.0.2", + "chai": "^4.2.0", + "mocha": "^7.1.1", + "ts-node": "^8.8.1" + } } diff --git a/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts index c8730331f..618a56e89 100644 --- a/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts +++ b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts @@ -1,21 +1,23 @@ -import * as SubscribeToTurnonCommandMessage from '../messages/SubscribeToTurnonCommand' +import * as TurnonCommandMessage from '../messages/TurnonCommand' import * as GeneralReplyMessage from '../messages/GeneralReply' import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; import {ErrorCode, NatsTypescriptTemplateError} from '../NatsTypescriptTemplateError'; import { Hooks } from '../hooks'; export function reply( - onRequest: (err?: NatsTypescriptTemplateError, msg?: SubscribeToTurnonCommandMessage.SubscribeToTurnonCommand, streetlight_id?: string) =>Promise, - onReplyError: (err: NatsTypescriptTemplateError) => void, - nc: Client, - - streetlight_id: string - + onRequest: (err?: NatsTypescriptTemplateError, msg?: TurnonCommandMessage.TurnonCommand, streetlight_id?: string) =>Promise, + onReplyError: (err: NatsTypescriptTemplateError) => void, + nc: Client + + ,streetlight_id: string + , + options?: SubscriptionOptions ): Promise { return new Promise(async (resolve, reject) => { try { - let subscribeOptions: SubscriptionOptions = {}; + let subscribeOptions: SubscriptionOptions = {... options}; + subscribeOptions.max = 1; let subscription = nc.subscribe(`streetlight.${streetlight_id}.command.turnon`,async (err, msg) => { if (err) { @@ -27,18 +29,19 @@ export function reply( } try { - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + let receivedDataHooks = Hooks.getInstance().getreceivedDataHook(); var receivedData : any = msg.data; for(let hook of receivedDataHooks){ receivedData = hook(receivedData); } } catch (e) { - onReplyError(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)) + const error = NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e); + onReplyError(error); return; } - let requestData = SubscribeToTurnonCommandMessage.Convert.toSubscribeToTurnonCommand(receivedData); - let message =await onRequest(undefined, requestData, + + let message =await onRequest(undefined, receivedData, receivedTopicParameters['streetlight_id']); if (msg.reply) { @@ -50,11 +53,13 @@ try{ dataToSend = hook(dataToSend); } }catch(e){ - reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + const error = NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e); + onReplyError(error) return; } - nc.publish(`streetlight.${streetlight_id}.command.turnon`, dataToSend); + + await nc.publish(msg.reply, dataToSend); } else { let error = new NatsTypescriptTemplateError('Expected request to need a reply, did not..', '000'); onReplyError(error) diff --git a/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts index 6e6b52866..35d4946c9 100644 --- a/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts +++ b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts @@ -7,9 +7,9 @@ import { Hooks } from '../hooks'; export function request( message: AnonymousMessage3Message.AnonymousMessage3, - nc: Client, + nc: Client - streetlight_id: string + ,streetlight_id: string ): Promise { return new Promise(async (resolve, reject) => { @@ -24,10 +24,12 @@ try{ dataToSend = hook(dataToSend); } }catch(e){ - reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + const error = NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e); + reject(error); return; } + msg = await nc.request(`streetlight.${streetlight_id}.event.turnon`, undefined, dataToSend) }catch(e){ reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); @@ -35,18 +37,18 @@ try{ } try { - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + let receivedDataHooks = Hooks.getInstance().getreceivedDataHook(); var receivedData : any = msg.data; for(let hook of receivedDataHooks){ receivedData = hook(receivedData); } } catch (e) { - reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + const error = NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e); + reject(error); return; } - let recievedData = GeneralReplyMessage.Convert.toGeneralReply(receivedData); - resolve(recievedData); + resolve(receivedData); }) } diff --git a/examples/request reply/streetlight/src/hooks.ts b/examples/request reply/streetlight/src/hooks.ts index 321b9085c..d4528c513 100644 --- a/examples/request reply/streetlight/src/hooks.ts +++ b/examples/request reply/streetlight/src/hooks.ts @@ -1,20 +1,20 @@ export enum AvailableHooks { - RecievedData = 'RecievedData', + receivedData = 'receivedData', BeforeSendingData = 'BeforeSendingData' } -export type RecievedDataHook = (receivedData: any) => string; +export type receivedDataHook = (receivedData: any) => string; export type BeforeSendingDataHook = (messageToSend: any) => string; export class Hooks { private static instance: Hooks; private hooks: { BeforeSendingData: BeforeSendingDataHook[]; - RecievedData: RecievedDataHook[]; + receivedData: receivedDataHook[]; }; private constructor() { this.hooks = { BeforeSendingData: [], - RecievedData: [] + receivedData: [] } } public static getInstance(): Hooks { @@ -40,15 +40,15 @@ export class Hooks { * Register a hook for BeforeSendingData * @param hook */ - public async registerRecievedData(hook: RecievedDataHook) { - this.hooks[AvailableHooks.RecievedData] - ? this.hooks[AvailableHooks.RecievedData].push(hook) + public async registerreceivedData(hook: receivedDataHook) { + this.hooks[AvailableHooks.receivedData] + ? this.hooks[AvailableHooks.receivedData].push(hook) : [hook]; } - public getRecievedDataHook(): RecievedDataHook[] { - return this.hooks[AvailableHooks.RecievedData]; + public getreceivedDataHook(): receivedDataHook[] { + return this.hooks[AvailableHooks.receivedData]; } public getBeforeSendingDataHook(): BeforeSendingDataHook[] { diff --git a/examples/request reply/streetlight/src/index.ts b/examples/request reply/streetlight/src/index.ts index fa4aeea83..9bb17f463 100644 --- a/examples/request reply/streetlight/src/index.ts +++ b/examples/request reply/streetlight/src/index.ts @@ -3,8 +3,8 @@ import {fromSeed} from 'ts-nkeys'; -import {AvailableHooks, RecievedDataHook, BeforeSendingDataHook, Hooks} from './hooks'; -export {AvailableHooks, RecievedDataHook, BeforeSendingDataHook, Hooks} +import {AvailableHooks, receivedDataHook, BeforeSendingDataHook, Hooks} from './hooks'; +export {AvailableHooks, receivedDataHook, BeforeSendingDataHook, Hooks} import * as TestClient from './tests/testclient/'; export { TestClient }; import {ErrorCode, NatsTypescriptTemplateError} from './NatsTypescriptTemplateError'; @@ -18,14 +18,17 @@ import { Subscription, ServersChangedEvent, SubEvent, - ServerInfo + ServerInfo, + SubscriptionOptions } from 'ts-nats'; + +export {Client, ServerInfo, ServersChangedEvent, SubEvent} import * as streetlightStreetlightIdCommandTurnonChannel from "./channels/StreetlightStreetlightIdCommandTurnon"; export {streetlightStreetlightIdCommandTurnonChannel}; import * as streetlightStreetlightIdEventTurnonChannel from "./channels/StreetlightStreetlightIdEventTurnon"; export {streetlightStreetlightIdEventTurnonChannel}; -import * as SubscribeToTurnonCommandMessage from "./messages/SubscribeToTurnonCommand"; -export {SubscribeToTurnonCommandMessage}; +import * as TurnonCommandMessage from "./messages/TurnonCommand"; +export {TurnonCommandMessage}; import * as GeneralReplyMessage from "./messages/GeneralReply"; export {GeneralReplyMessage}; import * as AnonymousMessage3Message from "./messages/AnonymousMessage3"; @@ -87,9 +90,11 @@ export class NatsAsyncApiClient extends events.EventEmitter{ return new Promise(async (resolve: () => void, reject: (error: any) => void) => { this.options = this.setDefaultOptions(options); try{ - this.options.payload = Payload.JSON; - this.jsonClient = await connect(this.options); - this.chainEvents(this.jsonClient); + if(!this.jsonClient || this.jsonClient!.isClosed()){ + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); + } resolve(); }catch(e){ reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); @@ -97,12 +102,22 @@ export class NatsAsyncApiClient extends events.EventEmitter{ }) } + /** + * Returns whether or not any of the clients are closed + */ + isClosed(){ + if (!this.jsonClient || this.jsonClient!.isClosed()){ + return true; + } + } /** * Disconnect all clients from the server */ async disconnect(){ - this.jsonClient!.close() + if(this.jsonClient && !this.jsonClient!.isClosed()){ + this.jsonClient!.close(); + } } private chainEvents(ns: Client){ @@ -207,23 +222,31 @@ export class NatsAsyncApiClient extends events.EventEmitter{ /** * Channel for the turn on command which should turn on the streetlight - * @param onRequest Called when request recieved. + * @param onRequest Called when request received. * @param onReplyError Called when it was not possible to send the reply. */ public replyToStreetlightStreetlightIdCommandTurnon( - onRequest : ( - err?: NatsTypescriptTemplateError, - msg?: SubscribeToTurnonCommandMessage.SubscribeToTurnonCommand,streetlight_id?: string - ) =>Promise, onReplyError : (err: NatsTypescriptTemplateError) => void - - ,streetlight_id: string - ): Promise { + onRequest : ( + err?: NatsTypescriptTemplateError, + msg?: TurnonCommandMessage.TurnonCommand,streetlight_id?: string + ) =>Promise, + onReplyError : (err: NatsTypescriptTemplateError) => void + + ,streetlight_id: string + , + options?: SubscriptionOptions + ): Promise { const nc: Client = this.jsonClient!; if(nc){ - return streetlightStreetlightIdCommandTurnonChannel.reply(onRequest, onReplyError, nc + return streetlightStreetlightIdCommandTurnonChannel.reply( + onRequest, + onReplyError, + nc ,streetlight_id + , + options ); }else{ return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); @@ -235,15 +258,20 @@ export class NatsAsyncApiClient extends events.EventEmitter{ * Channel for when the streetlight is turned on * @param requestMessage The request message to send. */ - public requestStreetlightStreetlightIdEventTurnon(requestMessage:AnonymousMessage3Message.AnonymousMessage3 - - ,streetlight_id: string + public requestStreetlightStreetlightIdEventTurnon( + requestMessage:AnonymousMessage3Message.AnonymousMessage3 + + ,streetlight_id: string + ): Promise { const nc: Client = this.jsonClient!; if(nc){ - return streetlightStreetlightIdEventTurnonChannel.request(requestMessage, nc - - ,streetlight_id + return streetlightStreetlightIdEventTurnonChannel.request( + requestMessage, + nc + + ,streetlight_id + ); }else{ return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); diff --git a/examples/request reply/streetlight/src/messages/TurnonCommand.ts b/examples/request reply/streetlight/src/messages/TurnonCommand.ts new file mode 100644 index 000000000..27c30978c --- /dev/null +++ b/examples/request reply/streetlight/src/messages/TurnonCommand.ts @@ -0,0 +1,162 @@ +// To parse this data: +// +// import { Convert, TurnonCommand } from "./file"; +// +// const turnonCommand = Convert.toTurnonCommand(json); +// +// These functions will throw an error if the JSON doesn't +// match the expected interface, even if the JSON is valid. + +export interface TurnonCommand { + /** + * How bright should the light be. + */ + lumen: number; +} + +// Converts JSON strings to/from your types +// and asserts the results of JSON.parse at runtime +export class Convert { + public static toTurnonCommand(json: string): TurnonCommand { + return cast(JSON.parse(json), r("TurnonCommand")); + } + + public static turnonCommandToJson(value: TurnonCommand): string { + return JSON.stringify(uncast(value, r("TurnonCommand")), null, 2); + } +} + +function invalidValue(typ: any, val: any): never { + throw Error(`Invalid value ${JSON.stringify(val)} for type ${JSON.stringify(typ)}`); +} + +function jsonToJSProps(typ: any): any { + if (typ.jsonToJS === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ }); + typ.jsonToJS = map; + } + return typ.jsonToJS; +} + +function jsToJSONProps(typ: any): any { + if (typ.jsToJSON === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ }); + typ.jsToJSON = map; + } + return typ.jsToJSON; +} + +function transform(val: any, typ: any, getProps: any): any { + function transformPrimitive(typ: string, val: any): any { + if (typeof typ === typeof val) return val; + return invalidValue(typ, val); + } + + function transformUnion(typs: any[], val: any): any { + // val must validate against one typ in typs + const l = typs.length; + for (let i = 0; i < l; i++) { + const typ = typs[i]; + try { + return transform(val, typ, getProps); + } catch (_) {} + } + return invalidValue(typs, val); + } + + function transformEnum(cases: string[], val: any): any { + if (cases.indexOf(val) !== -1) return val; + return invalidValue(cases, val); + } + + function transformArray(typ: any, val: any): any { + // val must be an array with no invalid elements + if (!Array.isArray(val)) return invalidValue("array", val); + return val.map(el => transform(el, typ, getProps)); + } + + function transformDate(val: any): any { + if (val === null) { + return null; + } + const d = new Date(val); + if (isNaN(d.valueOf())) { + return invalidValue("Date", val); + } + return d; + } + + function transformObject(props: { [k: string]: any }, additional: any, val: any): any { + if (val === null || typeof val !== "object" || Array.isArray(val)) { + return invalidValue("object", val); + } + const result: any = {}; + Object.getOwnPropertyNames(props).forEach(key => { + const prop = props[key]; + const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined; + result[prop.key] = transform(v, prop.typ, getProps); + }); + Object.getOwnPropertyNames(val).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(props, key)) { + result[key] = transform(val[key], additional, getProps); + } + }); + return result; + } + + if (typ === "any") return val; + if (typ === null) { + if (val === null) return val; + return invalidValue(typ, val); + } + if (typ === false) return invalidValue(typ, val); + while (typeof typ === "object" && typ.ref !== undefined) { + typ = typeMap[typ.ref]; + } + if (Array.isArray(typ)) return transformEnum(typ, val); + if (typeof typ === "object") { + return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) + : invalidValue(typ, val); + } + // Numbers can be parsed by Date but shouldn't be. + if (typ === Date && typeof val !== "number") return transformDate(val); + return transformPrimitive(typ, val); +} + +function cast(val: any, typ: any): T { + return transform(val, typ, jsonToJSProps); +} + +function uncast(val: T, typ: any): any { + return transform(val, typ, jsToJSONProps); +} + +function a(typ: any) { + return { arrayItems: typ }; +} + +function u(...typs: any[]) { + return { unionMembers: typs }; +} + +function o(props: any[], additional: any) { + return { props, additional }; +} + +function m(additional: any) { + return { props: [], additional }; +} + +function r(name: string) { + return { ref: name }; +} + +const typeMap: any = { + "TurnonCommand": o([ + { json: "lumen", js: "lumen", typ: 0 }, + ], "any"), +}; diff --git a/examples/request reply/streetlight/src/tests/testclient/index.ts b/examples/request reply/streetlight/src/tests/testclient/index.ts index 51d80c268..d6eee442e 100644 --- a/examples/request reply/streetlight/src/tests/testclient/index.ts +++ b/examples/request reply/streetlight/src/tests/testclient/index.ts @@ -11,14 +11,15 @@ import { Subscription, ServersChangedEvent, SubEvent, - ServerInfo + ServerInfo, + SubscriptionOptions } from 'ts-nats'; import * as streetlightStreetlightIdCommandTurnonChannel from "./testchannels/StreetlightStreetlightIdCommandTurnon"; export {streetlightStreetlightIdCommandTurnonChannel}; import * as streetlightStreetlightIdEventTurnonChannel from "./testchannels/StreetlightStreetlightIdEventTurnon"; export {streetlightStreetlightIdEventTurnonChannel}; -import * as SubscribeToTurnonCommandMessage from "../../messages/SubscribeToTurnonCommand"; -export {SubscribeToTurnonCommandMessage}; +import * as TurnonCommandMessage from "../../messages/TurnonCommand"; +export {TurnonCommandMessage}; import * as GeneralReplyMessage from "../../messages/GeneralReply"; export {GeneralReplyMessage}; import * as AnonymousMessage3Message from "../../messages/AnonymousMessage3"; @@ -61,7 +62,6 @@ export declare interface NatsAsyncApiTestClient { } export class NatsAsyncApiTestClient extends events.EventEmitter{ - public jsonClient?: Client; public stringClient?: Client; @@ -82,9 +82,11 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ return new Promise(async (resolve: () => void, reject: (error: any) => void) => { this.options = this.setDefaultOptions(options); try{ - this.options.payload = Payload.JSON; - this.jsonClient = await connect(this.options); - this.chainEvents(this.jsonClient); + if(!this.jsonClient || this.jsonClient!.isClosed()){ + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); + } resolve(); }catch(e){ reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); @@ -92,12 +94,22 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ }) } + /** + * Returns whether or not any of the clients are closed + */ + isClosed(){ + if (!this.jsonClient || this.jsonClient!.isClosed()){ + return true; + } + } /** * Disconnect all clients from the server */ async disconnect(){ - this.jsonClient!.close() + if(this.jsonClient && !this.jsonClient!.isClosed()){ + this.jsonClient!.close(); + } } private chainEvents(ns: Client){ @@ -204,15 +216,20 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ * Channel for the turn on command which should turn on the streetlight * @param requestMessage The request message to send. */ - public requestStreetlightStreetlightIdCommandTurnon(requestMessage:GeneralReplyMessage.GeneralReply - - ,streetlight_id: string - ): Promise { + public requestStreetlightStreetlightIdCommandTurnon( + requestMessage:GeneralReplyMessage.GeneralReply + + ,streetlight_id: string + + ): Promise { const nc: Client = this.jsonClient!; if(nc){ - return streetlightStreetlightIdCommandTurnonChannel.request(requestMessage, nc - - ,streetlight_id + return streetlightStreetlightIdCommandTurnonChannel.request( + requestMessage, + nc + + ,streetlight_id + ); }else{ return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); @@ -222,23 +239,31 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ /** * Channel for when the streetlight is turned on - * @param onRequest Called when request recieved. + * @param onRequest Called when request received. * @param onReplyError Called when it was not possible to send the reply. */ public replyToStreetlightStreetlightIdEventTurnon( - onRequest : ( - err?: NatsTypescriptTemplateError, - msg?: GeneralReplyMessage.GeneralReply,streetlight_id?: string - ) =>Promise, onReplyError : (err: NatsTypescriptTemplateError) => void - - ,streetlight_id: string - ): Promise { + onRequest : ( + err?: NatsTypescriptTemplateError, + msg?: GeneralReplyMessage.GeneralReply,streetlight_id?: string + ) =>Promise, + onReplyError : (err: NatsTypescriptTemplateError) => void + + ,streetlight_id: string + , + options?: SubscriptionOptions + ): Promise { const nc: Client = this.jsonClient!; if(nc){ - return streetlightStreetlightIdEventTurnonChannel.reply(onRequest, onReplyError, nc + return streetlightStreetlightIdEventTurnonChannel.reply( + onRequest, + onReplyError, + nc ,streetlight_id + , + options ); }else{ return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); diff --git a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts index 57a450dfe..869c44d94 100644 --- a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts +++ b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts @@ -1,5 +1,5 @@ -import * as SubscribeToTurnonCommandMessage from '../../../messages/SubscribeToTurnonCommand'; +import * as TurnonCommandMessage from '../../../messages/TurnonCommand'; import * as GeneralReplyMessage from '../../../messages/GeneralReply'; import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; import {ErrorCode, NatsTypescriptTemplateError} from '../../../NatsTypescriptTemplateError'; @@ -7,11 +7,11 @@ import { Hooks } from '../../../hooks'; export function request( message: GeneralReplyMessage.GeneralReply, - nc: Client, + nc: Client - streetlight_id: string + ,streetlight_id: string - ): Promise { + ): Promise { return new Promise(async (resolve, reject) => { let msg; @@ -24,10 +24,12 @@ try{ dataToSend = hook(dataToSend); } }catch(e){ - reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + const error = NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e); + reject(error); return; } + msg = await nc.request(`streetlight.${streetlight_id}.command.turnon`, undefined, dataToSend) }catch(e){ reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); @@ -35,18 +37,18 @@ try{ } try { - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + let receivedDataHooks = Hooks.getInstance().getreceivedDataHook(); var receivedData : any = msg.data; for(let hook of receivedDataHooks){ receivedData = hook(receivedData); } } catch (e) { - reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + const error = NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e); + reject(error); return; } - let recievedData = SubscribeToTurnonCommandMessage.Convert.toSubscribeToTurnonCommand(receivedData); - resolve(recievedData); + resolve(receivedData); }) } diff --git a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts index 6366fa6f8..21e2cd499 100644 --- a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts +++ b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts @@ -6,16 +6,18 @@ import {ErrorCode, NatsTypescriptTemplateError} from '../../../NatsTypescriptTem import { Hooks } from '../../../hooks'; export function reply( - onRequest: (err?: NatsTypescriptTemplateError, msg?: GeneralReplyMessage.GeneralReply, streetlight_id?: string) =>Promise, - onReplyError: (err: NatsTypescriptTemplateError) => void, - nc: Client, - - streetlight_id: string - + onRequest: (err?: NatsTypescriptTemplateError, msg?: GeneralReplyMessage.GeneralReply, streetlight_id?: string) =>Promise, + onReplyError: (err: NatsTypescriptTemplateError) => void, + nc: Client + + ,streetlight_id: string + , + options?: SubscriptionOptions ): Promise { return new Promise(async (resolve, reject) => { try { - let subscribeOptions: SubscriptionOptions = {}; + let subscribeOptions: SubscriptionOptions = {... options}; + subscribeOptions.max = 1; let subscription = nc.subscribe(`streetlight.${streetlight_id}.event.turnon`,async (err, msg) => { if (err) { @@ -27,18 +29,19 @@ export function reply( } try { - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + let receivedDataHooks = Hooks.getInstance().getreceivedDataHook(); var receivedData : any = msg.data; for(let hook of receivedDataHooks){ receivedData = hook(receivedData); } } catch (e) { - onReplyError(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)) + const error = NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e); + onReplyError(error); return; } - let requestData = GeneralReplyMessage.Convert.toGeneralReply(receivedData); - let message =await onRequest(undefined, requestData, + + let message =await onRequest(undefined, receivedData, receivedTopicParameters['streetlight_id']); if (msg.reply) { @@ -50,11 +53,13 @@ try{ dataToSend = hook(dataToSend); } }catch(e){ - reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + const error = NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e); + onReplyError(error) return; } - nc.publish(`streetlight.${streetlight_id}.event.turnon`, dataToSend); + + await nc.publish(msg.reply, dataToSend); } else { let error = new NatsTypescriptTemplateError('Expected request to need a reply, did not..', '000'); onReplyError(error) diff --git a/partials/channel/OnReceivingData.njk b/partials/channel/OnReceivingData.njk index a7ab51016..c37da654d 100644 --- a/partials/channel/OnReceivingData.njk +++ b/partials/channel/OnReceivingData.njk @@ -1,18 +1,30 @@ -{% macro OnReceivingData(promisfyErrors) %} +{% macro OnReceivingData(promisfyErrors, message, defaultContentType) %} try { - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); + let receivedDataHooks = Hooks.getInstance().getreceivedDataHook(); var receivedData : any = msg.data; for(let hook of receivedDataHooks){ receivedData = hook(receivedData); } + {%- if message.contentType() | isBinaryPayload(defaultContentType) %} + if(receivedDataHooks.length == 0 ){ + let error = new NatsTypescriptTemplateError('Missing hooks to convert binary data', '000'); + onReplyError(error); + return; + } + {%- endif %} + {%- if message.contentType() | isStringPayload(defaultContentType) %} + if(receivedDataHooks.length == 0){ + receivedData = {{message.uid() | pascalCase}}Message.Convert.to{{message.uid() | pascalCase}}(receivedData); + } + {%- endif %} } catch (e) { + const error = NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e); {%- if promisfyErrors == true %} - reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); - return; + reject(error); {%- else %} - onReplyError(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)) - return; + onReplyError(error); {%- endif %} + return; } {% endmacro %} diff --git a/partials/channel/OnSendingData.njk b/partials/channel/OnSendingData.njk index 774d21a1d..95f9727a3 100644 --- a/partials/channel/OnSendingData.njk +++ b/partials/channel/OnSendingData.njk @@ -1,13 +1,30 @@ -{% macro OnSendingData() %} +{% macro OnSendingData(promisfyErrors, message, defaultContentType) %} try{ let beforeSendingHooks = Hooks.getInstance().getBeforeSendingDataHook(); var dataToSend : any = message; for(let hook of beforeSendingHooks){ dataToSend = hook(dataToSend); } + {%- if message.contentType() | isBinaryPayload(defaultContentType) %} + if(receivedDataHooks.length == 0 ){ + let error = new NatsTypescriptTemplateError('Missing hooks to convert binary data', '000'); + onReplyError(error); + return; + } + {%- endif %} + {%- if message.contentType() | isStringPayload(defaultContentType) %} + if(receivedDataHooks.length == 0 ){ + dataToSend = {{message.uid() | pascalCase}}Message.Convert.{{message.uid() | camelCase}}ToJson(dataToSend); + } + {%- endif %} }catch(e){ - reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); + const error = NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e); + {%- if promisfyErrors == true %} + reject(error); + {%- else %} + onReplyError(error) + {%- endif %} return; } {% endmacro %} diff --git a/partials/channel/Publish.njk b/partials/channel/Publish.njk index 7091701fa..83bca2ab2 100644 --- a/partials/channel/Publish.njk +++ b/partials/channel/Publish.njk @@ -1,20 +1,20 @@ {%- from "./OnSendingData.njk" import OnSendingData %} -{% macro publish(channelName, channelParameters, publishMessage, server) %} +{% macro publish(channelName, channelParameters, publishMessage, server, defaultContentType) %} export function publish( message: {{publishMessage | getMessageType}}, - nc: Client, + nc: Client {% if channelParameters | length %} - {{channelParameters | realizeParametersForChannel}} + ,{{channelParameters | realizeParametersForChannel}} {% endif %} ): Promise { return new Promise(async (resolve, reject) => { try{ {%- if publishMessage.payload() | messageHasNotNullPayload %} - {{OnSendingData()}} - nc.publish({{channelParameters | realizeChannelName(channelName)}}, dataToSend); + {{OnSendingData(true, publishMessage, defaultContentType)}} + await nc.publish({{channelParameters | realizeChannelName(channelName)}}, dataToSend); {%- else %} - nc.publish({{channelParameters | realizeChannelName(channelName)}}, null); + await nc.publish({{channelParameters | realizeChannelName(channelName)}}, null); {%- endif %} resolve(); }catch(e){ diff --git a/partials/channel/Reply.njk b/partials/channel/Reply.njk index 0456101f6..56675efa5 100644 --- a/partials/channel/Reply.njk +++ b/partials/channel/Reply.njk @@ -1,29 +1,27 @@ {%- from "./OnSendingData.njk" import OnSendingData %} {%- from "./OnReceivingData.njk" import OnReceivingData %} -{% macro reply(channelName, channelParameters, replyMessage, recieveMessage, server, params) %} +{% macro reply(channelName, channelParameters, replyMessage, receiveMessage, server, params, defaultContentType) %} export function reply( - onRequest: (err?: NatsTypescriptTemplateError, msg?: {{recieveMessage | getMessageType}}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => - {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{replyMessage | getMessageType}}{%-if params.promisifyReplyCallback | length %}>{%- endif %}, - onReplyError: (err: NatsTypescriptTemplateError) => void, - nc: Client, - {% if channelParameters | length %} - {{channelParameters | realizeParametersForChannel}} - {% endif %} + onRequest: (err?: NatsTypescriptTemplateError, msg?: {{receiveMessage | getMessageType}}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => + {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{replyMessage | getMessageType}}{%-if params.promisifyReplyCallback | length %}>{%- endif %}, + onReplyError: (err: NatsTypescriptTemplateError) => void, + nc: Client + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannel}} + {% endif %}, + options?: SubscriptionOptions ): Promise { return new Promise(async (resolve, reject) => { try { - let subscribeOptions: SubscriptionOptions = {}; - {%- if recieveMessage | hasNatsBindings %} - {%- if recieveMessage.bindings().nats().queue() | length %} + let subscribeOptions: SubscriptionOptions = {... options}; + {%- if receiveMessage | hasNatsBindings %} + {%- if receiveMessage.bindings().nats().queue() | length %} //If queue - subscribeOptions.queue = '{{recieveMessage.bindings().nats().queue().name()}}'; - {%- endif %} - {%- if recieveMessage.bindings().nats().unsubAfter() | length %} - //If unsubafter - subscribeOptions.max = {{recieveMessage.bindings().nats().unsubAfter()}}; + subscribeOptions.queue = '{{receiveMessage.bindings().nats().queue().name()}}'; {%- endif %} {%- endif %} + subscribeOptions.max = 1; let subscription = nc.subscribe({{channelParameters | realizeChannelName(channelName)}}, {%- if params.promisifyReplyCallback | length %}async{%- endif %} (err, msg) => { if (err) { @@ -40,10 +38,10 @@ export function reply( } {%- endif %} - {%- if recieveMessage.payload() | messageHasNotNullPayload %} - {{OnReceivingData(false)}} - let requestData = {{recieveMessage.uid() | pascalCase}}Message.Convert.to{{recieveMessage.uid() | pascalCase}}(receivedData); - let message = {%-if params.promisifyReplyCallback | length %}await{%- endif %} onRequest(undefined, requestData{% if channelParameters | length %}, + {%- if receiveMessage.payload() | messageHasNotNullPayload %} + {{OnReceivingData(false, receiveMessage, defaultContentType)}} + + let message = {%-if params.promisifyReplyCallback | length %}await{%- endif %} onRequest(undefined, receivedData{% if channelParameters | length %}, {%- set counter = 1 %} {%- for parameterName, parameter in channelParameters %} receivedTopicParameters['{{parameterName}}']{%- if counter < (channelParameters | length) %},{%- endif %} @@ -62,10 +60,11 @@ export function reply( if (msg.reply) { {%- if replyMessage.payload() | messageHasNotNullPayload %} - {{OnSendingData()}} - nc.publish({{channelParameters | realizeChannelName(channelName)}}, dataToSend); + {{OnSendingData(false, replyMessage, defaultContentType)}} + + await nc.publish(msg.reply, dataToSend); {%- else %} - nc.publish({{channelParameters | realizeChannelName(channelName)}}, null); + await nc.publish(msg.reply, null); {%- endif %} } else { let error = new NatsTypescriptTemplateError('Expected request to need a reply, did not..', '000'); diff --git a/partials/channel/Request.njk b/partials/channel/Request.njk index ec6ff8562..fb985f104 100644 --- a/partials/channel/Request.njk +++ b/partials/channel/Request.njk @@ -1,20 +1,21 @@ {%- from "./OnSendingData.njk" import OnSendingData %} {%- from "./OnReceivingData.njk" import OnReceivingData %} -{% macro request(channelName, channelParameters, recieveMessage, requestMessage, server) %} +{% macro request(channelName, channelParameters, requestMessage, receiveMessage, server, defaultContentType) %} export function request( message: {{requestMessage | getMessageType}}, - nc: Client, + nc: Client {% if channelParameters | length %} - {{channelParameters | realizeParametersForChannel}} + ,{{channelParameters | realizeParametersForChannel}} {% endif %} - ): Promise<{{recieveMessage | getMessageType}}> { + ): Promise<{{receiveMessage | getMessageType}}> { return new Promise(async (resolve, reject) => { let msg; try { {%- if requestMessage.payload() | messageHasNotNullPayload %} - {{OnSendingData()}} + {{OnSendingData(true, requestMessage, defaultContentType)}} + msg = await nc.request({{channelParameters | realizeChannelName(channelName)}}, undefined, dataToSend) {%- else %} msg = await nc.request({{channelParameters | realizeChannelName(channelName)}}, undefined, null) @@ -24,10 +25,9 @@ export function request( return; } - {%- if recieveMessage.payload() | messageHasNotNullPayload %} - {{OnReceivingData(true)}} - let recievedData = {{recieveMessage.uid() | pascalCase}}Message.Convert.to{{recieveMessage.uid() | pascalCase}}(receivedData); - resolve(recievedData); + {%- if receiveMessage.payload() | messageHasNotNullPayload %} + {{OnReceivingData(true, receiveMessage, defaultContentType)}} + resolve(receivedData); {%- else %} resolve(null); {%- endif %} diff --git a/partials/channel/Subscribe.njk b/partials/channel/Subscribe.njk index 8ec7b6c10..06a7cd800 100644 --- a/partials/channel/Subscribe.njk +++ b/partials/channel/Subscribe.njk @@ -1,14 +1,16 @@ -{% macro subscribe(channelName, channelParameters, subscribtionMessage, server) %} +{%- from "./OnReceivingData.njk" import OnReceivingData %} +{% macro subscribe(channelName, channelParameters, subscribtionMessage, server, defaultContentType) %} export function subscribe( - onDataCallback : (err?: NatsTypescriptTemplateError, msg?: {{subscribtionMessage | getMessageType}}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void, - nc: Client, - {% if channelParameters | length %} - {{channelParameters | realizeParametersForChannel}} - {% endif %} + onDataCallback : (err?: NatsTypescriptTemplateError, msg?: {{subscribtionMessage | getMessageType}}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void, + nc: Client + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannel}} + {% endif %}, + options?: SubscriptionOptions ): Promise { return new Promise(async (resolve, reject) => { - let subscribeOptions: SubscriptionOptions = {}; + let subscribeOptions: SubscriptionOptions = {... options}; {%- if subscribtionMessage | hasNatsBindings %} {%- if subscribtionMessage.bindings().nats().queue() | length %} //If queue @@ -36,18 +38,8 @@ export function subscribe( } {%- endif %} {%- if subscribtionMessage.payload() | messageHasNotNullPayload %} - try{ - let receivedDataHooks = Hooks.getInstance().getRecievedDataHook(); - var processedDataReceived: any = msg.data; - for(let hook of receivedDataHooks){ - processedDataReceived = hook(processedDataReceived); - } - }catch(e){ - reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.HOOK_ERROR, e)); - return; - } - let publishedData = {{subscribtionMessage.uid() | pascalCase}}Message.Convert.to{{subscribtionMessage.uid() | pascalCase}}(processedDataReceived); - onDataCallback(undefined, publishedData{% if channelParameters | length %}, + {{OnReceivingData(true, subscribtionMessage, defaultContentType)}} + onDataCallback(undefined, receivedData{% if channelParameters | length %}, {%- set counter = 1 %} {%- for parameterName, parameter in channelParameters %} receivedTopicParameters['{{parameterName}}']{%- if counter < (channelParameters | length) %},{%- endif %} diff --git a/partials/index/Publish.njk b/partials/index/Publish.njk index 62c9909bd..1b92c81a9 100644 --- a/partials/index/Publish.njk +++ b/partials/index/Publish.njk @@ -4,9 +4,12 @@ * {{messageDescription}} * @param requestMessage The message to publish. */ - public publishTo{{channelName | pascalCase }}(requestMessage: {{message | getMessageType}} {% if channelParameters | length %} - ,{{channelParameters | realizeParametersForChannel}} - {% endif %}): Promise { + public publishTo{{channelName | pascalCase }}( + requestMessage: {{message | getMessageType}} + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannel}} + {% endif %} + ): Promise { {%- if message.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; {%- endif %} diff --git a/partials/index/Reply.njk b/partials/index/Reply.njk index 33be3ba3d..7c48e8bdd 100644 --- a/partials/index/Reply.njk +++ b/partials/index/Reply.njk @@ -1,34 +1,42 @@ -{% macro reply(defaultContentType, channelName, subscribeMessage, publishMessage, messageDescription, channelParameters, params) %} +{% macro reply(defaultContentType, channelName, replyMessage, requestMessage, messageDescription, channelParameters, params) %} /** * {{messageDescription}} - * @param onRequest Called when request recieved. + * @param onRequest Called when request received. * @param onReplyError Called when it was not possible to send the reply. */ public replyTo{{channelName | pascalCase }}( - onRequest : ( - err?: NatsTypescriptTemplateError, - msg?: {{publishMessage | getMessageType}} - {%- if channelParameters | length %},{{channelParameters | realizeParametersForChannel(false)}}{% endif %} - ) => {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{subscribeMessage | getMessageType}}{%- if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError : (err: NatsTypescriptTemplateError) => void - {% if channelParameters | length %} - ,{{channelParameters | realizeParametersForChannel}} - {% endif %}): Promise { - {%- if publishMessage.contentType() | isBinaryPayload(defaultContentType) %} + onRequest : ( + err?: NatsTypescriptTemplateError, + msg?: {{requestMessage | getMessageType}} + {%- if channelParameters | length %},{{channelParameters | realizeParametersForChannel(false)}}{% endif %} + ) => {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{replyMessage | getMessageType}}{%- if params.promisifyReplyCallback | length %}>{%- endif %}, + onReplyError : (err: NatsTypescriptTemplateError) => void + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannel}} + {% endif %}, + options?: SubscriptionOptions + ): Promise { + {%- if requestMessage.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; {%- endif %} - {%- if publishMessage.contentType() | isStringPayload(defaultContentType) %} + {%- if requestMessage.contentType() | isStringPayload(defaultContentType) %} const nc: Client = this.stringClient!; {%- endif %} - {%- if publishMessage.contentType() | isJsonPayload(defaultContentType) %} + {%- if requestMessage.contentType() | isJsonPayload(defaultContentType) %} const nc: Client = this.jsonClient!; {%- endif %} if(nc){ - return {{ channelName | camelCase }}Channel.reply(onRequest, onReplyError, nc + return {{ channelName | camelCase }}Channel.reply( + onRequest, + onReplyError, + nc {% if channelParameters | length %} ,{{channelParameters | realizeParametersForChannelWithoutType}} - {% endif %}); + {% endif %}, + options + ); }else{ return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); } diff --git a/partials/index/Request.njk b/partials/index/Request.njk index 39d17bbf1..2f262fb12 100644 --- a/partials/index/Request.njk +++ b/partials/index/Request.njk @@ -1,27 +1,32 @@ -{% macro request(defaultContentType, channelName, publishMessage, subscribeMessage, messageDescription, channelParameters) %} +{% macro request(defaultContentType, channelName, requestMessage, replyMessage, messageDescription, channelParameters) %} /** * {{messageDescription}} * @param requestMessage The request message to send. */ - public request{{channelName | pascalCase }}(requestMessage:{{subscribeMessage | getMessageType}} - {% if channelParameters | length %} - ,{{channelParameters | realizeParametersForChannel}} - {% endif %}): Promise<{{publishMessage | getMessageType}}> { - {%- if subscribeMessage.contentType() | isBinaryPayload(defaultContentType) %} + public request{{channelName | pascalCase }}( + requestMessage:{{requestMessage | getMessageType}} + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannel}} + {% endif %} + ): Promise<{{replyMessage | getMessageType}}> { + {%- if requestMessage.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; {%- endif %} - {%- if subscribeMessage.contentType() | isStringPayload(defaultContentType) %} + {%- if requestMessage.contentType() | isStringPayload(defaultContentType) %} const nc: Client = this.stringClient!; {%- endif %} - {%- if subscribeMessage.contentType() | isJsonPayload(defaultContentType) %} + {%- if requestMessage.contentType() | isJsonPayload(defaultContentType) %} const nc: Client = this.jsonClient!; {%- endif %} if(nc){ - return {{ channelName | camelCase }}Channel.request(requestMessage, nc - {% if channelParameters | length %} - ,{{channelParameters | realizeParametersForChannelWithoutType}} - {% endif %}); + return {{ channelName | camelCase }}Channel.request( + requestMessage, + nc + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannelWithoutType}} + {% endif %} + ); }else{ return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); } diff --git a/partials/index/Standard.njk b/partials/index/Standard.njk index d075eb34d..e89ebb259 100644 --- a/partials/index/Standard.njk +++ b/partials/index/Standard.njk @@ -21,19 +21,25 @@ this.options = this.setDefaultOptions(options); try{ {%- if asyncapi | containsBinaryPayload %} - this.options.payload = Payload.BINARY; - this.binaryClient = await connect(this.options); - this.chainEvents(this.binaryClient); + if(!this.binaryClient || this.binaryClient!.isClosed()){ + this.options.payload = Payload.BINARY; + this.binaryClient = await connect(this.options); + this.chainEvents(this.binaryClient); + } {%- endif %} {%- if asyncapi | containsStringPayload %} - this.options.payload = Payload.STRING; - this.stringClient = await connect(this.options); - this.chainEvents(this.stringClient); + if(!this.stringClient || this.stringClient!.isClosed()){ + this.options.payload = Payload.STRING; + this.stringClient = await connect(this.options); + this.chainEvents(this.stringClient); + } {%- endif %} {%- if asyncapi | containsJsonPayload %} - this.options.payload = Payload.JSON; - this.jsonClient = await connect(this.options); - this.chainEvents(this.jsonClient); + if(!this.jsonClient || this.jsonClient!.isClosed()){ + this.options.payload = Payload.JSON; + this.jsonClient = await connect(this.options); + this.chainEvents(this.jsonClient); + } {%- endif %} resolve(); }catch(e){ @@ -42,19 +48,45 @@ }) } + /** + * Returns whether or not any of the clients are closed + */ + isClosed(){ + {%- if asyncapi | containsBinaryPayload %} + if (!this.binaryClient || this.binaryClient!.isClosed()){ + return true; + } + {%- endif %} + {%- if asyncapi | containsStringPayload %} + if (!this.stringClient || this.stringClient!.isClosed()){ + return true; + } + {%- endif %} + {%- if asyncapi | containsJsonPayload %} + if (!this.jsonClient || this.jsonClient!.isClosed()){ + return true; + } + {%- endif %} + } /** * Disconnect all clients from the server */ async disconnect(){ {%- if asyncapi | containsBinaryPayload %} - this.binaryClient!.close() + if(this.binaryClient && !this.binaryClient!.isClosed()){ + this.binaryClient!.close(); + } {%- endif %} {%- if asyncapi | containsStringPayload %} - this.stringClient!.close() + if(this.stringClient && !this.stringClient!.isClosed()){ + this.stringClient!.close(); + } {%- endif %} {%- if asyncapi | containsJsonPayload %} - this.jsonClient!.close() + if(this.jsonClient && !this.jsonClient!.isClosed()){ + this.jsonClient!.close(); + } {%- endif %} } diff --git a/partials/index/Subscribe.njk b/partials/index/Subscribe.njk index 65453ae9a..c14fc3890 100644 --- a/partials/index/Subscribe.njk +++ b/partials/index/Subscribe.njk @@ -2,11 +2,15 @@ {% macro subscribe(defaultContentType, channelName, message, messageDescription, channelParameters) %} /** * {{messageDescription}} - * @param onDataCallback Called when message recieved. + * @param onDataCallback Called when message received. */ - public subscribeTo{{channelName | pascalCase }}(onDataCallback : (err?: NatsTypescriptTemplateError, msg?: {{message | getMessageType}}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void {% if channelParameters | length %} - ,{{channelParameters | realizeParametersForChannel}} - {% endif %}): Promise { + public subscribeTo{{channelName | pascalCase }}( + onDataCallback : (err?: NatsTypescriptTemplateError, msg?: {{message | getMessageType}}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannel}} + {% endif %}, + options?: SubscriptionOptions + ): Promise { {%- if message.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; {%- endif %} @@ -17,10 +21,13 @@ const nc: Client = this.jsonClient!; {%- endif %} if(nc){ - return {{ channelName | camelCase }}Channel.subscribe(onDataCallback, nc - {% if channelParameters | length %} - ,{{channelParameters | realizeParametersForChannelWithoutType}} - {% endif %}); + return {{ channelName | camelCase }}Channel.subscribe( + onDataCallback, nc + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannelWithoutType}} + {% endif %}, + options + ); }else{ return Promise.reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.NOT_CONNECTED)); } diff --git a/template/src/channels/$$channel$$.ts.njk b/template/src/channels/$$channel$$.ts.njk index 651d5adbb..7a68cff3c 100644 --- a/template/src/channels/$$channel$$.ts.njk +++ b/template/src/channels/$$channel$$.ts.njk @@ -18,18 +18,18 @@ import {ErrorCode, NatsTypescriptTemplateError} from '../NatsTypescriptTemplateE import { Hooks } from '../hooks'; {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{ request(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} + {{ request(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), defaultContentType) }} {%- endif %} {%- if channel | isReplier %} - {{ reply(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), params) }} + {{ reply(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), params, defaultContentType) }} {%- endif %} {%- endif %} {%- if channel | isPubsub %} {%- if channel.hasSubscribe() %} - {{ publish(channelName, channel.parameters(), channel.subscribe().message(0), asyncapi.server(params.server)) }} + {{ publish(channelName, channel.parameters(), channel.subscribe().message(0), asyncapi.server(params.server), defaultContentType) }} {%- endif %} {%- if channel.hasPublish() %} - {{ subscribe(channelName, channel.parameters(), channel.publish().message(0), asyncapi.server(params.server)) }} + {{ subscribe(channelName, channel.parameters(), channel.publish().message(0), asyncapi.server(params.server), defaultContentType) }} {%- endif %} {%- endif %} diff --git a/template/src/hooks.ts b/template/src/hooks.ts index 321b9085c..d4528c513 100644 --- a/template/src/hooks.ts +++ b/template/src/hooks.ts @@ -1,20 +1,20 @@ export enum AvailableHooks { - RecievedData = 'RecievedData', + receivedData = 'receivedData', BeforeSendingData = 'BeforeSendingData' } -export type RecievedDataHook = (receivedData: any) => string; +export type receivedDataHook = (receivedData: any) => string; export type BeforeSendingDataHook = (messageToSend: any) => string; export class Hooks { private static instance: Hooks; private hooks: { BeforeSendingData: BeforeSendingDataHook[]; - RecievedData: RecievedDataHook[]; + receivedData: receivedDataHook[]; }; private constructor() { this.hooks = { BeforeSendingData: [], - RecievedData: [] + receivedData: [] } } public static getInstance(): Hooks { @@ -40,15 +40,15 @@ export class Hooks { * Register a hook for BeforeSendingData * @param hook */ - public async registerRecievedData(hook: RecievedDataHook) { - this.hooks[AvailableHooks.RecievedData] - ? this.hooks[AvailableHooks.RecievedData].push(hook) + public async registerreceivedData(hook: receivedDataHook) { + this.hooks[AvailableHooks.receivedData] + ? this.hooks[AvailableHooks.receivedData].push(hook) : [hook]; } - public getRecievedDataHook(): RecievedDataHook[] { - return this.hooks[AvailableHooks.RecievedData]; + public getreceivedDataHook(): receivedDataHook[] { + return this.hooks[AvailableHooks.receivedData]; } public getBeforeSendingDataHook(): BeforeSendingDataHook[] { diff --git a/template/src/index.ts.njk b/template/src/index.ts.njk index f62eef4dd..187337f13 100644 --- a/template/src/index.ts.njk +++ b/template/src/index.ts.njk @@ -8,8 +8,8 @@ import {fromSeed} from 'ts-nkeys'; -import {AvailableHooks, RecievedDataHook, BeforeSendingDataHook, Hooks} from './hooks'; -export {AvailableHooks, RecievedDataHook, BeforeSendingDataHook, Hooks} +import {AvailableHooks, receivedDataHook, BeforeSendingDataHook, Hooks} from './hooks'; +export {AvailableHooks, receivedDataHook, BeforeSendingDataHook, Hooks} import * as TestClient from './tests/testclient/'; export {% raw %}{{% endraw %} TestClient {% raw %}}{% endraw %}; import {ErrorCode, NatsTypescriptTemplateError} from './NatsTypescriptTemplateError'; @@ -23,8 +23,10 @@ import { Subscription, ServersChangedEvent, SubEvent, - ServerInfo + ServerInfo, + SubscriptionOptions } from 'ts-nats'; + export {Client, ServerInfo, ServersChangedEvent, SubEvent} {%- for channelName, message in asyncapi.channels() %} import * as {{ channelName | camelCase }}Channel from "./channels/{{ channelName | pascalCase | firstUpperCase }}"; @@ -77,7 +79,7 @@ export class NatsAsyncApiClient extends events.EventEmitter{ {%- for channelName, channel in asyncapi.channels() %} {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{request(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters())}} + {{request(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- if channel | isReplier %} {{reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters(), params)}} diff --git a/template/src/tests/testclient/index.ts.njk b/template/src/tests/testclient/index.ts.njk index 84851f1c7..f8ec3e2aa 100644 --- a/template/src/tests/testclient/index.ts.njk +++ b/template/src/tests/testclient/index.ts.njk @@ -16,7 +16,8 @@ import { Subscription, ServersChangedEvent, SubEvent, - ServerInfo + ServerInfo, + SubscriptionOptions } from 'ts-nats'; {%- for channelName, message in asyncapi.channels() %} @@ -67,15 +68,14 @@ export declare interface NatsAsyncApiTestClient { on(event: AvailableEvents.yield, listener: () => void): this; } export class NatsAsyncApiTestClient extends events.EventEmitter{ - {{standard(asyncapi)}} {%- for channelName, channel in asyncapi.channels() %} {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{ reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters(), params)}} + {{ reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0),channel.publish().message(0), channel.description(), channel.parameters(), params)}} {%- endif %} {%- if channel | isReplier %} - {{ request(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters())}} + {{ request(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- endif %} diff --git a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk index 0e811dfa1..83113c44d 100644 --- a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk +++ b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk @@ -20,18 +20,18 @@ import { Hooks } from '../../../hooks'; {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{ reply(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), params) }} + {{ reply(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), params, defaultContentType) }} {%- endif %} {%- if channel | isReplier %} - {{ request(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server)) }} + {{ request(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), defaultContentType) }} {%- endif %} {%- endif %} {%- if channel | isPubsub %} {%- if channel.hasSubscribe() %} - {{ subscribe(channelName, channel.parameters(), channel.subscribe().message(0), asyncapi.server(params.server)) }} + {{ subscribe(channelName, channel.parameters(), channel.subscribe().message(0), asyncapi.server(params.server), defaultContentType) }} {%- endif %} {%- if channel.hasPublish() %} - {{ publish(channelName, channel.parameters(), channel.publish().message(0), asyncapi.server(params.server)) }} + {{ publish(channelName, channel.parameters(), channel.publish().message(0), asyncapi.server(params.server), defaultContentType) }} {%- endif %} {%- endif %} From f491232a13ca17a1fd4db727a114ef790bdd9d9b Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 27 Jul 2020 02:35:55 +0200 Subject: [PATCH 078/110] Matched the template with bindings. --- .../StreetlightStreetlightIdCommandTurnon.ts | 1 - .../StreetlightStreetlightIdEventTurnon.ts | 5 ++--- .../StreetlightStreetlightIdCommandTurnon.ts | 5 ++--- .../StreetlightStreetlightIdEventTurnon.ts | 1 - partials/channel/Reply.njk | 7 +++++-- partials/channel/Request.njk | 14 ++++++++++---- partials/channel/Subscribe.njk | 2 +- 7 files changed, 20 insertions(+), 15 deletions(-) diff --git a/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts index 618a56e89..b66f3bf16 100644 --- a/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts +++ b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts @@ -17,7 +17,6 @@ export function reply( return new Promise(async (resolve, reject) => { try { let subscribeOptions: SubscriptionOptions = {... options}; - subscribeOptions.max = 1; let subscription = nc.subscribe(`streetlight.${streetlight_id}.command.turnon`,async (err, msg) => { if (err) { diff --git a/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts index 35d4946c9..533fc97e5 100644 --- a/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts +++ b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts @@ -13,7 +13,7 @@ export function request( ): Promise { return new Promise(async (resolve, reject) => { - + var timeout = undefined; let msg; try { @@ -29,8 +29,7 @@ try{ return; } - - msg = await nc.request(`streetlight.${streetlight_id}.event.turnon`, undefined, dataToSend) + msg = await nc.request(`streetlight.${streetlight_id}.event.turnon`, timeout, dataToSend) }catch(e){ reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); return; diff --git a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts index 869c44d94..4ee25be80 100644 --- a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts +++ b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts @@ -13,7 +13,7 @@ export function request( ): Promise { return new Promise(async (resolve, reject) => { - + var timeout = undefined; let msg; try { @@ -29,8 +29,7 @@ try{ return; } - - msg = await nc.request(`streetlight.${streetlight_id}.command.turnon`, undefined, dataToSend) + msg = await nc.request(`streetlight.${streetlight_id}.command.turnon`, timeout, dataToSend) }catch(e){ reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); return; diff --git a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts index 21e2cd499..b35f47934 100644 --- a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts +++ b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts @@ -17,7 +17,6 @@ export function reply( return new Promise(async (resolve, reject) => { try { let subscribeOptions: SubscriptionOptions = {... options}; - subscribeOptions.max = 1; let subscription = nc.subscribe(`streetlight.${streetlight_id}.event.turnon`,async (err, msg) => { if (err) { diff --git a/partials/channel/Reply.njk b/partials/channel/Reply.njk index 56675efa5..2d590a81e 100644 --- a/partials/channel/Reply.njk +++ b/partials/channel/Reply.njk @@ -18,10 +18,13 @@ export function reply( {%- if receiveMessage | hasNatsBindings %} {%- if receiveMessage.bindings().nats().queue() | length %} //If queue - subscribeOptions.queue = '{{receiveMessage.bindings().nats().queue().name()}}'; + subscribeOptions.queue = '{{receiveMessage.bindings().nats().queue()}}'; + {%- endif %} + {%- if receiveMessage.bindings().nats().unsubAfter() | length %} + //If unsubafter + subscribeOptions.max = {{receiveMessage.bindings().nats().unsubAfter()}}; {%- endif %} {%- endif %} - subscribeOptions.max = 1; let subscription = nc.subscribe({{channelParameters | realizeChannelName(channelName)}}, {%- if params.promisifyReplyCallback | length %}async{%- endif %} (err, msg) => { if (err) { diff --git a/partials/channel/Request.njk b/partials/channel/Request.njk index fb985f104..8da8b0227 100644 --- a/partials/channel/Request.njk +++ b/partials/channel/Request.njk @@ -10,15 +10,21 @@ export function request( {% endif %} ): Promise<{{receiveMessage | getMessageType}}> { return new Promise(async (resolve, reject) => { - + var timeout = undefined; + {%- if requestMessage | hasNatsBindings %} + {%- if requestMessage.bindings().nats().requestReply() | length %} + {%- if requestMessage.bindings().nats().requestReply().timeout() | length %} + timeout = '{{requestMessage.bindings().nats().requestReply().timeout()}}'; + {%- endif %} + {%- endif %} + {%- endif %} let msg; try { {%- if requestMessage.payload() | messageHasNotNullPayload %} {{OnSendingData(true, requestMessage, defaultContentType)}} - - msg = await nc.request({{channelParameters | realizeChannelName(channelName)}}, undefined, dataToSend) + msg = await nc.request({{channelParameters | realizeChannelName(channelName)}}, timeout, dataToSend) {%- else %} - msg = await nc.request({{channelParameters | realizeChannelName(channelName)}}, undefined, null) + msg = await nc.request({{channelParameters | realizeChannelName(channelName)}}, timeout, null) {%- endif %} }catch(e){ reject(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, e)); diff --git a/partials/channel/Subscribe.njk b/partials/channel/Subscribe.njk index 06a7cd800..9c3e90b34 100644 --- a/partials/channel/Subscribe.njk +++ b/partials/channel/Subscribe.njk @@ -14,7 +14,7 @@ export function subscribe( {%- if subscribtionMessage | hasNatsBindings %} {%- if subscribtionMessage.bindings().nats().queue() | length %} //If queue - subscribeOptions.queue = '{{subscribtionMessage.bindings().nats().queue().name()}}'; + subscribeOptions.queue = '{{subscribtionMessage.bindings().nats().queue()}}'; {%- endif %} {%- if subscribtionMessage.bindings().nats().unsubAfter() | length %} //If unsubafter From e7ad8ccbe870ebb4e8fc3f1cf2e8fe69f96bdfdc Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 27 Jul 2020 02:48:59 +0200 Subject: [PATCH 079/110] Matched the template with bindings. --- examples/request reply/streetlight/src/index.ts | 11 +---------- .../streetlight/src/tests/testclient/index.ts | 11 +---------- partials/index/Standard.njk | 11 +---------- 3 files changed, 3 insertions(+), 30 deletions(-) diff --git a/examples/request reply/streetlight/src/index.ts b/examples/request reply/streetlight/src/index.ts index 9bb17f463..0162745f4 100644 --- a/examples/request reply/streetlight/src/index.ts +++ b/examples/request reply/streetlight/src/index.ts @@ -88,7 +88,7 @@ export class NatsAsyncApiClient extends events.EventEmitter{ */ connect(options : NatsConnectionOptions): Promise{ return new Promise(async (resolve: () => void, reject: (error: any) => void) => { - this.options = this.setDefaultOptions(options); + this.options = options; try{ if(!this.jsonClient || this.jsonClient!.isClosed()){ this.options.payload = Payload.JSON; @@ -209,15 +209,6 @@ export class NatsAsyncApiClient extends events.EventEmitter{ }); } - /** - * Set the default options based on the AsyncAPI file. - * @param options to set - */ - private setDefaultOptions(options: NatsConnectionOptions){ - //If server binding options sat set the options - options.encoding = 'utf8'; - return options; - } /** diff --git a/examples/request reply/streetlight/src/tests/testclient/index.ts b/examples/request reply/streetlight/src/tests/testclient/index.ts index d6eee442e..c32c64f0a 100644 --- a/examples/request reply/streetlight/src/tests/testclient/index.ts +++ b/examples/request reply/streetlight/src/tests/testclient/index.ts @@ -80,7 +80,7 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ */ connect(options : NatsConnectionOptions): Promise{ return new Promise(async (resolve: () => void, reject: (error: any) => void) => { - this.options = this.setDefaultOptions(options); + this.options = options; try{ if(!this.jsonClient || this.jsonClient!.isClosed()){ this.options.payload = Payload.JSON; @@ -201,15 +201,6 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ }); } - /** - * Set the default options based on the AsyncAPI file. - * @param options to set - */ - private setDefaultOptions(options: NatsConnectionOptions){ - //If server binding options sat set the options - options.encoding = 'utf8'; - return options; - } /** diff --git a/partials/index/Standard.njk b/partials/index/Standard.njk index e89ebb259..602b9b8e6 100644 --- a/partials/index/Standard.njk +++ b/partials/index/Standard.njk @@ -18,7 +18,7 @@ */ connect(options : NatsConnectionOptions): Promise{ return new Promise(async (resolve: () => void, reject: (error: any) => void) => { - this.options = this.setDefaultOptions(options); + this.options = options; try{ {%- if asyncapi | containsBinaryPayload %} if(!this.binaryClient || this.binaryClient!.isClosed()){ @@ -179,13 +179,4 @@ }); } - /** - * Set the default options based on the AsyncAPI file. - * @param options to set - */ - private setDefaultOptions(options: NatsConnectionOptions){ - //If server binding options sat set the options - options.encoding = 'utf8'; - return options; - } {% endmacro %} \ No newline at end of file From 12430b7c97785b9c04a5dc9a7615f216baa83c5a Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 27 Jul 2020 02:52:10 +0200 Subject: [PATCH 080/110] Removed unused files. --- docs/img/binary_recieve_hooks.png | Bin 7203 -> 0 bytes docs/img/binary_send_hooks.png | Bin 7205 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/img/binary_recieve_hooks.png delete mode 100644 docs/img/binary_send_hooks.png diff --git a/docs/img/binary_recieve_hooks.png b/docs/img/binary_recieve_hooks.png deleted file mode 100644 index 2549720b1097e440d7d75b503d82c52309f69613..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7203 zcmd6McTiJZv@akkMNzs9r58a+p#;T3NFX7UkWd2B5(puL1VS2JR1grPh*Fd;sE8s> z5RhU3QHml~KtxecdQ%V(yob;4&fJ-M=lyrzdoyQF*4caQwcA?j_uD)1SR0F-V*A7d z1O#@XQ3#xXfM7Zxb40cQZ@Nc^gn+Xh&rU&~_{mBAqP_w_18U*AUz+$UG5o!kTK?EO~<0)l{!fQ*hn^zFe0YEV-U7E0z+yH6>7zTaB2Ap28kWZ=hw>_rRMY+~jc6hH?`%whVvAYFa1zL74> z7%0aReTYHS|6*lxGF);HiyFZAI~Ooi*FYEgchqDyk@B}RFwho{#Rd9WGr15L1cnZV zvS5F8*dc-BzdDqF0E$1*Cqxa31lIE3MFZ?p|6L}3(@>{CHrv>mZE3+WwGY4=LO6fb zp^n}*e#QYjBo+kb5RF3Y@TOiNAdHbOn8@S=IvHYJf{^y!JVP(CoiiRwB6x#BEz}@z zFEbt$Z07{=H!_7mLa^4rWZ-0%U^Ihc4NNfzVSsUf;K?`#TO)mvKiY`rZ50fZ6Bsle z5oSU6B|3*?`50H@pF%n>*zw0IN*u#)017jjB5J%)$*jRJWV4z!PeFnzK&kh5{830`bn1$MeTGPqYP-_EgXBLi$ zz~HGiAX77c7h5l2zu@K$wxEC@K!62;jd?BvcA&8l;1=fA-V_*}NJQB}oXub)9>d4k zB7{c7B5;ltSZbgh9qDICw8Qw?24YNoeT>PzW>gvkm><*uPGtMQz!qpE%@oVCGZ$&16X^b0le-CRaI1B3PkTd**I427bt?YLAB zFUZgg;z(sXGmuaU6>Y<_3-yOvk}aLAIb=4NNQAS{)(lgi0m0hB($^V5@Zov+`TN62 z4nagTk-^mGLW6v<4i*>|hRxtPApF3PkbnRi8jg%|whLjip(wl^)mA?+loe=0v~{AJ zqMQsJgAue)APnFxXpFZL$dv7bMA7ZZ6c<(q+1V0sdLXFaHb%xweKUQCK@gg3AHpND zkx;a^c@UK1#K3stfE_WnVw1oKe*;92kvSz0f+OQ>>_Q=IvbB{ToLxw-tF~EDkn4iMPp zp=cY&AQ&77W8mXIBl(}O2EPBzl2ByTZPUvF0&>M@gsFY7`*e;i%B@4bLnA?0zfH_i za}PW?uU&$GBkSk#Y9)xVDtGLUVcy_B{Ic7G2j8ET+4rBEg3!v@`k? z_nCThA6(lf4PI%v@a5R(qhZ)=6YtwlSO+g}HcV+Z$7klli|nu_*7NS`wX^GM%d@h2 zQi_6`4=S$Zgct^{+P_0IML;wqO8peEKxtDF5LLB|;$POZF*FxaJq0|(f}JusEnmMD z?Nd+41VuYdfg zo|v4(8yFZc8C~_NpRNkTv}?N?&cFruLK;o=_1Bo0rp+vB>FZ7zWt~xe(d#EE>phzT zagfP5mC_ph^!KkX$$oUYwSm6A@5}LtiN1*G>1hWj6ndwy5dO#C++=LHjT+$Z|2;^m zATw1YGQeE#MecFDf`Y=tNPEJ>jpP%Zzwg!6Iq#H^nBd;IbB8@VFgOS$`F@-%z2DR~ zdg9lo^9t)Sy+O$uwz=OaA@d_hbyCHe2^d_UvUhRi`n7BN@~+>t2OdADtSr27$Xyld zFC>#rN*0*CAEV^aw(w*8RpNP|`wyu{&$YU_yT481g@qkc5z9NX5n?W)2}P`s%er+%xm({e~+^^*RzkTW7+Jt<9fK`{(?eDR~RWUM0ihT!SoxkZmN>%}*3 z-h4ebSAM6ow96$Aq_PVZxe^i?=|0R)#1%Cjiu`37u{^|Eo!xz-Bl!>osiQ2SsX|jB zEVlfS{G5MKH=fb`RIIsnP4b!l3h)6v&W_6#!}-RH)CX0>Z1VCkBSb%O9kbQB+FwfcycUycg>*1GHDhYE?a&f&fL5_A^cy?yIb zD3Y~~d7VPLgsg!kWM(D&DdP*B1-*lL)1Q3wj%xaP+AH$2kyC`{Imd1>hU$xV<+g3LNYtJ}t-zLtdg^7;hl+Z_WD|f63135o zb%ad$By%lT14dacT<;m+;H8o4Kb<1#1Df!cMyo)+;(t0QW-cx+Kh~Q!Rwui8O)cYR z7M^JwYuaL7D0E=Fvb;QhmK^z3?OjQ$(|vab7K^n?6PT-$%{IMI^|bfG0f-j8i)k=M z!JZp1XqOxIP`RafW~rZ&NceT4_@Y3JnnSDI$DC)f6>%zt$ZdS(j_Xfv^)g$Evd7iN zm8z_-v}SpZ+5LWzck;!7d&i8CkrK|%4EULFu$t9 z5#n36Y!Q=;o-SuL7ZmUuEC>fq}l^H09?fJ=#d- za+RN5gs&!ID?Hc(|&!3J%XT0AM<`guQb;g#f;^KhNuhR?=Gb=Ml51%GAnk&N=qrJ*1 z=5j2hfqZt&{6_bhRP_^5q;_FraGtiT&&+N3QPD{aRNCjt7`5Tm#4NGaT6>a)oUWwU z;uTW%&ZQos;oBaOD{9h@KZSG;5pUDPFlBB;;&i9vpNAS73Maxd8~B~SfnEFZ&#q0q zD3cNi+Au9C&%Y!{R4~AM5y>k&srMMb+ry~(D>_>x%bU@V+d%|G+T?}0rk|Dh5|tp) zE1JOQ;w26=SZ{(MRSnpu$*1KWo4|3Aafm4Q?pjiZfo7z2<*2q)N zios3A6h|QXs*`rCAvbNP0qBY=+|t2F+f;NB#S;3CLZ;+5ZT#QwOl%utxG6&GJMw75 z+{XGEn|oI{6xq;u996B|yv>R@-}SD90~6R6YIrz^3CYWjd8)T(XI)#BcE*5=oV;aj zS8wmQKzQb!>5JUa)-u1=kA_Q4%e&@h{7KolZ=37F&xYh^xIIe;4@v|COp$ zak)v@k`;%|z76Da@7#jgTBn}w?%VI~dz79%E6Djd;qa!n_tQcmQjZ0I7iVe8ne)B3 zpruK5R6t!r!yzJ~abjv}M}*Inb^{3HvX=PFr=vzjxBUG4;DhDjk3tsB0oHM6W`@D} z{cHZ*35vc|hExKpz)SZ-$TW;i6p>v(|)hsNm!Ntw((vLD(h1bMyJPo7-3 zmYLZL4U{ZwZ%6i=D$D_>!DK(ItTlF5>AidRx~D#TiyD3uf_G~QcWw+@wlPJ3N{zOv zCzU^~di&3LcMDO?`53bS>xIH{PeE;p+x5~&2=EH}3&JeO(xolt} zIt}~x?HiE1_qjhKBZG70NH>4R>HBcRfb6Q?Y$t$>Mc1xf%YO0_N$6}ZOA!QVJYD$s z^w_>1O)Wm3T0LzwY_fZsy1WB?SgIo>ckjNg0Wf<^zhp;M6{tb1G`abfBVo!u6LvpC z&tqn{+zw&>Gk_;{D;_in#-3bDRk66@e30DsQsH>0{iREnN^)}#I-EW|dA#vLSiasv zi36~5Gf#jVN*PC2?q=>_33$eUGxPGCdU|>W0+rlBp>u|HgQF>8t+MYbfK0dXd-27o zWBh3Kr!#Y5t|+7&L{3-FuME;OWtsg4AjeftPI{c7I{nFG_osnR6Xu{F)dqcRa!pF; zBIDj6!=STrk5kD4uOl{ohp6XV%4?{vx0lkY3FltbE)Ez#x)b*vI`qzXd8jG(L`1#W zII_RsX_PKaN2)^jUSnpJwOu$2v#05+0U3MR#pQKh-(~(He4RHr(0r!(XvAu@i-(8a z#d1ZCj|b_>o-O!2pM0Z-_&d1ff#k)uk);iZaM81v}Uq@aF<)t$%c z+2fb%xzpEjs}=blr?o{JARYTB={3?_KdpRJY3W+q8_u0Mt9VKv=pJ}LS^}Y1)AL^1 z&3Vn_%*LZ6&+Z4`6eS-EJFZGr*GRuP*j@&t6omnVpNibEXqncT$w_fpxgDS=QVsd$ zbAMv0>2dBKCFM&yqH?lx_zMF@kd*nzUeCP;-N+B?<1%ygAa*}E(8&ozw>$lxTnY9kX; z6`mvKy5p(PrEO|>0^`HOR2JV6B8jor*jJmIb6rQDbT;a#|NhCtmp3Y7wysCBf`82w zaD|$*H|WrNj5wJ1-i^a~@DU_g6MSg&hTzJ_ zcu+%7NFGj0M_0l2j+N`TZ+*$-5uee<*fr;cVm&^N2zvXlfj4rrzv$t^L^~Xr>s6>6 z@ssMb5*@?6dga0IcS$`1t}5t}MbDTeLm-O`XrCsg{@CY}*S?X0(>jWk|8nv4&DRf6 zN&9JG?SUeOv$!wv@7!G{Z^dI$dSp%$T#d)Hooe`(g&!3SpwbF7ep;cc&2;BAFMEJa z2E|jHbRPgiyJC`2Q1D9d7YIBcJKY)UR#%NCG7G-e?NAU;K}7 zVDJB1RhhNm;1|jAr6C90UTE(V9B^PTs!M$hM_m&5BbFCO0U8cG*&JoQ$!}e4Zg_>P6?F(45F-vkhIwd)e;ZTGf`>rO#&ex`Ve3c4=!U;J9?YSK{`}-y`#0)8By! zz3i{JNfBZv&I_b@m_*)H$N`Aa(PM9aSVbj)4|*;nbR<8x0US;cl#Xk;qP^fJTde+% zgX7QiS5fZVxM6lYWI+{Q`9Grc?g*LA>am}b@7@5qZwky}g+za`6VuYt?ld*I1D6sP z`YfDXRa8{6D$B(a*FJp6zEe^nN^jMj8|&F`0E6AGZ)n)O(-1G4#XZ(InXx8c)&2K! zgXSm?+!(x>nD8qCYmY5XjWxD@#AGyK2?wG_Kh&`%-rhUyV!~}zdbs0*yC&YwuHa)+ zM5(Up!~6@eu~ouPGQ6U(iAhO!u3nWD>v9JbrBF1zrR=uB;D^9djXUV4w2;JjB^>~h zvf@Tx-mvgvvG9$-^KiPq|LypA(c`VMN-nOhuX&e!zX78Qtx1@i``qeBqiI9ej%3Jx z9_zV2u`t>-G1R~lQ$Dx%kroIoo{)%ibITda^=>0QPa!AHpBs@oD1AO z(C^dfbeps^5=-mr2646+b6Q4jJFx;!968|L6kcaW@XQyfs;#YsK8cw7WEv5xVv(d- zWzrd^VjTM8_P+i5@yCxJzf)6FbGMHc>>l`-^Qq;mf)L)pp*TF}`RTae*kV2?y*zbg zCFISA4|f$L+QgrWEqM;axJi_NTs6=CxD%J!)wSR8W_C2PZBUN038_zn<@@qU+c(eQ zCsmGUeYp@{D3VmvV7I)o_${kiGje8P0vC3qJ$<&Z`)a-6H28jbVsi4NNszIJZQh9? z@RrMacljI!nLB%>#;N&EwoM*DLov}M`W9D?rHqUW# zaO}_ilkO|lG3T&g<;DxNcYlbltZI)54Hp+D~jxn za-}&esR~Joe5}A^=$6plm2I{8?!9yR_sZhYbKrM`^9bQIm2r#Sf#>eQ$)k;rBG$Oy zzko>0IKot~i_ejWh=>BdP-|?#Q1cm&tP<#HLfiXfg=05&k3Q5n9Gk=tm3c2N*#+!9 zXP>>Y1k>`>t5+_b-R$`HNh0DGL{j?!%#`wIqqHpyi+hTTtA{?_eJTzl+M@dWW1N>* z*QNbNL1HIW(mgfIh+06ZxI|D?gj{d0zgX1lPc$|9lzH$(`0bsI2LM3K2>S;RoA=Xn z#;_V$VhR6XBJ)yJt4@Y!Mq0VZ`Emm}t?j0p_d&O8a{AI>@i5TAUwh9fm4J$F|AoMx zEsgb0F3&cyv+m=7*!c$p?e}DF+aW8yDzE2mf8V{a&-^e{i#4f|IAl>a)V}+oox1;W zylqEjQTZkmcGsnBJWRT38(9{CGOJUp84J}=XDaKwdGjXpGi^V|#2pWG9M5mW0w` zS1BRcmqd{^Nw$;}!i0Kn^}NUL_s8$}9mo6E_dSmLxbJhW`<(N)T07y7z?#1MU5Euh81 z-=9f!p^|OrfOnK0)Ib}m4>W7qpdE2obsbAUX3`l{;9*7eVz9UVVo3{Rvw#*9OjjGM ztqajL(1sZT?G7YwQXu{Rva&T89yO3dXZ!sb3k0gIrw#qnYbuxI^QV;q@o=`X_VdES zuzD0boCk*PO#7q54fUt~(eYukeVBkx9d#%Yh~>XQ1MJiP4HKRn3^BBHrf^}-UNnC= z!snQu>mPMJXA0iekmG~214DQWvXw8*&MyeB&wx7N0-c=#m}Isg2ZM0s;%Q_!oecCD z#bY5X(6AsDokD;G;_baKL1Z|>S{LdIL+b={s4zf<6GCGVAxujYjt4`bxilvZ&l2t$ z!mxwckP!Cva7P^8-#XX_;fkcXSmTLgB*L2wcZO3D6p{^`?(5@E@b$vk+E}mvTS!Zc ztrrJ|*VS<&6JR7=rXv=K2t-irgMxhQd>9Tau%mD2R=k6)8DS1#w!wDZVYZI;SYNUQ zmTikc+q>BZ*r)6I^^43^p>10pURX?YI;qn@!LG6yZ2G3$_D8SI?56W9#G=q!VD_>!i!J z=Y#}f19@0F3uz5E46mj>XTTG6qGfWs|TzZloQU`%bs9h zWk}!vrmcyLAQqXyaU|Gcur7gUl)gRG8;Y``IAhS504ID1hQdIB@rHhQKN|-_R|~hW z05@A?C`-q|KnLoGWB3FF`GxRoz`oWPU|GPazC^>VV4xhWtg%=Yho)zXrEz`H1av3| z2fRmdLolH*OK(8bweYquv;hQt2-};B3=E+1Al`ItpbyWBi*TV}z*qvt--+j_XJJ9r z0VD9CTzyoiE`ea}5Nu5%B7I3t_EblHW4gp@lJRsrWczg)V58;X+1M3Tp33MYvb?s4J)Ic^<7tIbvZ-vyEJi!A4{yU3*r!?^UUxb7rNs;+%0Rh>Y7=(pm$m#ifTbh%Vd`D;8 z87(*EA%aM?1)3Lg4yoMT3d*#*0T;tTx{F12^DV)8?NM#}9ZJb+e|fdV<@s8xc2IAg znuQA=y8zc$e<>mB)NE`ja=D zyNwa+E4L?*LTct)*G|b%I0=)WmZvNzbx2U^sfZ>>S7b{%6oc4lN0e&s?m$P20GB4H zF6OyZ&ZSHC2M->+A2mEY?91ahJ2^XRjCj;V@fWFYzl=Q$A08hs@(U-E;jDK}Ce`a` zO9q1x`c`;zZS6z4bi{O^}5CKG$bkHe|`vDkb31=473{bjAs_l3ON+~>Ato0Ia@De37}zMV(yZr;4eqhI4$~*EVr;Zy$!c)Ze)?SND9t?3aQj$bXH0=fghPWgkC3 z{5xT};;MAhALw1Z?B>m~FK-&I{`xi1zH9R?&@D%^cmuM9@xFcg+)5CRg9axIj!U8C z1;uP$p<*|?_wLOAyL|C4k;-a$lzs8yr@~)rA0+0BBX^eEJq`lR zI`}R$|7!a2^|3^){?a#t9m?8#tOUOH;op1$M#Pe%98)I=#E*p-EqpHhwXC=?ekb9V zz~@6dVH)P7fZaL$a!P`1-MGV(sIYIT&_YckU^rafEzIxa8n=vYh1YJSlAsj&fF>4~rz*O3rFp=&mG`Lvq^4Z;FPoIgYgevVC|OM- zh3Lw_xO&l5N@A@#U~rMf;lt3%qMhhIgL#7|B;%S>Ux}a z;d)V78R~ryWU)aiaqmVGbo+dPaWEc-!+i|Cbj8f)$z^*vZTF|Fu3oi=*LwTTQyZF+ zQKpuvg~|NM^S1k|VYSx!3UNR$#Pmi2;DltgNiQ;JfAmU%R;&iA$_v zcMlJbY3W7(vEJTZqrY_WoB6r>1AYz^n!Qk}K*&ouz5nIEINb{tM429Z_wr>qQfxDF zV=Z8MzIXA&bT3pncj#^rZ%Uev7Pa>HilRi?4J8`Z4DJUI3Nl{pTO+cuLhM7g9R+2o zNY5Nkd-Hjp$kpa%539YW<5Sn)mu6qRdiBS?m5Gi1ACc?(Ek1%Au78bkPhj?;(Q`eF z_0oZc6`MZZ!&SUaefDQsO+5jaX|1V2+n2SXrLAg5T8vvMONx@o2Bj3#j%hh+_b1Oo zpy_F|%lxjcgt@snLP&L~f%x_lk;PN{M3->AnLO!1ICts$3y)8_IgJxao7urB%3>L- z5pnfLGtM=*+LADrBx{Xx1>)k)p8HEEvUMUA)*6d!>L4oc>>>=E&eFy!n|}_8inj4* zl8Aj>LQ@5%5xIPQG_+>#;H&1S=CNlPk45z*Z7O&Ns!KZDUuGz5L3sM}y=WEkH?d^? zLyfV7Z4%la4fxZjs%-X-ZC`&CUiV=YmtF=InXjJomHTL(I8I?F zhJ(r>B;KTlkc@0D+;_*?e02_6Z{=B1Fx5tm#-^DZ9t?SjfeINFzgp%QZP9g6#d8UlLXyNi73Uw>Y&?4= zE;&UYuC#0Wg>=iUB#Yaco#h>0e*&_a9R(OVQorbLg{_p+)CH39idFRL;jLn(q6#S1 z2u^)CC$RIJ`4ynFiJ1sBn(YLB${YX`GsHEO;V!>n3Wvg!~ls})CE9)64RUy z`)!{FU>`hPV8M3FH4+6VQiOXtw<>20T)L=ACQKwG>bGkhKv6~B&UDXj`@rOuK2>d5 zKfmQV0{|46m(hy>TR>2>Rd3@I1;+}vTqglTQ{N_hpW2%(v#gSTDr9|yWn_G3XBhH< zn4;RNtdqiJRrjVC!$t}M;t?iC0;_cjTi}y3>1W+1US{D~V#(s_omAQ^S3nz^!b3g? zB)RCb2t=l)p|+){x#)On8_lKes2q>_Oe3!SY~}|YuE75;)w0vX>6sa)h=|SmK6F1n zXDAeUqp|VLwBatd>7J~kbF+h2eLK?*Hf^GN1XEH|%afAChR4Pfe>7?)GeSaO4m>&? zlm7>?kQ4Xs+$q~GD(d9pbM3~>o4e*Mi7_Sja#kNf@6^|q%NzKq4RsC=I}N{kSJ?oN zn6oB?;;46;4|=XWEA@4WOlcdDm6g?r`ts$Av$V9d@A}Go46#&E>@q9>e$X%w!76Fq zReMxE9R08=MJeepu+1O!Mv)u$j3Rz48^vH+W6tygBxD$v35`uZ7e zq;Gju8kB`Y$~6s~nKZ?eD_4|*##;pAhJo!&eQtjK@cA)!i!QOETeq;rIcLvqKN`;z z9zHq!s-7`7*?oSlKhHo+<;?meA!#dO?BfEH@MYHd6k;E3@WGIj@?#TZ-$qACW##e5 zW*)qNduwlZZOR`wFnF{D;6?bLpdk7K@B#Sc0F&?)?EKh6%f}MJlii8|sdxn5ek8zl-`6F><13*i4?J zrT;)|BEyCVFuuCxm}WTlIC*GvG^hLN7Hs4hu)SZZ7PCe(Uqq394)pgU3mDVT*q2$U z5oLHHrI;U=GM1S7s3lG?v$?*mZnh9Y+^>5f^v5zC<*!C1Rfs*^9{FW<)?YTT6{E~L z!+3p%P>((s_0i~y>_X^V*5~qbw=-cQ~-gkBvwYBx9J1V!X z%CqxM0YcPPy;@{>-!ry**w+=|=Cx zU^P0axdaZ?Wnx3QYV2FODyW_2(h!S`HSg(C+5KVuFo+xlfN^Aho!K`J zA|j9TtmEVB3*A%~3$2LSx0hRWjErs^?nJqRVbXQ)Odh65pZ~Ek|Jq0*^y84ahv=d8 z?ZD!HcGDXA?&HO~x}tB`?86vYfXX?=?>RVhG*xZP?{Z~T*W8=GHApr0?&YZO_SdB; zZ8tG7$=`P%5uKRvSkfePQEl;b>hj_47ft^h|Ix&LXZmn<@9UUU8?LhbO+@qFc2Nn% z+2$7`BfcjsL!oA0PGz0h=A3^|(Jb<^BsoB4?O}>^sm8pKTj&zL7^lF36)M%<~YL+2ALf9ji>7ErsS<{x2_s>Xv8 zTK6cKDlq;z(Vc*l-JPyz(t{Plod5Fnfx*#(zGA(=WGzp=1&U(WOn&f4sm;UIGxzt( zxbNK$?N=66$C9dXr?&S~E=ndJ2$)s{%`%=|*^6MeQ(PKO-10E;fUT^oOz*2UCvNN+ z$stoYw8M^)KaY*;lB?%qlLJZNpg>#fr`l{x;m)c+l9X)Sxe~l?c0~y zQ#RgV_0~&UJq_gFH@AN7@z%bkP3|71n{|Hd$0b*NepPQXQ}NE;HXw|i2^ON zRmwna&rFVO)JBJimbUkgZujABNYd$RbBC>mJgN;!M%C^wy>4D#dCeXMR&&r1{qp|s zi@YgoVp4xaYixU7lg?_Ix{Z+1@bl*-w#nN8-*@GM)-?MnlJLY0#V%vP#yqnAUiXVT zjpYh12!A(z<2k+Za1d9KuN5VhIQ^p!!F?i)Z7TFJxWut|8YX&Rqu^2LsVS*! z_d%P{D|=r#xih#PW_=aRu&Qzu*#+Umi4T)WB@#oLAd+x~tmt1O1F1j5uQVi}$CtDF z;{!H}<-iH>IIt_O7lkwwjnEVq{JuM z)wx^cF7d$m!M*cIys6d-=BtvbQM*9*vwNcVw8SM2R?u9uKlha3{*=*Kfms3foc;ef zRrjX3R{<~b4GP;{?1U{)tl8!O3D^&ifUBhd3Fsa9O;08PdSdO@#c$c7C*#=yaqY)E z?%=oBiMkcQP692Th-z%@KkfoF!;fDR^qZU*0^}r9KF}1rMNaOi0~?v%i?@GslWu^U zTzGSCDQ3%f%P~Q*>jEnrXR?XuA_Gdp6pFsqTIzpnmk1Lvuq~W7mrScClj5N$U_e+5J?H@W{4FVjj zxYi5TDKfkNgP=xp$Oh5)-~H3a9D##gCt4=u(v=uihs}ZMOVc|jUF4M_nzJ$S&1-%Z za69<2y39+6oAOQIyvK>iTL<$2?qp;d~lRMMvuL7J5;nSI$w(}{ZLm2!2 z>s+SjgFgog%@ru%3?Uad=9rqA3a#rXcByc;w@O!ZGUk2$8uxw(lJeMNkQn8GG_i^he{o*|xrMGVbixfohd-3+|Z4C{L=K#J7KREQ= zZoDl~daf%&^@ih2&}d`b0jsT5Sg6B?l_lKO{NbB3Tj|m4+?lTAa?Q5z^kHy?f@;T? z&o67|0O$jlX06VSww9LY+{>38fxT9bb4xYY{q*UPka(W(MNWKY=!WiVb; zl%GFrd&7V|rkSv#;H^wfNgT3+4jhu?+GGMy+8^f9r9!!PE#XpO|MK_m)X%DkF*dm# zQW1e~QQD;P8#jiQ#FnJ&ixV(jUS1l~gU_B_^&4v}f589z5?UX=`UNX8nSZV7YC}T< zqO(s=DR1TRbSX|=CR^b`oAO%R(3q2Wij3TDm!Bg;L&Z^NB_HS5Pk(%N?Z6|8BimHG zDzg7ne9c5V1?k|RAg5ZORihl;UdnqUn6rI$b>nnrY}U~H>$^dbD?_C=KtydSdDzDn z8aJxFI=LcV(=nTi4bzCPuU~781iZW-bkm4Cd+xM&8IpL;Xz8?$cXD#FYisoEwiQ9h zrGkPdNhyeuHbaYqf)k-qp_LjJ#V<^}*y9P>AdtF*y5Ixy)gn7>SgiT`n}4MkP8)XE z>+C9Rb)BBtTwk?3C83%ft0G&Xk3yliT%k@O`^fKePDNGj55x4HUILT(QP#{_1V}>3 z^m)d0ghEa9ekG-WKy#^7G8NQ%=G}Wk;LYVVjmUBosH`fdFFZVaDT#Op6e+5!mg?H4 z#keMEa~+h0j;S({eI#Jf5V?8ZDCBFAzGour+?SRC?<2bDROQADN`G-^~=B^JF*lb%O2y1i6MxF7ARnqxOZy$nbOJg zLEQs)B;-$Nf4)~u5eCZvM}Nzhwj#&a&|v}Z-OJ*GFyAiuBE0c05V-k2$VhapM|sk5!RZQH>SN&N4a Date: Mon, 27 Jul 2020 03:16:32 +0200 Subject: [PATCH 081/110] Updated example README. --- examples/publish subscribe/README.md | 13 ++++++++++++- examples/request reply/README.md | 10 ++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/examples/publish subscribe/README.md b/examples/publish subscribe/README.md index 46fe164a5..f25793a49 100644 --- a/examples/publish subscribe/README.md +++ b/examples/publish subscribe/README.md @@ -3,8 +3,19 @@ Publish and subscribe

+ +# How to run it + +1. Run the docker-compose file `../docker-compose.yml` or run the NATS server your self locally on the standard port. +2. Install the dependencies `npm i` +3. Run the local test with `npm run start` + + + +# Description + This example contains two channels are: `streetlight/{streetlight_id}/command/turnon` which are for subscribing to the command `turnon`. The generated client interprets this as the NATS topic `streetlight.{streetlight_id}.command.turnon`. The `{streetlight_id}` is the channel parameter which are not realized before actually subscribing to anything. When a message is received on channel `streetlight.1.command.turnon` it can automatically interpret what the `streetlight_id` parameter is. -`streetlight/{streetlight_id}/event/turnon` which are for publishing when the light is acutally turned on. +`streetlight/{streetlight_id}/event/turnon` are for publishing when the light is acutally turned on. diff --git a/examples/request reply/README.md b/examples/request reply/README.md index 9355a8fce..3abf8f867 100644 --- a/examples/request reply/README.md +++ b/examples/request reply/README.md @@ -3,6 +3,16 @@ Request and reply

+ +# How to run it + +1. Run the docker-compose file `../docker-compose.yml` or run the NATS server your self locally on the standard port. +2. Install the dependencies `npm i` +3. Run the local test with `npm run start` + + + +# Description This example contains two channels are: `streetlight/{streetlight_id}/command/turnon` which are for replying to the command `turnon`. The generated client interprets this as the NATS topic `streetlight.{streetlight_id}.command.turnon`. The `{streetlight_id}` is the channel parameter which are not realized before actually subscribing to anything. When a message is received on channel `streetlight.1.command.turnon` it can automatically interpret what the `streetlight_id` parameter is. From 3f32dbd2d1ae48449bccb089f86b20a70518b774 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 27 Jul 2020 12:25:06 +0200 Subject: [PATCH 082/110] Updated README.md --- README.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 962d37ffd..2ea723a31 100644 --- a/README.md +++ b/README.md @@ -51,14 +51,16 @@ async function connect(){ connect(); ``` -or use it directly where needed. - # Features * Supports wildcard channels. AsyncAPI describes the channel path to be defined as [RFC 6570 URI](https://www.asyncapi.com/docs/specifications/2.0.0/#a-name-channelsobject-a-channels-object). So a channel containing a wildcard needs to be defined as `smartylighting/streetlights/*`. This also works with parameters such as `smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured`, ensure to define the type of the parameter as a String if you want to use wildcards. * Supports [test/mirror client](#test-client) for testing or other useful scenarios. * This template can be used as a javascript library as well since the generated code works directly in Node.js. * This template uses [quicktype](https://quicktype.io/) to generate the corresponding message payloads. +# Restrictions +* Empty objects are not supported, use `null` types instead. +* This template has not been tested with payloads with different specs other then JSON Schema draft 7. + # Connection options Currently the generated client offers 4 standard methods of connecting to your NATS server `connectWithUserCreds`, `connectWithUserPass`, `connectToHost` and `connectWithNkey`. If you need something customized use the standard `connect` method with your custom options. Currently the template does not care which security details you have defined in your AsyncAPI document. @@ -191,7 +193,7 @@ natsClient.on(AvailableEvents.yield, () => { These are the available template parameters: |Parameter|Type|Description| |---|---|---| -| generateTestClient | Boolean | Use this parameter to generate the [test client](###test-client). Add the following to the CLI when generating your code `--param "generateTestClient=true"` +| generateTestClient | Boolean | Use this parameter to generate the [test client](#test-client). Add the following to the CLI when generating your code `--param "generateTestClient=true"` | promisifyReplyCallback | Boolean | Use this parameter to change from the default regular callback when using the request operation. Add the following to the CLI when generating your code `--param "promisifyReplyCallback=true"` # Test Client @@ -206,7 +208,7 @@ The following payload types are supported, this is limited to the underlying NAT # Client Hooks -Sometimes to you want to change the data before sending or reciving it. For this purpose hooks has been added to control the flow of information outside the generated code. The hooks can be used to alter the payload before sending or after recieving any data i.e. encrypt, compress data, etc. It is possible to register as many hooks as you want however there are certain restrictions. +Sometimes to you want to change the data before sending or reciving it. For this purpose hooks has been added to control the flow of information outside the generated code. The hooks can be used to alter the payload before sending or after recieving any data i.e. encrypt, compress data, etc. It is possible to register as many hooks as you want however there are certain restrictions, see [hook restrictions](#Hook-restrictions). These are the available hooks: @@ -248,8 +250,3 @@ The first hook always receive the message type as is. Any intermediary hooks can ### String payloads The first hook always receive the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return a string representation of the message. - -# Restrictions -* Empty objects are not supported, use `null` types instead. -* This template has not been tested with payloads with different specs other then JSON Schema draft 7. -* \ No newline at end of file From cf71b16bdf1340da7c51c25c9b7d22b62c5e21f1 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 27 Jul 2020 12:48:39 +0200 Subject: [PATCH 083/110] Added function comments to filters/all.js --- filters/all.js | 66 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/filters/all.js b/filters/all.js index a989c6d8c..3c70f3915 100644 --- a/filters/all.js +++ b/filters/all.js @@ -31,8 +31,9 @@ filter.isJsonPayload = (messageContentType, defaultContentType) => { filter.messageHasNotNullPayload = (messagePayload) => { return messagePayload.type()+"" != "null"; } + /** - * Because quicktype cant handle null provide custom message type. + * Because quicktype cant handle null types we have to ensure if it is null thats */ filter.getMessageType = (message) => { if(message.payload().type()+"" == "null"){ @@ -43,7 +44,7 @@ filter.getMessageType = (message) => { } /** - * Figure out if a payload is located in the document. + * Figure out if a content type is located in the document. * @param {*} document to look through * @param {*} payload to find */ @@ -117,6 +118,11 @@ filter.camelCase = string => { return camelCase(string); } +/** + * Convert JSON schema draft 7 types to typescript types + * @param {*} jsonSchemaType + * @param {*} property + */ function toTsType(jsonSchemaType, property) { switch (jsonSchemaType.toLowerCase()) { case 'string': @@ -136,6 +142,9 @@ function toTsType(jsonSchemaType, property) { } } +/** + * Convert RFC 6570 URI with parameters to NATS topic. + */ filter.realizeChannelName = (parameters, channelName) => { let returnString = '\`' + channelName + '\`'; returnString = returnString.replace(/\//g, `.`); @@ -144,20 +153,14 @@ filter.realizeChannelName = (parameters, channelName) => { } return returnString; } + filter.realizeChannelNameWithoutParameters = (channelName) => { - return toNatsChannel(channelName, null) + return realizeChannelName(null, channelName); } -function toNatsChannel(channelName, parameters){ - let returnString = '\`' + channelName + '\`'; - returnString = returnString.replace(/\//g, `.`); - if(parameters){ - for (paramName in parameters) { - returnString = returnString.replace(`{${paramName}}`, `\${${paramName}}`); - } - } - return returnString; -} +/** + * Realize parameters without using types without trailing comma + */ filter.realizeParametersForChannelWithoutType = (parameters) => { let returnString = ''; for (paramName in parameters) { @@ -168,6 +171,10 @@ filter.realizeParametersForChannelWithoutType = (parameters) => { } return returnString; } + +/** + * Realize parameters using types without trailing comma + */ filter.realizeParametersForChannel = (parameters, required = true) => { let returnString = ''; const requiredType = !required ? '?' : '' @@ -182,6 +189,16 @@ filter.realizeParametersForChannel = (parameters, required = true) => { return returnString; } +/** + * Does an object have bindings + */ +filter.hasNatsBindings = obj => { + return obj.bindings && obj.bindings.nats; +} + +/** + * is the channel a publish and subscribe type if nothing is specified default to being pubsub type + */ filter.isPubsub = channel => { const tempChannel = channel._json; if ( @@ -193,9 +210,10 @@ filter.isPubsub = channel => { } return false; } -filter.hasNatsBindings = obj => { - return obj.bindings && obj.bindings.nats; -} + +/** + * is the channel a request and reply + */ filter.isRequestReply = channel => { let tempChannel = channel._json; if ( @@ -207,12 +225,14 @@ filter.isRequestReply = channel => { } return false; } + +/** + * Is the request reply a requester + */ filter.isRequester = channel => { let tempChannel = channel._json; if ( - tempChannel.bindings && - tempChannel.bindings.nats && - tempChannel.bindings.nats.is == 'requestReply' && + isRequestReply(channel) && tempChannel.bindings.nats.requestReply && tempChannel.bindings.nats.requestReply.is == 'requester' ) { @@ -220,12 +240,14 @@ filter.isRequester = channel => { } return false; } + +/** + * Is the request reply a replier + */ filter.isReplier = channel => { let tempChannel = channel._json; if ( - tempChannel.bindings && - tempChannel.bindings.nats && - tempChannel.bindings.nats.is == 'requestReply' && + isRequestReply(channel) && tempChannel.bindings.nats.requestReply && tempChannel.bindings.nats.requestReply.is == 'replier' ) { From d69492b5f84b6bc0ac8e7cd57b6a9343e9868933 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 27 Jul 2020 12:49:31 +0200 Subject: [PATCH 084/110] Added comments to rename-njk.js --- hooks/rename-njk.js | 1 + 1 file changed, 1 insertion(+) diff --git a/hooks/rename-njk.js b/hooks/rename-njk.js index 65bb2c668..ffcb4a641 100644 --- a/hooks/rename-njk.js +++ b/hooks/rename-njk.js @@ -2,6 +2,7 @@ const fs = require('fs'); const path = require('path'); /** + * Rename all the generated files whos extension is .njk * * @param {string} dir to recursively rename files with njk extension */ From e6a76142bab9792759d8f9f85ebba8f4f76ad43b Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 27 Jul 2020 13:36:52 +0200 Subject: [PATCH 085/110] Fixed refactor error with undefined function. --- examples/publish subscribe/streetlight/src/index.ts | 12 ++---------- .../streetlight/src/tests/testclient/index.ts | 11 +---------- filters/all.js | 4 +++- 3 files changed, 6 insertions(+), 21 deletions(-) diff --git a/examples/publish subscribe/streetlight/src/index.ts b/examples/publish subscribe/streetlight/src/index.ts index 9545944d0..03128a0bf 100644 --- a/examples/publish subscribe/streetlight/src/index.ts +++ b/examples/publish subscribe/streetlight/src/index.ts @@ -86,7 +86,8 @@ export class NatsAsyncApiClient extends events.EventEmitter{ */ connect(options : NatsConnectionOptions): Promise{ return new Promise(async (resolve: () => void, reject: (error: any) => void) => { - this.options = this.setDefaultOptions(options); + this.options = options; + console.log(this.options) try{ if(!this.jsonClient || this.jsonClient!.isClosed()){ this.options.payload = Payload.JSON; @@ -207,15 +208,6 @@ export class NatsAsyncApiClient extends events.EventEmitter{ }); } - /** - * Set the default options based on the AsyncAPI file. - * @param options to set - */ - private setDefaultOptions(options: NatsConnectionOptions){ - //If server binding options sat set the options - options.encoding = 'utf8'; - return options; - } /** diff --git a/examples/publish subscribe/streetlight/src/tests/testclient/index.ts b/examples/publish subscribe/streetlight/src/tests/testclient/index.ts index 6bf56380d..38f4bda47 100644 --- a/examples/publish subscribe/streetlight/src/tests/testclient/index.ts +++ b/examples/publish subscribe/streetlight/src/tests/testclient/index.ts @@ -78,7 +78,7 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ */ connect(options : NatsConnectionOptions): Promise{ return new Promise(async (resolve: () => void, reject: (error: any) => void) => { - this.options = this.setDefaultOptions(options); + this.options = options; try{ if(!this.jsonClient || this.jsonClient!.isClosed()){ this.options.payload = Payload.JSON; @@ -199,15 +199,6 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ }); } - /** - * Set the default options based on the AsyncAPI file. - * @param options to set - */ - private setDefaultOptions(options: NatsConnectionOptions){ - //If server binding options sat set the options - options.encoding = 'utf8'; - return options; - } /** diff --git a/filters/all.js b/filters/all.js index 3c70f3915..7eb5f8485 100644 --- a/filters/all.js +++ b/filters/all.js @@ -145,7 +145,7 @@ function toTsType(jsonSchemaType, property) { /** * Convert RFC 6570 URI with parameters to NATS topic. */ -filter.realizeChannelName = (parameters, channelName) => { +function realizeChannelName(parameters, channelName){ let returnString = '\`' + channelName + '\`'; returnString = returnString.replace(/\//g, `.`); for (paramName in parameters) { @@ -154,6 +154,8 @@ filter.realizeChannelName = (parameters, channelName) => { return returnString; } +filter.realizeChannelName = realizeChannelName; + filter.realizeChannelNameWithoutParameters = (channelName) => { return realizeChannelName(null, channelName); } From 8ee1c7038af97309218a28312c7ece7b348e9dae Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 27 Jul 2020 13:39:29 +0200 Subject: [PATCH 086/110] Fixed another refactor error with undefined functions. --- filters/all.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/filters/all.js b/filters/all.js index 7eb5f8485..ee6b44952 100644 --- a/filters/all.js +++ b/filters/all.js @@ -216,7 +216,7 @@ filter.isPubsub = channel => { /** * is the channel a request and reply */ -filter.isRequestReply = channel => { +function isRequestReply(channel){ let tempChannel = channel._json; if ( tempChannel.bindings && @@ -227,6 +227,7 @@ filter.isRequestReply = channel => { } return false; } +filter.isRequestReply = isRequestReply; /** * Is the request reply a requester From 5cd9931a096933e18a5a25e819c331c54b817c91 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 27 Jul 2020 19:42:33 +0200 Subject: [PATCH 087/110] Changed generator requirement to current version of the generator. --- README.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2ea723a31..40b9ad180 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This template is for generating a TypeScript/Node.js NATS client based on an Asy # How to use Example generations can be found under [examples](./examples) which includes [publish and subscribe](./examples/publish%20subscribe) example as well as [request and reply](./examples/request%20reply). ## Requirements -* @asyncapi/generator v1.0.0 +* @asyncapi/generator <= v1.0.0-rc.5 Install the generator through [npm or run it from docker official installer](https://github.com/asyncapi/generator#install). diff --git a/package.json b/package.json index 7eb746bb1..36a495c34 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "required": false } }, - "generator": ">=0.50.0 <2.0.0", + "generator": ">=0.50.0 <=1.0.0-rc.5", "filters": [ "@asyncapi/generator-filters" ] From 9a335eac8edf93d8080422e36309e713007a2743 Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Mon, 27 Jul 2020 19:43:08 +0200 Subject: [PATCH 088/110] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fran Méndez --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 40b9ad180..fa056c742 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Given any AsyncAPI file (`AsyncAPI.yml`) first generate the client with the [Asy ag --install --output ./nats-client ./AsyncAPI.yml @asyncapi/ts-nats-template --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" ``` -Afterwards `cd` into the generated folder `nats-client` and run the commands `npm i` and `npm run build`. The generated NATS client is now ready to be used in either TypeScript or Node.js. +Afterward, `cd` into the generated folder `nats-client` and run the commands `npm i` and `npm run build`. The generated NATS client is now ready to be used in either TypeScript or Node.js. ### TypeScript @@ -249,4 +249,3 @@ The first hook always receive the message type as is. Any intermediary hooks can ### String payloads The first hook always receive the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return a string representation of the message. - From 23a67e8077e2cfb347e0cb0477b58b01f725493e Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Mon, 27 Jul 2020 19:49:58 +0200 Subject: [PATCH 089/110] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fran Méndez --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fa056c742..c02d6fc32 100644 --- a/README.md +++ b/README.md @@ -245,7 +245,7 @@ There are different hook restrictions based on the payload type. Binary payloads are a bit special since you are required to at least provide 1. hook for both receiving data and when sending data since no standard way of converting a message type to a buffer has been implemented. The first hook always receive the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return the buffer representation of the message. ### JSON payloads -The first hook always receive the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return the correct message type. +The first hook always receives the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return the correct message type. ### String payloads The first hook always receive the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return a string representation of the message. From a5d3d36c74258282fe7ec0a86b50c176cc46c724 Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Mon, 27 Jul 2020 19:50:35 +0200 Subject: [PATCH 090/110] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fran Méndez --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c02d6fc32..b82ae777e 100644 --- a/README.md +++ b/README.md @@ -248,4 +248,4 @@ Binary payloads are a bit special since you are required to at least provide 1. The first hook always receives the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return the correct message type. ### String payloads -The first hook always receive the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return a string representation of the message. +The first hook always receives the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return a string representation of the message. From e1013222b17751e545e7909ba7c604c6110c7dbf Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 27 Jul 2020 19:53:32 +0200 Subject: [PATCH 091/110] Changed README.md to use 2 spaces instead of tabs. --- README.md | 140 +++++++++++++++++++++++++++--------------------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/README.md b/README.md index b82ae777e..d56498740 100644 --- a/README.md +++ b/README.md @@ -28,11 +28,11 @@ Afterward, `cd` into the generated folder `nats-client` and run the commands `np import * as GeneratedClient from "./nats-client"; const natsClient = new GeneratedClient.NatsAsyncApiClient(); async function connect(){ - try{ - await natsClient.connect({url: "nats://demo.nats.io:4222", reconnectTimeWait: 1000, reconnect: true, maxReconnectAttempts: -1}); - }catch(e){ - console.log(e); - } + try{ + await natsClient.connect({url: "nats://demo.nats.io:4222", reconnectTimeWait: 1000, reconnect: true, maxReconnectAttempts: -1}); + }catch(e){ + console.log(e); + } } connect(); ``` @@ -42,11 +42,11 @@ connect(); const GeneratedClient = require("./nats-client"); const natsClient = new GeneratedClient.NatsAsyncApiClient(); async function connect(){ - try{ - await natsClient.connect({url: "nats://demo.nats.io:4222", reconnectTimeWait: 1000, reconnect: true, maxReconnectAttempts: -1}); - }catch(e){ - console.log(e); - } + try{ + await natsClient.connect({url: "nats://demo.nats.io:4222", reconnectTimeWait: 1000, reconnect: true, maxReconnectAttempts: -1}); + }catch(e){ + console.log(e); + } } connect(); ``` @@ -73,57 +73,57 @@ import {AvailableEvents, NatsAsyncApiClient, NatsTypescriptTemplateError, Client const natsClient = new NatsAsyncApiClient(); natsClient.on(AvailableEvents.permissionError, (e: NatsTypescriptTemplateError) => { - console.log("NatsAsyncApiClient permissionError"); - console.log(e); + console.log("NatsAsyncApiClient permissionError"); + console.log(e); }); natsClient.on(AvailableEvents.close, (e: NatsTypescriptTemplateError) => { - console.log("NatsAsyncApiClient close"); - console.log(e); + console.log("NatsAsyncApiClient close"); + console.log(e); }); natsClient.on(AvailableEvents.connect, (connection: Client, serverURL: string, info: ServerInfo) => { - console.log("NatsAsyncApiTestClient connect"); - console.log({connection, serverURL, info}); + console.log("NatsAsyncApiTestClient connect"); + console.log({connection, serverURL, info}); }); natsClient.on(AvailableEvents.connecting, (serverURL: string) => { - console.log("NatsAsyncApiClient connecting"); - console.log(serverURL); + console.log("NatsAsyncApiClient connecting"); + console.log(serverURL); }); natsClient.on(AvailableEvents.disconnect, (serverURL: string) => { - console.log("NatsAsyncApiClient disconnect"); - console.log(serverURL); + console.log("NatsAsyncApiClient disconnect"); + console.log(serverURL); }); natsClient.on(AvailableEvents.error, (e: NatsTypescriptTemplateError) => { - console.log("NatsAsyncApiClient error"); - console.log(e); + console.log("NatsAsyncApiClient error"); + console.log(e); }); natsClient.on(AvailableEvents.pingcount, () => { - console.log("NatsAsyncApiClient pingcount"); + console.log("NatsAsyncApiClient pingcount"); }); natsClient.on(AvailableEvents.pingtimer, () => { - console.log("NatsAsyncApiClient pingtimer"); + console.log("NatsAsyncApiClient pingtimer"); }); natsClient.on(AvailableEvents.reconnect, (connection: Client, serverURL: string, info: ServerInfo) => { - console.log("NatsAsyncApiClient reconnect"); - console.log({connection, serverURL, info}); + console.log("NatsAsyncApiClient reconnect"); + console.log({connection, serverURL, info}); }); natsClient.on(AvailableEvents.reconnecting, (serverURL: string) => { - console.log("NatsAsyncApiClient reconnecting"); - console.log(serverURL); + console.log("NatsAsyncApiClient reconnecting"); + console.log(serverURL); }); natsClient.on(AvailableEvents.serversChanged, (e: ServersChangedEvent) => { - console.log("NatsAsyncApiClient serversChanged"); - console.log(e); + console.log("NatsAsyncApiClient serversChanged"); + console.log(e); }); natsClient.on(AvailableEvents.subscribe, (e: SubEvent) => { - console.log("NatsAsyncApiClient subscribe"); - console.log(e); + console.log("NatsAsyncApiClient subscribe"); + console.log(e); }); natsClient.on(AvailableEvents.unsubscribe, (e: SubEvent) => { - console.log("NatsAsyncApiClient unsubscribe"); - console.log(e); + console.log("NatsAsyncApiClient unsubscribe"); + console.log(e); }); natsClient.on(AvailableEvents.yield, () => { - console.log("NatsAsyncApiClient yield"); + console.log("NatsAsyncApiClient yield"); }); ``` ## Node.js example @@ -131,61 +131,61 @@ natsClient.on(AvailableEvents.yield, () => { const {AvailableEvents, NatsAsyncApiClient} = require("nats-client"); const natsClient = new NatsAsyncApiClient(); natsClient.on(AvailableEvents.permissionError, (e) => { - console.log("NatsAsyncApiClient permissionError"); - console.log(e); + console.log("NatsAsyncApiClient permissionError"); + console.log(e); }); natsClient.on(AvailableEvents.close, (e) => { - console.log("NatsAsyncApiClient close"); - console.log(e); + console.log("NatsAsyncApiClient close"); + console.log(e); }); natsTestClient.on(AvailableEvents.connect, async (connection, serverURL, info) => { - console.log("NatsAsyncApiTestClient connect"); - console.log({connection, serverURL, info}); + console.log("NatsAsyncApiTestClient connect"); + console.log({connection, serverURL, info}); }); natsClient.on(AvailableEvents.connect, (connection, serverURL, info) => { - console.log("NatsAsyncApiClient connect"); - console.log({connection, serverURL, info}); + console.log("NatsAsyncApiClient connect"); + console.log({connection, serverURL, info}); }); natsClient.on(AvailableEvents.connecting, (serverURL) => { - console.log("NatsAsyncApiClient connecting"); - console.log(serverURL); + console.log("NatsAsyncApiClient connecting"); + console.log(serverURL); }); natsClient.on(AvailableEvents.disconnect, (serverURL) => { - console.log("NatsAsyncApiClient disconnect"); - console.log(serverURL); + console.log("NatsAsyncApiClient disconnect"); + console.log(serverURL); }); natsClient.on(AvailableEvents.error, (e) => { - console.log("NatsAsyncApiClient error"); - console.log(e); + console.log("NatsAsyncApiClient error"); + console.log(e); }); natsClient.on(AvailableEvents.pingcount, () => { - console.log("NatsAsyncApiClient pingcount"); + console.log("NatsAsyncApiClient pingcount"); }); natsClient.on(AvailableEvents.pingtimer, () => { - console.log("NatsAsyncApiClient pingtimer"); + console.log("NatsAsyncApiClient pingtimer"); }); natsClient.on(AvailableEvents.reconnect, (connection, serverURL, info) => { - console.log("NatsAsyncApiClient reconnect"); - console.log({connection, serverURL, info}); + console.log("NatsAsyncApiClient reconnect"); + console.log({connection, serverURL, info}); }); natsClient.on(AvailableEvents.reconnecting, (serverURL) => { - console.log("NatsAsyncApiClient reconnecting"); - console.log(serverURL); + console.log("NatsAsyncApiClient reconnecting"); + console.log(serverURL); }); natsClient.on(AvailableEvents.serversChanged, (e) => { - console.log("NatsAsyncApiClient serversChanged"); - console.log(e); + console.log("NatsAsyncApiClient serversChanged"); + console.log(e); }); natsClient.on(AvailableEvents.subscribe, (e) => { - console.log("NatsAsyncApiClient subscribe"); - console.log(e); + console.log("NatsAsyncApiClient subscribe"); + console.log(e); }); natsClient.on(AvailableEvents.unsubscribe, (e) => { - console.log("NatsAsyncApiClient unsubscribe"); - console.log(e); + console.log("NatsAsyncApiClient unsubscribe"); + console.log(e); }); natsClient.on(AvailableEvents.yield, () => { - console.log("NatsAsyncApiClient yield"); + console.log("NatsAsyncApiClient yield"); }); ``` @@ -224,16 +224,16 @@ const {AvailableEvents, NatsAsyncApiClient, Hooks} = require("nats-client"); const natsClient = new NatsAsyncApiClient(); const msgpack = require("msgpack-lite"); function encode(msg){ - console.log("encode"); - console.log(msg); - // encode from JS Object to MessagePack (Buffer) - return msgpack.encode(msg); + console.log("encode"); + console.log(msg); + // encode from JS Object to MessagePack (Buffer) + return msgpack.encode(msg); } function decode(msg){ - // decode from MessagePack (Buffer) to JS Object - console.log("Decoding"); - console.log(msg); - return msgpack.decode(msg.data); // => {"foo": "bar"} + // decode from MessagePack (Buffer) to JS Object + console.log("Decoding"); + console.log(msg); + return msgpack.decode(msg.data); // => {"foo": "bar"} } Hooks.getInstance().registerBeforeSendingData(encode); Hooks.getInstance().registerreceivedData(decode); From 0c53c4286a79524a4ac84bdbe728ab3d771b46ea Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Mon, 27 Jul 2020 19:55:14 +0200 Subject: [PATCH 092/110] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fran Méndez --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d56498740..bf6a5d1ae 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ connect(); # Restrictions * Empty objects are not supported, use `null` types instead. -* This template has not been tested with payloads with different specs other then JSON Schema draft 7. +* This template has not been tested with payloads with different specs other than JSON Schema draft 7. # Connection options Currently the generated client offers 4 standard methods of connecting to your NATS server `connectWithUserCreds`, `connectWithUserPass`, `connectToHost` and `connectWithNkey`. If you need something customized use the standard `connect` method with your custom options. Currently the template does not care which security details you have defined in your AsyncAPI document. From 3b7f1134265453c1318cfc6c4e180bbaabf4bf09 Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Mon, 27 Jul 2020 19:56:56 +0200 Subject: [PATCH 093/110] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fran Méndez --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bf6a5d1ae..3178eed4e 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ connect(); * This template has not been tested with payloads with different specs other than JSON Schema draft 7. # Connection options -Currently the generated client offers 4 standard methods of connecting to your NATS server `connectWithUserCreds`, `connectWithUserPass`, `connectToHost` and `connectWithNkey`. If you need something customized use the standard `connect` method with your custom options. Currently the template does not care which security details you have defined in your AsyncAPI document. +Currently the generated client offers 4 standard methods of connecting to your NATS server `connectWithUserCreds`, `connectWithUserPass`, `connectToHost` and `connectWithNkey`. If you need something customized use the standard `connect` method with your custom options. Currently, the template does not care which security details you have defined in your AsyncAPI document. # Available events The generated client can emit multiple events, all of these are directly from the [nats-ts](https://github.com/nats-io/nats.ts#notifications) library. Where the errors are wrapped in a custom `NatsTypescriptTemplateError` type. From 98e362bcc0e7705aecb7b5d2bcb97783463db8cb Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Tue, 28 Jul 2020 07:06:06 +0200 Subject: [PATCH 094/110] Added standard binary converter. Fixed problem with request/reply for test client which was reverted. Fixed a problem with default content type was not provided correctly. --- README.md | 2 +- examples/publish subscribe/streetlight/src/index.ts | 1 - .../streetlight/src/tests/testclient/index.ts | 8 ++++---- .../StreetlightStreetlightIdCommandTurnon.ts | 4 ++-- .../StreetlightStreetlightIdEventTurnon.ts | 2 +- partials/channel/OnReceivingData.njk | 6 ++---- partials/channel/OnSendingData.njk | 8 +++----- partials/index/Reply.njk | 10 +++++----- template/src/channels/$$channel$$.ts.njk | 8 ++++---- template/src/tests/testclient/index.ts.njk | 4 ++-- .../tests/testclient/testchannels/$$channel$$.ts.njk | 8 ++++---- 11 files changed, 28 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 3178eed4e..17fd49cda 100644 --- a/README.md +++ b/README.md @@ -242,7 +242,7 @@ Hooks.getInstance().registerreceivedData(decode); There are different hook restrictions based on the payload type. ### Binary payloads -Binary payloads are a bit special since you are required to at least provide 1. hook for both receiving data and when sending data since no standard way of converting a message type to a buffer has been implemented. The first hook always receive the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return the buffer representation of the message. +The first hook always receives the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return a buffer to transmit. ### JSON payloads The first hook always receives the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return the correct message type. diff --git a/examples/publish subscribe/streetlight/src/index.ts b/examples/publish subscribe/streetlight/src/index.ts index 03128a0bf..7267f36f2 100644 --- a/examples/publish subscribe/streetlight/src/index.ts +++ b/examples/publish subscribe/streetlight/src/index.ts @@ -87,7 +87,6 @@ export class NatsAsyncApiClient extends events.EventEmitter{ connect(options : NatsConnectionOptions): Promise{ return new Promise(async (resolve: () => void, reject: (error: any) => void) => { this.options = options; - console.log(this.options) try{ if(!this.jsonClient || this.jsonClient!.isClosed()){ this.options.payload = Payload.JSON; diff --git a/examples/request reply/streetlight/src/tests/testclient/index.ts b/examples/request reply/streetlight/src/tests/testclient/index.ts index c32c64f0a..970228514 100644 --- a/examples/request reply/streetlight/src/tests/testclient/index.ts +++ b/examples/request reply/streetlight/src/tests/testclient/index.ts @@ -208,11 +208,11 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ * @param requestMessage The request message to send. */ public requestStreetlightStreetlightIdCommandTurnon( - requestMessage:GeneralReplyMessage.GeneralReply + requestMessage:TurnonCommandMessage.TurnonCommand ,streetlight_id: string - ): Promise { + ): Promise { const nc: Client = this.jsonClient!; if(nc){ return streetlightStreetlightIdCommandTurnonChannel.request( @@ -236,8 +236,8 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ public replyToStreetlightStreetlightIdEventTurnon( onRequest : ( err?: NatsTypescriptTemplateError, - msg?: GeneralReplyMessage.GeneralReply,streetlight_id?: string - ) =>Promise, + msg?: AnonymousMessage3Message.AnonymousMessage3,streetlight_id?: string + ) =>Promise, onReplyError : (err: NatsTypescriptTemplateError) => void ,streetlight_id: string diff --git a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts index 4ee25be80..e89cf465a 100644 --- a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts +++ b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdCommandTurnon.ts @@ -6,12 +6,12 @@ import {ErrorCode, NatsTypescriptTemplateError} from '../../../NatsTypescriptTem import { Hooks } from '../../../hooks'; export function request( - message: GeneralReplyMessage.GeneralReply, + message: TurnonCommandMessage.TurnonCommand, nc: Client ,streetlight_id: string - ): Promise { + ): Promise { return new Promise(async (resolve, reject) => { var timeout = undefined; let msg; diff --git a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts index b35f47934..4cff6d078 100644 --- a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts +++ b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts @@ -6,7 +6,7 @@ import {ErrorCode, NatsTypescriptTemplateError} from '../../../NatsTypescriptTem import { Hooks } from '../../../hooks'; export function reply( - onRequest: (err?: NatsTypescriptTemplateError, msg?: GeneralReplyMessage.GeneralReply, streetlight_id?: string) =>Promise, + onRequest: (err?: NatsTypescriptTemplateError, msg?: AnonymousMessage3Message.AnonymousMessage3, streetlight_id?: string) =>Promise, onReplyError: (err: NatsTypescriptTemplateError) => void, nc: Client diff --git a/partials/channel/OnReceivingData.njk b/partials/channel/OnReceivingData.njk index c37da654d..584597326 100644 --- a/partials/channel/OnReceivingData.njk +++ b/partials/channel/OnReceivingData.njk @@ -7,10 +7,8 @@ try { receivedData = hook(receivedData); } {%- if message.contentType() | isBinaryPayload(defaultContentType) %} - if(receivedDataHooks.length == 0 ){ - let error = new NatsTypescriptTemplateError('Missing hooks to convert binary data', '000'); - onReplyError(error); - return; + if(receivedDataHooks.length == 0){ + receivedData = {{message.uid() | pascalCase}}Message.Convert.to{{message.uid() | pascalCase}}(receivedData.toString()); } {%- endif %} {%- if message.contentType() | isStringPayload(defaultContentType) %} diff --git a/partials/channel/OnSendingData.njk b/partials/channel/OnSendingData.njk index 95f9727a3..f6ee74f5b 100644 --- a/partials/channel/OnSendingData.njk +++ b/partials/channel/OnSendingData.njk @@ -7,14 +7,12 @@ try{ dataToSend = hook(dataToSend); } {%- if message.contentType() | isBinaryPayload(defaultContentType) %} - if(receivedDataHooks.length == 0 ){ - let error = new NatsTypescriptTemplateError('Missing hooks to convert binary data', '000'); - onReplyError(error); - return; + if(beforeSendingHooks.length == 0){ + dataToSend = Buffer.from({{message.uid() | pascalCase}}Message.Convert.{{message.uid() | camelCase}}ToJson(dataToSend)); } {%- endif %} {%- if message.contentType() | isStringPayload(defaultContentType) %} - if(receivedDataHooks.length == 0 ){ + if(beforeSendingHooks.length == 0 ){ dataToSend = {{message.uid() | pascalCase}}Message.Convert.{{message.uid() | camelCase}}ToJson(dataToSend); } {%- endif %} diff --git a/partials/index/Reply.njk b/partials/index/Reply.njk index 7c48e8bdd..1a836d8a0 100644 --- a/partials/index/Reply.njk +++ b/partials/index/Reply.njk @@ -1,5 +1,5 @@ -{% macro reply(defaultContentType, channelName, replyMessage, requestMessage, messageDescription, channelParameters, params) %} +{% macro reply(defaultContentType, channelName, replyMessage, receiveMessage, messageDescription, channelParameters, params) %} /** * {{messageDescription}} * @param onRequest Called when request received. @@ -8,7 +8,7 @@ public replyTo{{channelName | pascalCase }}( onRequest : ( err?: NatsTypescriptTemplateError, - msg?: {{requestMessage | getMessageType}} + msg?: {{receiveMessage | getMessageType}} {%- if channelParameters | length %},{{channelParameters | realizeParametersForChannel(false)}}{% endif %} ) => {%- if params.promisifyReplyCallback | length %}Promise<{%- endif %}{{replyMessage | getMessageType}}{%- if params.promisifyReplyCallback | length %}>{%- endif %}, onReplyError : (err: NatsTypescriptTemplateError) => void @@ -17,13 +17,13 @@ {% endif %}, options?: SubscriptionOptions ): Promise { - {%- if requestMessage.contentType() | isBinaryPayload(defaultContentType) %} + {%- if receiveMessage.contentType() | isBinaryPayload(defaultContentType) %} const nc: Client = this.binaryClient!; {%- endif %} - {%- if requestMessage.contentType() | isStringPayload(defaultContentType) %} + {%- if receiveMessage.contentType() | isStringPayload(defaultContentType) %} const nc: Client = this.stringClient!; {%- endif %} - {%- if requestMessage.contentType() | isJsonPayload(defaultContentType) %} + {%- if receiveMessage.contentType() | isJsonPayload(defaultContentType) %} const nc: Client = this.jsonClient!; {%- endif %} diff --git a/template/src/channels/$$channel$$.ts.njk b/template/src/channels/$$channel$$.ts.njk index 7a68cff3c..741caf63a 100644 --- a/template/src/channels/$$channel$$.ts.njk +++ b/template/src/channels/$$channel$$.ts.njk @@ -18,18 +18,18 @@ import {ErrorCode, NatsTypescriptTemplateError} from '../NatsTypescriptTemplateE import { Hooks } from '../hooks'; {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{ request(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), defaultContentType) }} + {{ request(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), asyncapi.defaultContentType()) }} {%- endif %} {%- if channel | isReplier %} - {{ reply(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), params, defaultContentType) }} + {{ reply(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), params, asyncapi.defaultContentType()) }} {%- endif %} {%- endif %} {%- if channel | isPubsub %} {%- if channel.hasSubscribe() %} - {{ publish(channelName, channel.parameters(), channel.subscribe().message(0), asyncapi.server(params.server), defaultContentType) }} + {{ publish(channelName, channel.parameters(), channel.subscribe().message(0), asyncapi.server(params.server), asyncapi.defaultContentType()) }} {%- endif %} {%- if channel.hasPublish() %} - {{ subscribe(channelName, channel.parameters(), channel.publish().message(0), asyncapi.server(params.server), defaultContentType) }} + {{ subscribe(channelName, channel.parameters(), channel.publish().message(0), asyncapi.server(params.server), asyncapi.defaultContentType()) }} {%- endif %} {%- endif %} diff --git a/template/src/tests/testclient/index.ts.njk b/template/src/tests/testclient/index.ts.njk index f8ec3e2aa..1dd9f234f 100644 --- a/template/src/tests/testclient/index.ts.njk +++ b/template/src/tests/testclient/index.ts.njk @@ -72,10 +72,10 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ {%- for channelName, channel in asyncapi.channels() %} {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{ reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0),channel.publish().message(0), channel.description(), channel.parameters(), params)}} + {{ reply(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters(), params)}} {%- endif %} {%- if channel | isReplier %} - {{ request(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters())}} + {{ request(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.subscribe().message(0), channel.description(), channel.parameters())}} {%- endif %} {%- endif %} diff --git a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk index 83113c44d..ef30c6975 100644 --- a/template/src/tests/testclient/testchannels/$$channel$$.ts.njk +++ b/template/src/tests/testclient/testchannels/$$channel$$.ts.njk @@ -20,18 +20,18 @@ import { Hooks } from '../../../hooks'; {%- if channel | isRequestReply %} {%- if channel | isRequester %} - {{ reply(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), params, defaultContentType) }} + {{ reply(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server), params, asyncapi.defaultContentType()) }} {%- endif %} {%- if channel | isReplier %} - {{ request(channelName, channel.parameters(), channel.subscribe().message(0), channel.publish().message(0), asyncapi.server(params.server), defaultContentType) }} + {{ request(channelName, channel.parameters(), channel.publish().message(0), channel.subscribe().message(0), asyncapi.server(params.server), asyncapi.defaultContentType()) }} {%- endif %} {%- endif %} {%- if channel | isPubsub %} {%- if channel.hasSubscribe() %} - {{ subscribe(channelName, channel.parameters(), channel.subscribe().message(0), asyncapi.server(params.server), defaultContentType) }} + {{ subscribe(channelName, channel.parameters(), channel.subscribe().message(0), asyncapi.server(params.server), asyncapi.defaultContentType()) }} {%- endif %} {%- if channel.hasPublish() %} - {{ publish(channelName, channel.parameters(), channel.publish().message(0), asyncapi.server(params.server), defaultContentType) }} + {{ publish(channelName, channel.parameters(), channel.publish().message(0), asyncapi.server(params.server), asyncapi.defaultContentType()) }} {%- endif %} {%- endif %} From 2bb93c1724e106a1c9059984866642f6ef55dd98 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Tue, 28 Jul 2020 09:31:13 +0200 Subject: [PATCH 095/110] Removed unused script --- package.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/package.json b/package.json index 36a495c34..3a0582109 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,6 @@ "nats", "template" ], - "scripts": { - "gen": "node ./generatorComparators" - }, "author": "Jonas Lagoni (jonas-lt@live.dk)", "license": "Apache-2.0", "dependencies": { From 3736b6b5c61522e4503b122ab2a4380c5bc20a49 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 20 Aug 2020 13:05:18 +0200 Subject: [PATCH 096/110] Updated the new release candidate of the generator to be supported. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3a0582109..0e0820f68 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "required": false } }, - "generator": ">=0.50.0 <=1.0.0-rc.5", + "generator": ">=0.50.0 <=1.0.0-rc.9", "filters": [ "@asyncapi/generator-filters" ] From cbc4b64f0a522798447d2561885938917efccc0b Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Tue, 1 Sep 2020 12:35:21 +0200 Subject: [PATCH 097/110] Updated the generator version supported --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0e0820f68..b7bf2a581 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "required": false } }, - "generator": ">=0.50.0 <=1.0.0-rc.9", + "generator": ">=0.50.0 <=1.0.0-rc.10", "filters": [ "@asyncapi/generator-filters" ] From e899a8b918e10a2c4eefab04676a424d01081fbc Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Tue, 1 Sep 2020 13:00:38 +0200 Subject: [PATCH 098/110] Removed unused scripts and dependencies. --- template/package.json.njk | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/template/package.json.njk b/template/package.json.njk index ddab3fde8..41b2ff0f3 100644 --- a/template/package.json.njk +++ b/template/package.json.njk @@ -20,9 +20,7 @@ "types": "dist/index.d.ts", "scripts": { "watch": "tsc --watch", - "build": "tsc", - "start": "node src/api/index.js", - "test": "mocha -r ts-node/register tests/**/*.spec.ts" + "build": "tsc" }, "dependencies": { "@types/klaw-sync": "^6.0.0", @@ -32,10 +30,6 @@ "ts-nkeys":"1.0.16" }, "devDependencies": { - "@types/chai": "^4.2.11", - "@types/mocha": "^7.0.2", - "chai": "^4.2.0", - "mocha": "^7.1.1", "ts-node": "^8.8.1" } } From c577651e569e73344c7f3dcbacd4d5ffd353ee68 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Tue, 1 Sep 2020 13:03:47 +0200 Subject: [PATCH 099/110] Fixed channel parameter unwrapping not working properly. --- partials/channel/ChannelParameterUnwrap.njk | 45 +++++++++++++++++++++ partials/channel/Reply.njk | 14 ++----- partials/channel/Subscribe.njk | 14 ++----- 3 files changed, 53 insertions(+), 20 deletions(-) create mode 100644 partials/channel/ChannelParameterUnwrap.njk diff --git a/partials/channel/ChannelParameterUnwrap.njk b/partials/channel/ChannelParameterUnwrap.njk new file mode 100644 index 000000000..b13476ee5 --- /dev/null +++ b/partials/channel/ChannelParameterUnwrap.njk @@ -0,0 +1,45 @@ + +{% macro unwrap(channelName, channelParameters) %} + +{%- if channelParameters | length %} +var unmodifiedChannel = {{channelName | realizeChannelNameWithoutParameters | safe}}; +var channel = msg.subject; + +{%- for parameterName, parameter in channelParameters %} +{%- if prevParameterName | length %} + var {{parameterName | camelCase}}Split = {{prevParameterName}}Split[1].split("{{'{'+ parameterName + '}'}}"); +{%- else %} + var {{parameterName | camelCase}}Split = unmodifiedChannel.split("{{'{'+ parameterName + '}'}}"); +{%- endif %} +{%- set prevParameterName = (parameterName | camelCase) %} +{%- endfor %} + +const splits = [ + {%- set counter = 1 %} + {%- for parameterName, parameter in channelParameters %} + {%- if counter == (channelParameters | length) %} + {{parameterName | camelCase}}Split[0], + {{parameterName | camelCase}}Split[1] + {%- else %} + {{parameterName | camelCase}}Split[0], + {%- endif %} + {%- set counter = counter + 1 %} + {%- endfor %} +]; + + +{%- set counter = 0 %} +{%- set prevParameterName = null %} +{%- for parameterName, parameter in channelParameters %} +{%- if counter == 0 %} +channel = channel.substring(splits[{{counter}}].length); +{%- else %} +channel = channel.substring({{prevParameterName}}End+splits[{{counter}}].length); +{%- endif %} +var {{parameterName | camelCase}}End = channel.indexOf(splits[{{counter+1}}]); +var {{parameterName | camelCase}}Param = channel.substring(0, {{parameterName | camelCase}}End); +{%- set counter = counter + 1 %} +{%- set prevParameterName = (parameterName | camelCase) %} +{%- endfor %} +{%- endif %} +{% endmacro %} diff --git a/partials/channel/Reply.njk b/partials/channel/Reply.njk index 2d590a81e..1d95e2f42 100644 --- a/partials/channel/Reply.njk +++ b/partials/channel/Reply.njk @@ -1,6 +1,7 @@ {%- from "./OnSendingData.njk" import OnSendingData %} {%- from "./OnReceivingData.njk" import OnReceivingData %} +{%- from "./ChannelParameterUnwrap.njk" import unwrap %} {% macro reply(channelName, channelParameters, replyMessage, receiveMessage, server, params, defaultContentType) %} export function reply( onRequest: (err?: NatsTypescriptTemplateError, msg?: {{receiveMessage | getMessageType}}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => @@ -31,14 +32,7 @@ export function reply( onRequest(err); } else { {%- if channelParameters | length %} - const unmodifiedChannel = {{channelName | realizeChannelNameWithoutParameters}} - const receivedTopicParameters = { - {%- set counter = 1 %} - {%- for parameterName, parameter in channelParameters %} - {{parameterName}} : msg.subject.slice(unmodifiedChannel.split("{{'{'+ parameterName+ '}'}}")[0].length, msg.subject.length-unmodifiedChannel.split("{{'{'+parameterName+'}'}}")[1].length){%- if counter < (channelParameters | length) %},{%- endif %} - {%- set counter = counter+1 %} - {%- endfor %} - } + {{unwrap(channelName, channelParameters)}} {%- endif %} {%- if receiveMessage.payload() | messageHasNotNullPayload %} @@ -47,7 +41,7 @@ export function reply( let message = {%-if params.promisifyReplyCallback | length %}await{%- endif %} onRequest(undefined, receivedData{% if channelParameters | length %}, {%- set counter = 1 %} {%- for parameterName, parameter in channelParameters %} - receivedTopicParameters['{{parameterName}}']{%- if counter < (channelParameters | length) %},{%- endif %} + {{parameterName | camelCase}}Param{%- if counter < (channelParameters | length) %},{%- endif %} {%- set counter = counter+1 %} {%- endfor %} {%- endif %}); @@ -55,7 +49,7 @@ export function reply( let message = {%-if params.promisifyReplyCallback | length %}await{%- endif %} onRequest(undefined, null{% if channelParameters | length %}, {%- set counter = 1 %} {%- for parameterName, parameter in channelParameters %} - receivedTopicParameters['{{parameterName}}']{%- if counter < (channelParameters | length) %},{%- endif %} + {{parameterName | camelCase}}Param{%- if counter < (channelParameters | length) %},{%- endif %} {%- set counter = counter+1 %} {%- endfor %} {%- endif %}); diff --git a/partials/channel/Subscribe.njk b/partials/channel/Subscribe.njk index 9c3e90b34..8ec52004a 100644 --- a/partials/channel/Subscribe.njk +++ b/partials/channel/Subscribe.njk @@ -1,5 +1,6 @@ {%- from "./OnReceivingData.njk" import OnReceivingData %} +{%- from "./ChannelParameterUnwrap.njk" import unwrap %} {% macro subscribe(channelName, channelParameters, subscribtionMessage, server, defaultContentType) %} export function subscribe( onDataCallback : (err?: NatsTypescriptTemplateError, msg?: {{subscribtionMessage | getMessageType}}{% if channelParameters | length %}, {{channelParameters | realizeParametersForChannel(false)}}{% endif %}) => void, @@ -28,21 +29,14 @@ export function subscribe( onDataCallback(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, err)); }else{ {%- if channelParameters | length %} - const unmodifiedChannel = {{channelName | realizeChannelNameWithoutParameters}} - const receivedTopicParameters = { - {%- set counter = 1 %} - {%- for parameterName, parameter in channelParameters %} - {{parameterName}} : msg.subject.slice(unmodifiedChannel.split("{{'{'+ parameterName+ '}'}}")[0].length, msg.subject.length-unmodifiedChannel.split("{{'{'+parameterName+'}'}}")[1].length){%- if counter < (channelParameters | length) %},{%- endif %} - {%- set counter = counter+1 %} - {%- endfor %} - } + {{unwrap(channelName, channelParameters)}} {%- endif %} {%- if subscribtionMessage.payload() | messageHasNotNullPayload %} {{OnReceivingData(true, subscribtionMessage, defaultContentType)}} onDataCallback(undefined, receivedData{% if channelParameters | length %}, {%- set counter = 1 %} {%- for parameterName, parameter in channelParameters %} - receivedTopicParameters['{{parameterName}}']{%- if counter < (channelParameters | length) %},{%- endif %} + {{parameterName | camelCase}}Param{%- if counter < (channelParameters | length) %},{%- endif %} {%- set counter = counter+1 %} {%- endfor %} {%- endif %}); @@ -50,7 +44,7 @@ export function subscribe( onDataCallback(undefined, null{% if channelParameters | length %}, {%- set counter = 1 %} {%- for parameterName, parameter in channelParameters %} - receivedTopicParameters['{{parameterName}}']{%- if counter < (channelParameters | length) %},{%- endif %} + {{parameterName | camelCase}}Param{%- if counter < (channelParameters | length) %},{%- endif %} {%- set counter = counter+1 %} {%- endfor %} {%- endif %}); From 865e325423afe9802e94015abf3cc0fa7e976a25 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Tue, 1 Sep 2020 13:03:56 +0200 Subject: [PATCH 100/110] Updated examples. --- .../streetlight/package-lock.json | 968 ------------------ .../streetlight/package.json | 8 +- .../StreetlightStreetlightIdCommandTurnon.ts | 19 +- .../StreetlightStreetlightIdEventTurnon.ts | 4 +- .../streetlight/src/index.ts | 6 +- .../src/messages/AnonymousMessage2.ts | 162 +++ .../streetlight/src/tests/testclient/index.ts | 6 +- .../StreetlightStreetlightIdEventTurnon.ts | 23 +- .../streetlight/package-lock.json | 968 ------------------ .../request reply/streetlight/package.json | 8 +- .../StreetlightStreetlightIdCommandTurnon.ts | 19 +- .../StreetlightStreetlightIdEventTurnon.ts | 4 +- .../request reply/streetlight/src/index.ts | 6 +- .../src/messages/AnonymousMessage4.ts | 162 +++ .../streetlight/src/tests/testclient/index.ts | 6 +- .../StreetlightStreetlightIdEventTurnon.ts | 23 +- 16 files changed, 402 insertions(+), 1990 deletions(-) create mode 100644 examples/publish subscribe/streetlight/src/messages/AnonymousMessage2.ts create mode 100644 examples/request reply/streetlight/src/messages/AnonymousMessage4.ts diff --git a/examples/publish subscribe/streetlight/package-lock.json b/examples/publish subscribe/streetlight/package-lock.json index 44420165e..54a9a1391 100644 --- a/examples/publish subscribe/streetlight/package-lock.json +++ b/examples/publish subscribe/streetlight/package-lock.json @@ -4,12 +4,6 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@types/chai": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz", - "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==", - "dev": true - }, "@types/klaw-sync": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@types/klaw-sync/-/klaw-sync-6.0.0.tgz", @@ -18,779 +12,34 @@ "@types/node": "*" } }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, "@types/node": { "version": "13.9.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.5.tgz", "integrity": "sha512-hkzMMD3xu6BrJpGVLeQ3htQQNAcOrJjX7WFmtK8zWQpz2UJf13LCFF2ALA7c9OVdvc2vQJeDdjfR35M0sBCxvw==" }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, "nuid": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/nuid/-/nuid-1.1.4.tgz", "integrity": "sha512-PXiYyHhGfrq8H4g5HyC8enO1lz6SBe5z6x1yx/JG4tmADzDGJVQy3l1sRf3VtEvPsN8dGn9hRFRwDKWL62x0BA==" }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -807,75 +56,6 @@ "source-map": "^0.6.0" } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, "ts-nats": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/ts-nats/-/ts-nats-1.2.4.tgz", @@ -919,159 +99,11 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, "typescript": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.3.tgz", "integrity": "sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ==" }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/examples/publish subscribe/streetlight/package.json b/examples/publish subscribe/streetlight/package.json index 395761267..439f829c4 100644 --- a/examples/publish subscribe/streetlight/package.json +++ b/examples/publish subscribe/streetlight/package.json @@ -6,9 +6,7 @@ "types": "dist/index.d.ts", "scripts": { "watch": "tsc --watch", - "build": "tsc", - "start": "node src/api/index.js", - "test": "mocha -r ts-node/register tests/**/*.spec.ts" + "build": "tsc" }, "dependencies": { "@types/klaw-sync": "^6.0.0", @@ -18,10 +16,6 @@ "ts-nkeys": "1.0.16" }, "devDependencies": { - "@types/chai": "^4.2.11", - "@types/mocha": "^7.0.2", - "chai": "^4.2.0", - "mocha": "^7.1.1", "ts-node": "^8.8.1" } } diff --git a/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts b/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts index d12852cde..6883661a8 100644 --- a/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts +++ b/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts @@ -20,10 +20,19 @@ export function subscribe( if(err){ onDataCallback(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, err)); }else{ - const unmodifiedChannel = `streetlight.{streetlight_id}.command.turnon` - const receivedTopicParameters = { - streetlight_id : msg.subject.slice(unmodifiedChannel.split("{streetlight_id}")[0].length, msg.subject.length-unmodifiedChannel.split("{streetlight_id}")[1].length) - } + +var unmodifiedChannel = `streetlight.{streetlight_id}.command.turnon`; +var channel = msg.subject; + var streetlightIdSplit = unmodifiedChannel.split("{streetlight_id}"); + +const splits = [ + streetlightIdSplit[0], + streetlightIdSplit[1] +]; +channel = channel.substring(splits[0].length); +var streetlightIdEnd = channel.indexOf(splits[1]); +var streetlightIdParam = channel.substring(0, streetlightIdEnd); + try { let receivedDataHooks = Hooks.getInstance().getreceivedDataHook(); @@ -38,7 +47,7 @@ try { } onDataCallback(undefined, receivedData, - receivedTopicParameters['streetlight_id']); + streetlightIdParam); } }, subscribeOptions); resolve(subscription); diff --git a/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts b/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts index 5f3276c8e..b53c775e0 100644 --- a/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts +++ b/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts @@ -1,11 +1,11 @@ -import * as AnonymousMessage1Message from '../messages/AnonymousMessage1' +import * as AnonymousMessage2Message from '../messages/AnonymousMessage2' import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; import {ErrorCode, NatsTypescriptTemplateError} from '../NatsTypescriptTemplateError'; import { Hooks } from '../hooks'; export function publish( - message: AnonymousMessage1Message.AnonymousMessage1, + message: AnonymousMessage2Message.AnonymousMessage2, nc: Client ,streetlight_id: string diff --git a/examples/publish subscribe/streetlight/src/index.ts b/examples/publish subscribe/streetlight/src/index.ts index 7267f36f2..e8b683078 100644 --- a/examples/publish subscribe/streetlight/src/index.ts +++ b/examples/publish subscribe/streetlight/src/index.ts @@ -29,8 +29,8 @@ import * as streetlightStreetlightIdEventTurnonChannel from "./channels/Streetli export {streetlightStreetlightIdEventTurnonChannel}; import * as TurnonCommandMessage from "./messages/TurnonCommand"; export {TurnonCommandMessage}; -import * as AnonymousMessage1Message from "./messages/AnonymousMessage1"; -export {AnonymousMessage1Message}; +import * as AnonymousMessage2Message from "./messages/AnonymousMessage2"; +export {AnonymousMessage2Message}; import * as events from 'events'; @@ -240,7 +240,7 @@ export class NatsAsyncApiClient extends events.EventEmitter{ * @param requestMessage The message to publish. */ public publishToStreetlightStreetlightIdEventTurnon( - requestMessage: AnonymousMessage1Message.AnonymousMessage1 + requestMessage: AnonymousMessage2Message.AnonymousMessage2 ,streetlight_id: string diff --git a/examples/publish subscribe/streetlight/src/messages/AnonymousMessage2.ts b/examples/publish subscribe/streetlight/src/messages/AnonymousMessage2.ts new file mode 100644 index 000000000..5d9e8b6a4 --- /dev/null +++ b/examples/publish subscribe/streetlight/src/messages/AnonymousMessage2.ts @@ -0,0 +1,162 @@ +// To parse this data: +// +// import { Convert, AnonymousMessage2 } from "./file"; +// +// const anonymousMessage2 = Convert.toAnonymousMessage2(json); +// +// These functions will throw an error if the JSON doesn't +// match the expected interface, even if the JSON is valid. + +export interface AnonymousMessage2 { + /** + * How bright should the light be. + */ + lumen: number; +} + +// Converts JSON strings to/from your types +// and asserts the results of JSON.parse at runtime +export class Convert { + public static toAnonymousMessage2(json: string): AnonymousMessage2 { + return cast(JSON.parse(json), r("AnonymousMessage2")); + } + + public static anonymousMessage2ToJson(value: AnonymousMessage2): string { + return JSON.stringify(uncast(value, r("AnonymousMessage2")), null, 2); + } +} + +function invalidValue(typ: any, val: any): never { + throw Error(`Invalid value ${JSON.stringify(val)} for type ${JSON.stringify(typ)}`); +} + +function jsonToJSProps(typ: any): any { + if (typ.jsonToJS === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ }); + typ.jsonToJS = map; + } + return typ.jsonToJS; +} + +function jsToJSONProps(typ: any): any { + if (typ.jsToJSON === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ }); + typ.jsToJSON = map; + } + return typ.jsToJSON; +} + +function transform(val: any, typ: any, getProps: any): any { + function transformPrimitive(typ: string, val: any): any { + if (typeof typ === typeof val) return val; + return invalidValue(typ, val); + } + + function transformUnion(typs: any[], val: any): any { + // val must validate against one typ in typs + const l = typs.length; + for (let i = 0; i < l; i++) { + const typ = typs[i]; + try { + return transform(val, typ, getProps); + } catch (_) {} + } + return invalidValue(typs, val); + } + + function transformEnum(cases: string[], val: any): any { + if (cases.indexOf(val) !== -1) return val; + return invalidValue(cases, val); + } + + function transformArray(typ: any, val: any): any { + // val must be an array with no invalid elements + if (!Array.isArray(val)) return invalidValue("array", val); + return val.map(el => transform(el, typ, getProps)); + } + + function transformDate(val: any): any { + if (val === null) { + return null; + } + const d = new Date(val); + if (isNaN(d.valueOf())) { + return invalidValue("Date", val); + } + return d; + } + + function transformObject(props: { [k: string]: any }, additional: any, val: any): any { + if (val === null || typeof val !== "object" || Array.isArray(val)) { + return invalidValue("object", val); + } + const result: any = {}; + Object.getOwnPropertyNames(props).forEach(key => { + const prop = props[key]; + const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined; + result[prop.key] = transform(v, prop.typ, getProps); + }); + Object.getOwnPropertyNames(val).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(props, key)) { + result[key] = transform(val[key], additional, getProps); + } + }); + return result; + } + + if (typ === "any") return val; + if (typ === null) { + if (val === null) return val; + return invalidValue(typ, val); + } + if (typ === false) return invalidValue(typ, val); + while (typeof typ === "object" && typ.ref !== undefined) { + typ = typeMap[typ.ref]; + } + if (Array.isArray(typ)) return transformEnum(typ, val); + if (typeof typ === "object") { + return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) + : invalidValue(typ, val); + } + // Numbers can be parsed by Date but shouldn't be. + if (typ === Date && typeof val !== "number") return transformDate(val); + return transformPrimitive(typ, val); +} + +function cast(val: any, typ: any): T { + return transform(val, typ, jsonToJSProps); +} + +function uncast(val: T, typ: any): any { + return transform(val, typ, jsToJSONProps); +} + +function a(typ: any) { + return { arrayItems: typ }; +} + +function u(...typs: any[]) { + return { unionMembers: typs }; +} + +function o(props: any[], additional: any) { + return { props, additional }; +} + +function m(additional: any) { + return { props: [], additional }; +} + +function r(name: string) { + return { ref: name }; +} + +const typeMap: any = { + "AnonymousMessage2": o([ + { json: "lumen", js: "lumen", typ: 0 }, + ], "any"), +}; diff --git a/examples/publish subscribe/streetlight/src/tests/testclient/index.ts b/examples/publish subscribe/streetlight/src/tests/testclient/index.ts index 38f4bda47..d27935ddf 100644 --- a/examples/publish subscribe/streetlight/src/tests/testclient/index.ts +++ b/examples/publish subscribe/streetlight/src/tests/testclient/index.ts @@ -20,8 +20,8 @@ import * as streetlightStreetlightIdEventTurnonChannel from "./testchannels/Stre export {streetlightStreetlightIdEventTurnonChannel}; import * as TurnonCommandMessage from "../../messages/TurnonCommand"; export {TurnonCommandMessage}; -import * as AnonymousMessage1Message from "../../messages/AnonymousMessage1"; -export {AnonymousMessage1Message}; +import * as AnonymousMessage2Message from "../../messages/AnonymousMessage2"; +export {AnonymousMessage2Message}; @@ -228,7 +228,7 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ * @param onDataCallback Called when message received. */ public subscribeToStreetlightStreetlightIdEventTurnon( - onDataCallback : (err?: NatsTypescriptTemplateError, msg?: AnonymousMessage1Message.AnonymousMessage1, streetlight_id?: string) => void + onDataCallback : (err?: NatsTypescriptTemplateError, msg?: AnonymousMessage2Message.AnonymousMessage2, streetlight_id?: string) => void ,streetlight_id: string , diff --git a/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts b/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts index 58dcfc4f8..3265c5588 100644 --- a/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts +++ b/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts @@ -1,11 +1,11 @@ -import * as AnonymousMessage1Message from '../../../messages/AnonymousMessage1'; +import * as AnonymousMessage2Message from '../../../messages/AnonymousMessage2'; import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; import {ErrorCode, NatsTypescriptTemplateError} from '../../../NatsTypescriptTemplateError'; import { Hooks } from '../../../hooks'; export function subscribe( - onDataCallback : (err?: NatsTypescriptTemplateError, msg?: AnonymousMessage1Message.AnonymousMessage1, streetlight_id?: string) => void, + onDataCallback : (err?: NatsTypescriptTemplateError, msg?: AnonymousMessage2Message.AnonymousMessage2, streetlight_id?: string) => void, nc: Client ,streetlight_id: string @@ -20,10 +20,19 @@ export function subscribe( if(err){ onDataCallback(NatsTypescriptTemplateError.errorForCode(ErrorCode.INTERNAL_NATS_TS_ERROR, err)); }else{ - const unmodifiedChannel = `streetlight.{streetlight_id}.event.turnon` - const receivedTopicParameters = { - streetlight_id : msg.subject.slice(unmodifiedChannel.split("{streetlight_id}")[0].length, msg.subject.length-unmodifiedChannel.split("{streetlight_id}")[1].length) - } + +var unmodifiedChannel = `streetlight.{streetlight_id}.event.turnon`; +var channel = msg.subject; + var streetlightIdSplit = unmodifiedChannel.split("{streetlight_id}"); + +const splits = [ + streetlightIdSplit[0], + streetlightIdSplit[1] +]; +channel = channel.substring(splits[0].length); +var streetlightIdEnd = channel.indexOf(splits[1]); +var streetlightIdParam = channel.substring(0, streetlightIdEnd); + try { let receivedDataHooks = Hooks.getInstance().getreceivedDataHook(); @@ -38,7 +47,7 @@ try { } onDataCallback(undefined, receivedData, - receivedTopicParameters['streetlight_id']); + streetlightIdParam); } }, subscribeOptions); resolve(subscription); diff --git a/examples/request reply/streetlight/package-lock.json b/examples/request reply/streetlight/package-lock.json index 44420165e..54a9a1391 100644 --- a/examples/request reply/streetlight/package-lock.json +++ b/examples/request reply/streetlight/package-lock.json @@ -4,12 +4,6 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@types/chai": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz", - "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==", - "dev": true - }, "@types/klaw-sync": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@types/klaw-sync/-/klaw-sync-6.0.0.tgz", @@ -18,779 +12,34 @@ "@types/node": "*" } }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, "@types/node": { "version": "13.9.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.5.tgz", "integrity": "sha512-hkzMMD3xu6BrJpGVLeQ3htQQNAcOrJjX7WFmtK8zWQpz2UJf13LCFF2ALA7c9OVdvc2vQJeDdjfR35M0sBCxvw==" }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, "nuid": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/nuid/-/nuid-1.1.4.tgz", "integrity": "sha512-PXiYyHhGfrq8H4g5HyC8enO1lz6SBe5z6x1yx/JG4tmADzDGJVQy3l1sRf3VtEvPsN8dGn9hRFRwDKWL62x0BA==" }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -807,75 +56,6 @@ "source-map": "^0.6.0" } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, "ts-nats": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/ts-nats/-/ts-nats-1.2.4.tgz", @@ -919,159 +99,11 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, "typescript": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.3.tgz", "integrity": "sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ==" }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/examples/request reply/streetlight/package.json b/examples/request reply/streetlight/package.json index 395761267..439f829c4 100644 --- a/examples/request reply/streetlight/package.json +++ b/examples/request reply/streetlight/package.json @@ -6,9 +6,7 @@ "types": "dist/index.d.ts", "scripts": { "watch": "tsc --watch", - "build": "tsc", - "start": "node src/api/index.js", - "test": "mocha -r ts-node/register tests/**/*.spec.ts" + "build": "tsc" }, "dependencies": { "@types/klaw-sync": "^6.0.0", @@ -18,10 +16,6 @@ "ts-nkeys": "1.0.16" }, "devDependencies": { - "@types/chai": "^4.2.11", - "@types/mocha": "^7.0.2", - "chai": "^4.2.0", - "mocha": "^7.1.1", "ts-node": "^8.8.1" } } diff --git a/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts index b66f3bf16..301bfb150 100644 --- a/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts +++ b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts @@ -22,10 +22,19 @@ export function reply( if (err) { onRequest(err); } else { - const unmodifiedChannel = `streetlight.{streetlight_id}.command.turnon` - const receivedTopicParameters = { - streetlight_id : msg.subject.slice(unmodifiedChannel.split("{streetlight_id}")[0].length, msg.subject.length-unmodifiedChannel.split("{streetlight_id}")[1].length) - } + +var unmodifiedChannel = `streetlight.{streetlight_id}.command.turnon`; +var channel = msg.subject; + var streetlightIdSplit = unmodifiedChannel.split("{streetlight_id}"); + +const splits = [ + streetlightIdSplit[0], + streetlightIdSplit[1] +]; +channel = channel.substring(splits[0].length); +var streetlightIdEnd = channel.indexOf(splits[1]); +var streetlightIdParam = channel.substring(0, streetlightIdEnd); + try { let receivedDataHooks = Hooks.getInstance().getreceivedDataHook(); @@ -41,7 +50,7 @@ try { let message =await onRequest(undefined, receivedData, - receivedTopicParameters['streetlight_id']); + streetlightIdParam); if (msg.reply) { diff --git a/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts index 533fc97e5..a89f8bba8 100644 --- a/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts +++ b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdEventTurnon.ts @@ -1,12 +1,12 @@ import * as GeneralReplyMessage from '../messages/GeneralReply' -import * as AnonymousMessage3Message from '../messages/AnonymousMessage3' +import * as AnonymousMessage4Message from '../messages/AnonymousMessage4' import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; import {ErrorCode, NatsTypescriptTemplateError} from '../NatsTypescriptTemplateError'; import { Hooks } from '../hooks'; export function request( - message: AnonymousMessage3Message.AnonymousMessage3, + message: AnonymousMessage4Message.AnonymousMessage4, nc: Client ,streetlight_id: string diff --git a/examples/request reply/streetlight/src/index.ts b/examples/request reply/streetlight/src/index.ts index 0162745f4..0c9527d9b 100644 --- a/examples/request reply/streetlight/src/index.ts +++ b/examples/request reply/streetlight/src/index.ts @@ -31,8 +31,8 @@ import * as TurnonCommandMessage from "./messages/TurnonCommand"; export {TurnonCommandMessage}; import * as GeneralReplyMessage from "./messages/GeneralReply"; export {GeneralReplyMessage}; -import * as AnonymousMessage3Message from "./messages/AnonymousMessage3"; -export {AnonymousMessage3Message}; +import * as AnonymousMessage4Message from "./messages/AnonymousMessage4"; +export {AnonymousMessage4Message}; import * as events from 'events'; @@ -250,7 +250,7 @@ export class NatsAsyncApiClient extends events.EventEmitter{ * @param requestMessage The request message to send. */ public requestStreetlightStreetlightIdEventTurnon( - requestMessage:AnonymousMessage3Message.AnonymousMessage3 + requestMessage:AnonymousMessage4Message.AnonymousMessage4 ,streetlight_id: string diff --git a/examples/request reply/streetlight/src/messages/AnonymousMessage4.ts b/examples/request reply/streetlight/src/messages/AnonymousMessage4.ts new file mode 100644 index 000000000..286b473a7 --- /dev/null +++ b/examples/request reply/streetlight/src/messages/AnonymousMessage4.ts @@ -0,0 +1,162 @@ +// To parse this data: +// +// import { Convert, AnonymousMessage4 } from "./file"; +// +// const anonymousMessage4 = Convert.toAnonymousMessage4(json); +// +// These functions will throw an error if the JSON doesn't +// match the expected interface, even if the JSON is valid. + +export interface AnonymousMessage4 { + /** + * How bright should the light be. + */ + lumen: number; +} + +// Converts JSON strings to/from your types +// and asserts the results of JSON.parse at runtime +export class Convert { + public static toAnonymousMessage4(json: string): AnonymousMessage4 { + return cast(JSON.parse(json), r("AnonymousMessage4")); + } + + public static anonymousMessage4ToJson(value: AnonymousMessage4): string { + return JSON.stringify(uncast(value, r("AnonymousMessage4")), null, 2); + } +} + +function invalidValue(typ: any, val: any): never { + throw Error(`Invalid value ${JSON.stringify(val)} for type ${JSON.stringify(typ)}`); +} + +function jsonToJSProps(typ: any): any { + if (typ.jsonToJS === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ }); + typ.jsonToJS = map; + } + return typ.jsonToJS; +} + +function jsToJSONProps(typ: any): any { + if (typ.jsToJSON === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ }); + typ.jsToJSON = map; + } + return typ.jsToJSON; +} + +function transform(val: any, typ: any, getProps: any): any { + function transformPrimitive(typ: string, val: any): any { + if (typeof typ === typeof val) return val; + return invalidValue(typ, val); + } + + function transformUnion(typs: any[], val: any): any { + // val must validate against one typ in typs + const l = typs.length; + for (let i = 0; i < l; i++) { + const typ = typs[i]; + try { + return transform(val, typ, getProps); + } catch (_) {} + } + return invalidValue(typs, val); + } + + function transformEnum(cases: string[], val: any): any { + if (cases.indexOf(val) !== -1) return val; + return invalidValue(cases, val); + } + + function transformArray(typ: any, val: any): any { + // val must be an array with no invalid elements + if (!Array.isArray(val)) return invalidValue("array", val); + return val.map(el => transform(el, typ, getProps)); + } + + function transformDate(val: any): any { + if (val === null) { + return null; + } + const d = new Date(val); + if (isNaN(d.valueOf())) { + return invalidValue("Date", val); + } + return d; + } + + function transformObject(props: { [k: string]: any }, additional: any, val: any): any { + if (val === null || typeof val !== "object" || Array.isArray(val)) { + return invalidValue("object", val); + } + const result: any = {}; + Object.getOwnPropertyNames(props).forEach(key => { + const prop = props[key]; + const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined; + result[prop.key] = transform(v, prop.typ, getProps); + }); + Object.getOwnPropertyNames(val).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(props, key)) { + result[key] = transform(val[key], additional, getProps); + } + }); + return result; + } + + if (typ === "any") return val; + if (typ === null) { + if (val === null) return val; + return invalidValue(typ, val); + } + if (typ === false) return invalidValue(typ, val); + while (typeof typ === "object" && typ.ref !== undefined) { + typ = typeMap[typ.ref]; + } + if (Array.isArray(typ)) return transformEnum(typ, val); + if (typeof typ === "object") { + return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) + : invalidValue(typ, val); + } + // Numbers can be parsed by Date but shouldn't be. + if (typ === Date && typeof val !== "number") return transformDate(val); + return transformPrimitive(typ, val); +} + +function cast(val: any, typ: any): T { + return transform(val, typ, jsonToJSProps); +} + +function uncast(val: T, typ: any): any { + return transform(val, typ, jsToJSONProps); +} + +function a(typ: any) { + return { arrayItems: typ }; +} + +function u(...typs: any[]) { + return { unionMembers: typs }; +} + +function o(props: any[], additional: any) { + return { props, additional }; +} + +function m(additional: any) { + return { props: [], additional }; +} + +function r(name: string) { + return { ref: name }; +} + +const typeMap: any = { + "AnonymousMessage4": o([ + { json: "lumen", js: "lumen", typ: 0 }, + ], "any"), +}; diff --git a/examples/request reply/streetlight/src/tests/testclient/index.ts b/examples/request reply/streetlight/src/tests/testclient/index.ts index 970228514..d74570505 100644 --- a/examples/request reply/streetlight/src/tests/testclient/index.ts +++ b/examples/request reply/streetlight/src/tests/testclient/index.ts @@ -22,8 +22,8 @@ import * as TurnonCommandMessage from "../../messages/TurnonCommand"; export {TurnonCommandMessage}; import * as GeneralReplyMessage from "../../messages/GeneralReply"; export {GeneralReplyMessage}; -import * as AnonymousMessage3Message from "../../messages/AnonymousMessage3"; -export {AnonymousMessage3Message}; +import * as AnonymousMessage4Message from "../../messages/AnonymousMessage4"; +export {AnonymousMessage4Message}; @@ -236,7 +236,7 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ public replyToStreetlightStreetlightIdEventTurnon( onRequest : ( err?: NatsTypescriptTemplateError, - msg?: AnonymousMessage3Message.AnonymousMessage3,streetlight_id?: string + msg?: AnonymousMessage4Message.AnonymousMessage4,streetlight_id?: string ) =>Promise, onReplyError : (err: NatsTypescriptTemplateError) => void diff --git a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts index 4cff6d078..a3f1a18d5 100644 --- a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts +++ b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts @@ -1,12 +1,12 @@ import * as GeneralReplyMessage from '../../../messages/GeneralReply'; -import * as AnonymousMessage3Message from '../../../messages/AnonymousMessage3'; +import * as AnonymousMessage4Message from '../../../messages/AnonymousMessage4'; import { Client, NatsError, Subscription, SubscriptionOptions, Payload } from 'ts-nats'; import {ErrorCode, NatsTypescriptTemplateError} from '../../../NatsTypescriptTemplateError'; import { Hooks } from '../../../hooks'; export function reply( - onRequest: (err?: NatsTypescriptTemplateError, msg?: AnonymousMessage3Message.AnonymousMessage3, streetlight_id?: string) =>Promise, + onRequest: (err?: NatsTypescriptTemplateError, msg?: AnonymousMessage4Message.AnonymousMessage4, streetlight_id?: string) =>Promise, onReplyError: (err: NatsTypescriptTemplateError) => void, nc: Client @@ -22,10 +22,19 @@ export function reply( if (err) { onRequest(err); } else { - const unmodifiedChannel = `streetlight.{streetlight_id}.event.turnon` - const receivedTopicParameters = { - streetlight_id : msg.subject.slice(unmodifiedChannel.split("{streetlight_id}")[0].length, msg.subject.length-unmodifiedChannel.split("{streetlight_id}")[1].length) - } + +var unmodifiedChannel = `streetlight.{streetlight_id}.event.turnon`; +var channel = msg.subject; + var streetlightIdSplit = unmodifiedChannel.split("{streetlight_id}"); + +const splits = [ + streetlightIdSplit[0], + streetlightIdSplit[1] +]; +channel = channel.substring(splits[0].length); +var streetlightIdEnd = channel.indexOf(splits[1]); +var streetlightIdParam = channel.substring(0, streetlightIdEnd); + try { let receivedDataHooks = Hooks.getInstance().getreceivedDataHook(); @@ -41,7 +50,7 @@ try { let message =await onRequest(undefined, receivedData, - receivedTopicParameters['streetlight_id']); + streetlightIdParam); if (msg.reply) { From 87a7e4b4c4bc7273a4e6f4964950505d3bc696ea Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sat, 5 Sep 2020 20:43:04 +0200 Subject: [PATCH 101/110] Fixed parameter types other then strings where not working --- filters/all.js | 21 +++++++++++++++++++++ partials/channel/ChannelParameterUnwrap.njk | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/filters/all.js b/filters/all.js index ee6b44952..6bd97e7f5 100644 --- a/filters/all.js +++ b/filters/all.js @@ -142,6 +142,27 @@ function toTsType(jsonSchemaType, property) { } } + +/** + * Cast JSON schema variable to typescript type + * + * @param {*} jsonSchemaType + * @param {*} variableToCast + */ +function castToTsType(jsonSchemaType, variableToCast) { + switch (jsonSchemaType.toLowerCase()) { + case 'string': + return `"" + ${variableToCast}`; + case 'integer': + case 'number': + return `Number(${variableToCast})`; + case 'boolean': + return `Boolean(${variableToCast})`; + default: throw new Error("Parameter type not supported - " + jsonSchemaType); + } +} +filter.castToTsType = castToTsType; + /** * Convert RFC 6570 URI with parameters to NATS topic. */ diff --git a/partials/channel/ChannelParameterUnwrap.njk b/partials/channel/ChannelParameterUnwrap.njk index b13476ee5..e37b4f3a1 100644 --- a/partials/channel/ChannelParameterUnwrap.njk +++ b/partials/channel/ChannelParameterUnwrap.njk @@ -37,7 +37,8 @@ channel = channel.substring(splits[{{counter}}].length); channel = channel.substring({{prevParameterName}}End+splits[{{counter}}].length); {%- endif %} var {{parameterName | camelCase}}End = channel.indexOf(splits[{{counter+1}}]); -var {{parameterName | camelCase}}Param = channel.substring(0, {{parameterName | camelCase}}End); +{%- set paramVarToCast = 'channel.substring(0, ' + (parameterName | camelCase) + 'End)' %} +var {{parameterName | camelCase}}Param = {{parameter.schema().type() | castToTsType(paramVarToCast) | safe}}; {%- set counter = counter + 1 %} {%- set prevParameterName = (parameterName | camelCase) %} {%- endfor %} From 247036b7e75664138fb2612e545471020a5a2487 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Mon, 28 Sep 2020 23:52:05 +0200 Subject: [PATCH 102/110] Added current AsyncAPI github workflow and updated examples code. Updated package.json with scripts --- .../workflows/automerge-release-pr-bump.yml | 47 +++++++++++++++ .github/workflows/pull-request-testing.yml | 22 +++++++ .github/workflows/release.yml | 60 +++++++++++++++++++ .github/workflows/stale-issues-prs.yml | 27 +++++++++ .../workflows/welcome-first-time-contrib.yml | 23 +++++++ README.md | 2 +- .../StreetlightStreetlightIdCommandTurnon.ts | 2 +- .../StreetlightStreetlightIdEventTurnon.ts | 2 +- .../StreetlightStreetlightIdCommandTurnon.ts | 2 +- .../StreetlightStreetlightIdEventTurnon.ts | 2 +- package.json | 51 +++++++++++++++- 11 files changed, 234 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/automerge-release-pr-bump.yml create mode 100644 .github/workflows/pull-request-testing.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/stale-issues-prs.yml create mode 100644 .github/workflows/welcome-first-time-contrib.yml diff --git a/.github/workflows/automerge-release-pr-bump.yml b/.github/workflows/automerge-release-pr-bump.yml new file mode 100644 index 000000000..e84abcbb1 --- /dev/null +++ b/.github/workflows/automerge-release-pr-bump.yml @@ -0,0 +1,47 @@ +name: Automerge release bump PR + +on: + pull_request: + types: + - labeled + - unlabeled + - synchronize + - opened + - edited + - ready_for_review + - reopened + - unlocked + pull_request_review: + types: + - submitted + check_suite: + types: + - completed + status: {} + +jobs: + + autoapprove: + runs-on: ubuntu-latest + steps: + - name: Autoapproving + uses: hmarr/auto-approve-action@v2.0.0 + if: github.actor == 'asyncapi-bot' + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + automerge: + needs: [autoapprove] + runs-on: ubuntu-latest + steps: + - name: Automerging + uses: pascalgn/automerge-action@v0.7.5 + if: github.actor == 'asyncapi-bot' + env: + GITHUB_TOKEN: "${{ secrets.GH_TOKEN }}" + GITHUB_LOGIN: asyncapi-bot + MERGE_LABELS: "" + MERGE_METHOD: "squash" + MERGE_COMMIT_MESSAGE: "pull-request-title" + MERGE_RETRIES: "10" + MERGE_RETRY_SLEEP: "10000" \ No newline at end of file diff --git a/.github/workflows/pull-request-testing.yml b/.github/workflows/pull-request-testing.yml new file mode 100644 index 000000000..7ea188087 --- /dev/null +++ b/.github/workflows/pull-request-testing.yml @@ -0,0 +1,22 @@ +name: Pull request testing + +on: + pull_request + +jobs: + release: + name: 'Run linter and tests' + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v2 + - name: Setup Node.js + uses: actions/setup-node@v1 + with: + node-version: 13 + - name: Install dependencies + run: npm ci + - name: Run linter + run: npm run lint + - name: Run tests + run: npm test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..091c4094e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,60 @@ +name: Release + +on: + push: + branches: + - master + +jobs: + release: + name: 'Release NPM, GitHub' + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v2 + - name: Setup Node.js + uses: actions/setup-node@v1 + with: + node-version: 13 + - name: Install dependencies + run: npm ci + - name: Run tests + run: npm test + - name: Re generate examples + run: npm generate:examples + - name: Get version from package.json before release step + id: initversion + run: echo "::set-output name=version::$(npm run get-version --silent)" + - name: Release to NPM and GitHub + id: release + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + GIT_AUTHOR_NAME: asyncapi-bot + GIT_AUTHOR_EMAIL: info@asyncapi.io + GIT_COMMITTER_NAME: asyncapi-bot + GIT_COMMITTER_EMAIL: info@asyncapi.io + run: npm run release + - name: Get version from package.json after release step + id: extractver + run: echo "::set-output name=version::$(npm run get-version --silent)" + - name: Create Pull Request with updated package files + if: steps.initversion.outputs.version != steps.extractver.outputs.version + uses: peter-evans/create-pull-request@v2.4.4 + with: + token: ${{ secrets.GH_TOKEN }} + commit-message: 'chore(release): ${{ steps.extractver.outputs.version }}' + committer: asyncapi-bot + author: asyncapi-bot + title: 'chore(release): ${{ steps.extractver.outputs.version }}' + body: 'Version bump in package.json and package-lock.json for release [${{ steps.extractver.outputs.version }}](https://github.com/${{github.repository}}/releases/tag/v${{ steps.extractver.outputs.version }})' + branch: version-bump/${{ steps.extractver.outputs.version }} + - name: Publish information about the release to Twitter + if: steps.initversion.outputs.version != steps.extractver.outputs.version + uses: m1ner79/Github-Twittction@v1.0.1 + with: + twitter_status: "Release ${{ steps.extractver.outputs.version }} for ${{github.repository}} is out in the wild 😱💪🍾🎂\n\nThank you for the contribution ${{ github.event.commits[0].author.name }} https://github.com/${{github.repository}}/releases/tag/v${{ steps.extractver.outputs.version }}" + twitter_consumer_key: ${{ secrets.TWITTER_CONSUMER_KEY }} + twitter_consumer_secret: ${{ secrets.TWITTER_CONSUMER_SECRET }} + twitter_access_token_key: ${{ secrets.TWITTER_ACCESS_TOKEN_KEY }} + twitter_access_token_secret: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }} diff --git a/.github/workflows/stale-issues-prs.yml b/.github/workflows/stale-issues-prs.yml new file mode 100644 index 000000000..4cb32bf98 --- /dev/null +++ b/.github/workflows/stale-issues-prs.yml @@ -0,0 +1,27 @@ +name: Manage stale issues and PRs + +on: + schedule: + - cron: "0 0 * * *" + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v1.1.0 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: | + This issue has been automatically marked as stale because it has not had recent activity :sleeping: + It will be closed in 30 days if no further activity occurs. To unstale this issue, add a comment with detailed explanation. + Thank you for your contributions :heart: + stale-pr-message: | + This pull request has been automatically marked as stale because it has not had recent activity :sleeping: + It will be closed in 30 days if no further activity occurs. To unstale this pull request, add a comment with detailed explanation. + Thank you for your contributions :heart: + days-before-stale: 60 + days-before-close: 30 + stale-issue-label: stale + stale-pr-label: stale + exempt-issue-label: keep-open + exempt-pr-label: keep-open \ No newline at end of file diff --git a/.github/workflows/welcome-first-time-contrib.yml b/.github/workflows/welcome-first-time-contrib.yml new file mode 100644 index 000000000..df7aa3472 --- /dev/null +++ b/.github/workflows/welcome-first-time-contrib.yml @@ -0,0 +1,23 @@ +name: Welcome first time contributors + +on: + pull_request_target: + types: + - opened + issues: + types: + - opened + +jobs: + welcome: + runs-on: ubuntu-latest + steps: + - uses: actions/first-interaction@v1.0.0 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + issue-message: | + Welcome to AsyncAPI. Thanks a lot for reporting your first issue. + Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out [this issue](https://github.com/asyncapi/asyncapi/issues/115). + pr-message: | + Welcome to AsyncAPI. Thanks a lot for creating your first pull request. + Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out [this issue](https://github.com/asyncapi/asyncapi/issues/115). \ No newline at end of file diff --git a/README.md b/README.md index 17fd49cda..44b2dbd9a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This template is for generating a TypeScript/Node.js NATS client based on an Asy # How to use Example generations can be found under [examples](./examples) which includes [publish and subscribe](./examples/publish%20subscribe) example as well as [request and reply](./examples/request%20reply). ## Requirements -* @asyncapi/generator <= v1.0.0-rc.5 +* @asyncapi/generator <= v1.0.0-rc.11 Install the generator through [npm or run it from docker official installer](https://github.com/asyncapi/generator#install). diff --git a/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts b/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts index 6883661a8..de1497c19 100644 --- a/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts +++ b/examples/publish subscribe/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts @@ -31,7 +31,7 @@ const splits = [ ]; channel = channel.substring(splits[0].length); var streetlightIdEnd = channel.indexOf(splits[1]); -var streetlightIdParam = channel.substring(0, streetlightIdEnd); +var streetlightIdParam = "" + channel.substring(0, streetlightIdEnd); try { diff --git a/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts b/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts index 3265c5588..b20360301 100644 --- a/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts +++ b/examples/publish subscribe/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts @@ -31,7 +31,7 @@ const splits = [ ]; channel = channel.substring(splits[0].length); var streetlightIdEnd = channel.indexOf(splits[1]); -var streetlightIdParam = channel.substring(0, streetlightIdEnd); +var streetlightIdParam = "" + channel.substring(0, streetlightIdEnd); try { diff --git a/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts index 301bfb150..3e75fdd9a 100644 --- a/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts +++ b/examples/request reply/streetlight/src/channels/StreetlightStreetlightIdCommandTurnon.ts @@ -33,7 +33,7 @@ const splits = [ ]; channel = channel.substring(splits[0].length); var streetlightIdEnd = channel.indexOf(splits[1]); -var streetlightIdParam = channel.substring(0, streetlightIdEnd); +var streetlightIdParam = "" + channel.substring(0, streetlightIdEnd); try { diff --git a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts index a3f1a18d5..43159bcd9 100644 --- a/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts +++ b/examples/request reply/streetlight/src/tests/testclient/testchannels/StreetlightStreetlightIdEventTurnon.ts @@ -33,7 +33,7 @@ const splits = [ ]; channel = channel.substring(splits[0].length); var streetlightIdEnd = channel.indexOf(splits[1]); -var streetlightIdParam = channel.substring(0, streetlightIdEnd); +var streetlightIdParam = "" + channel.substring(0, streetlightIdEnd); try { diff --git a/package.json b/package.json index b7bf2a581..7d93e9f50 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,25 @@ "nats", "template" ], + "repository": { + "type": "git", + "url": "git+https://github.com/asyncapi/ts-nats-template.git" + }, + "bugs": { + "url": "https://github.com/asyncapi/ts-nats-template/issues" + }, + "homepage": "https://github.com/asyncapi/ts-nats-template#readme", "author": "Jonas Lagoni (jonas-lt@live.dk)", "license": "Apache-2.0", + "scripts": { + "generate:examples": "npm run generate:examples:pubSub && npm run generate:examples:requestReply", + "generate:examples:pubSub": "cd \"examples/publish subscribe\" && sh generate.sh", + "generate:examples:requestReply": "cd \"examples/request reply\" && sh generate.sh", + "release": "semantic-release", + "lint": "echo \"No linter specified yet\"", + "test": "echo \"No tests specified yet\"", + "get-version": "echo $npm_package_version" + }, "dependencies": { "filenamify": "^4.1.0", "lodash": "^4.17.15", @@ -18,6 +35,38 @@ "quicktype-core": "6.0.66", "is-url": "1.2.4" }, + "publishConfig": { + "access": "public" + }, + "devDependencies": { + "@semantic-release/commit-analyzer": "^8.0.1", + "@semantic-release/github": "^7.0.4", + "@semantic-release/npm": "^7.0.3", + "@semantic-release/release-notes-generator": "^9.0.1", + "conventional-changelog-conventionalcommits": "^4.2.3", + "semantic-release": "^17.0.4" + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits" + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits" + } + ], + "@semantic-release/npm", + "@semantic-release/github" + ] + }, "generator": { "supportedProtocols": [ "nats" @@ -34,7 +83,7 @@ "required": false } }, - "generator": ">=0.50.0 <=1.0.0-rc.10", + "generator": ">=1.0.0-rc.11", "filters": [ "@asyncapi/generator-filters" ] From 2500513cb04e01de49acb3e924dc3ebbf2c4a4f2 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Tue, 29 Sep 2020 00:40:54 +0200 Subject: [PATCH 103/110] Renamed workflow step --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 091c4094e..24117d005 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: run: npm ci - name: Run tests run: npm test - - name: Re generate examples + - name: Re-generate examples run: npm generate:examples - name: Get version from package.json before release step id: initversion From 20e51d1b4c5d6e480c10dabd5c2fbf3ab79ac485 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Tue, 29 Sep 2020 12:16:51 +0200 Subject: [PATCH 104/110] Removed unintended example. --- examples/publish subscribe/README.md | 21 - .../bin/StreetlightController.js | 46 - examples/publish subscribe/bin/streetlight.js | 46 - examples/publish subscribe/package-lock.json | 1346 ----------------- examples/publish subscribe/package.json | 14 - examples/request reply/README.md | 26 - .../bin/StreetlightController.js | 46 - examples/request reply/bin/streetlight.js | 49 - examples/request reply/package-lock.json | 1346 ----------------- examples/request reply/package.json | 14 - 10 files changed, 2954 deletions(-) delete mode 100644 examples/publish subscribe/README.md delete mode 100644 examples/publish subscribe/bin/StreetlightController.js delete mode 100644 examples/publish subscribe/bin/streetlight.js delete mode 100644 examples/publish subscribe/package-lock.json delete mode 100644 examples/publish subscribe/package.json delete mode 100644 examples/request reply/README.md delete mode 100644 examples/request reply/bin/StreetlightController.js delete mode 100644 examples/request reply/bin/streetlight.js delete mode 100644 examples/request reply/package-lock.json delete mode 100644 examples/request reply/package.json diff --git a/examples/publish subscribe/README.md b/examples/publish subscribe/README.md deleted file mode 100644 index f25793a49..000000000 --- a/examples/publish subscribe/README.md +++ /dev/null @@ -1,21 +0,0 @@ -

Streetlight example

-

- Publish and subscribe -

- - -# How to run it - -1. Run the docker-compose file `../docker-compose.yml` or run the NATS server your self locally on the standard port. -2. Install the dependencies `npm i` -3. Run the local test with `npm run start` - - - -# Description - -This example contains two channels are: - -`streetlight/{streetlight_id}/command/turnon` which are for subscribing to the command `turnon`. The generated client interprets this as the NATS topic `streetlight.{streetlight_id}.command.turnon`. The `{streetlight_id}` is the channel parameter which are not realized before actually subscribing to anything. When a message is received on channel `streetlight.1.command.turnon` it can automatically interpret what the `streetlight_id` parameter is. - -`streetlight/{streetlight_id}/event/turnon` are for publishing when the light is acutally turned on. diff --git a/examples/publish subscribe/bin/StreetlightController.js b/examples/publish subscribe/bin/StreetlightController.js deleted file mode 100644 index 295e96cab..000000000 --- a/examples/publish subscribe/bin/StreetlightController.js +++ /dev/null @@ -1,46 +0,0 @@ -const {AvailableEvents, NatsAsyncApiClient, TestClient, TurnonCommandMessage} = require("nats-client"); -const natsTestClient = new TestClient.NatsAsyncApiTestClient(); -const streetlight = "test_1"; -const stopApplication = () => { - setTimeout(() => { - natsTestClient.disconnect(); - }, 1000) -}; -natsTestClient.on(AvailableEvents.connect, async (connection, serverURL, info) => { - console.log("StreetLightController: connected"); - - //Listen for when the streetlight turns on. - natsTestClient.subscribeToStreetlightStreetlightIdEventTurnon( - (err, msg, streetlight_id) => { - return new Promise((resolve, reject) => { - console.log(`StreetLightController: Received message that streetlight ${streetlight_id} is turned on message was: ${JSON.stringify(msg)}`); - stopApplication(); - }); - }, - streetlight, - { - max: 1 - } - ); -}); - -async function connect(){ - console.log("Connecting client"); - try{ - await natsTestClient.connectToHost("localhost:4222", {reconnectTimeWait: 1000, reconnect: true, waitOnFirstConnect: true, maxReconnectAttempts: -1}); - }catch(e){ - console.log("Could not connect client") - console.log(e); - } -} -connect(); - -// Wait a bit before sending the request. -const timeoutFunction = setTimeout(async () => { - if(!natsTestClient.isClosed()){ - clearTimeout(timeoutFunction); - console.log(`StreetLightController: Publishing to turn on the streetlight`) - const publishMessage = TurnonCommandMessage.Convert.toTurnonCommand(JSON.stringify({lumen: 100})); - await natsTestClient.publishToStreetlightStreetlightIdCommandTurnon(publishMessage, streetlight); - } -}, 5000); \ No newline at end of file diff --git a/examples/publish subscribe/bin/streetlight.js b/examples/publish subscribe/bin/streetlight.js deleted file mode 100644 index 31c8f7ee5..000000000 --- a/examples/publish subscribe/bin/streetlight.js +++ /dev/null @@ -1,46 +0,0 @@ -const {AvailableEvents, NatsAsyncApiClient, AnonymousMessage1Message} = require("nats-client"); -const natsClient = new NatsAsyncApiClient(); -const streetlight = "test_1"; -const stopApplication = () => { - setTimeout(() => { - natsClient.disconnect(); - }, 1000) -}; -natsClient.on(AvailableEvents.connect, (connection, serverURL, info) => { - console.log("NatsAsyncApiClient connected"); - - //Listen for when the controller want to turn on the streetlight - natsClient.subscribeToStreetlightStreetlightIdCommandTurnon( - async (err, msg, streetlight_id) => { - console.log(`Streetlight: Received message to turn on the streetlight ${streetlight_id}, publish message was: ${JSON.stringify(msg)}`) - - //lets publish that the light is turned on. - const publish = async (lumen) => { - try{ - console.log(`Streetlight: publishing that the light is turned on`); - const publishMessage = new AnonymousMessage1Message.Convert.toAnonymousMessage1(JSON.stringify({lumen: lumen})); - await natsClient.publishToStreetlightStreetlightIdEventTurnon(publishMessage, streetlight); - stopApplication(); - }catch(e){ - console.log("Streetlight: Something went wrong when requesting the event StreetlightStreetlightIdEventTurnon"); - console.log(e); - } - } - publish(msg.lumen); - }, - streetlight, - { - max: 1 - } - ); -}); -async function connect(){ - console.log("Connecting client"); - try{ - await natsClient.connectToHost("localhost:4222", {reconnectTimeWait: 1000, reconnect: true, waitOnFirstConnect: true, maxReconnectAttempts: -1}); - }catch(e){ - console.log("Could not connect client") - console.log(e); - } -} -connect(); diff --git a/examples/publish subscribe/package-lock.json b/examples/publish subscribe/package-lock.json deleted file mode 100644 index 637f7eeea..000000000 --- a/examples/publish subscribe/package-lock.json +++ /dev/null @@ -1,1346 +0,0 @@ -{ - "name": "publish-subscribe", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "concurrently": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.2.0.tgz", - "integrity": "sha512-XxcDbQ4/43d6CxR7+iV8IZXhur4KbmEJk1CetVMUqCy34z9l0DkszbY+/9wvmSnToTej0SYomc2WSRH+L0zVJw==", - "requires": { - "chalk": "^2.4.2", - "date-fns": "^2.0.1", - "lodash": "^4.17.15", - "read-pkg": "^4.0.1", - "rxjs": "^6.5.2", - "spawn-command": "^0.0.2-1", - "supports-color": "^6.1.0", - "tree-kill": "^1.2.2", - "yargs": "^13.3.0" - } - }, - "date-fns": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.15.0.tgz", - "integrity": "sha512-ZCPzAMJZn3rNUvvQIMlXhDr4A+Ar07eLeGsGREoWU19a3Pqf5oYa+ccd+B3F6XVtQY6HANMFdOQ8A+ipFnvJdQ==" - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "nats-client": { - "version": "file:streetlight", - "requires": { - "@types/klaw-sync": "^6.0.0", - "@types/node": "13.9.5", - "ts-nats": "1.2.4", - "ts-nkeys": "1.0.16", - "typescript": "3.4.3" - }, - "dependencies": { - "@types/chai": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz", - "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==" - }, - "@types/klaw-sync": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@types/klaw-sync/-/klaw-sync-6.0.0.tgz", - "integrity": "sha512-Ibfb2jgpjYUxnl7RSVvUzOrv/vhkTVKEfPwQf9ZlDDsSyWVDp/2JtTBxO4eRrKBYtxc3cZQabdR38i8R0o1uww==", - "requires": { - "@types/node": "*" - } - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==" - }, - "@types/node": { - "version": "13.9.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.5.tgz", - "integrity": "sha512-hkzMMD3xu6BrJpGVLeQ3htQQNAcOrJjX7WFmtK8zWQpz2UJf13LCFF2ALA7c9OVdvc2vQJeDdjfR35M0sBCxvw==" - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "requires": { - "is-buffer": "~2.0.3" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "requires": { - "has-symbols": "^1.0.1" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "requires": { - "chalk": "^2.4.2" - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "nuid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/nuid/-/nuid-1.1.4.tgz", - "integrity": "sha512-PXiYyHhGfrq8H4g5HyC8enO1lz6SBe5z6x1yx/JG4tmADzDGJVQy3l1sRf3VtEvPsN8dGn9hRFRwDKWL62x0BA==" - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "requires": { - "picomatch": "^2.0.4" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } - }, - "ts-nats": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/ts-nats/-/ts-nats-1.2.4.tgz", - "integrity": "sha512-bIC+PlwHplRqhooa9kE+QPcQ9RPGUXD2ruvdf6LoFpP6MjE6exVoRhYSydm0e5wk7VfuXpTbH1NoopTKHwlOKA==", - "requires": { - "nuid": "^1.1.0", - "ts-nkeys": "^1.0.12" - } - }, - "ts-nkeys": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/ts-nkeys/-/ts-nkeys-1.0.16.tgz", - "integrity": "sha512-1qrhAlavbm36wtW+7NtKOgxpzl+70NTF8xlz9mEhiA5zHMlMxjj3sEVKWm3pGZhHXE0Q3ykjrj+OSRVaYw+Dqg==", - "requires": { - "tweetnacl": "^1.0.3" - } - }, - "ts-node": { - "version": "8.10.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", - "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", - "requires": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" - } - } - }, - "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" - }, - "typescript": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.3.tgz", - "integrity": "sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ==" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" - } - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" - }, - "read-pkg": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", - "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", - "requires": { - "normalize-package-data": "^2.3.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "rxjs": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz", - "integrity": "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==", - "requires": { - "tslib": "^1.9.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "spawn-command": { - "version": "0.0.2-1", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", - "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=" - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" - }, - "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } -} diff --git a/examples/publish subscribe/package.json b/examples/publish subscribe/package.json deleted file mode 100644 index acd3a1839..000000000 --- a/examples/publish subscribe/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "publish-subscribe", - "version": "1.0.0", - "description": "Publish and subscribe example", - "scripts": { - "start": "concurrently \"node ./bin/streetlight\" \"node ./bin/streetlightController\"" - }, - "dependencies": { - "nats-client": "file:./streetlight", - "concurrently": "5.2.0" - }, - "author": "", - "license": "ISC" -} diff --git a/examples/request reply/README.md b/examples/request reply/README.md deleted file mode 100644 index 3abf8f867..000000000 --- a/examples/request reply/README.md +++ /dev/null @@ -1,26 +0,0 @@ -

Streetlight example

-

- Request and reply -

- - -# How to run it - -1. Run the docker-compose file `../docker-compose.yml` or run the NATS server your self locally on the standard port. -2. Install the dependencies `npm i` -3. Run the local test with `npm run start` - - - -# Description -This example contains two channels are: - -`streetlight/{streetlight_id}/command/turnon` which are for replying to the command `turnon`. The generated client interprets this as the NATS topic `streetlight.{streetlight_id}.command.turnon`. The `{streetlight_id}` is the channel parameter which are not realized before actually subscribing to anything. When a message is received on channel `streetlight.1.command.turnon` it can automatically interpret what the `streetlight_id` parameter is. - -`streetlight/{streetlight_id}/event/turnon` which are for requesting another application when the light is acutally turned on. - - - -One very important thing to keep in mind here when looking at the streetlight [AsyncAPI document](./streetlight.json) you might notice that the publish and subscribe operations look weird and reversed. If not, great skip the following explaination. The request/reply pattern uses the existing publish and subscribe operations to define what is replied and what is requested. This is determined by the NATS bindings provided by the AsyncAPI spec. As observed for the channel `streetlight/{streetlight_id}/command/turnon` its bindings are defined as being a `replier`. This means that the publish operation are used to describe what is being published to the application and the subscribe operation describes the corresponding reply. - -For the request channel `streetlight/{streetlight_id}/event/turnon` it has the binding `requester` which means that the publish operation are used to describe what is being published to it and the subscribe operation are used to describe what the request the application are to send. \ No newline at end of file diff --git a/examples/request reply/bin/StreetlightController.js b/examples/request reply/bin/StreetlightController.js deleted file mode 100644 index 958289245..000000000 --- a/examples/request reply/bin/StreetlightController.js +++ /dev/null @@ -1,46 +0,0 @@ -const {AvailableEvents, TestClient, GeneralReplyMessage, TurnonCommandMessage} = require("nats-client"); -const natsTestClient = new TestClient.NatsAsyncApiTestClient(); -const streetlight = "test_1"; -const stopApplication = () => { - setTimeout(() => { - natsTestClient.disconnect(); - }, 1000); -} -natsTestClient.on(AvailableEvents.connect, async (connection, serverURL, info) => { - console.log("StreetLightController: connected"); - - //Listen for when the streetlight turns on. - natsTestClient.replyToStreetlightStreetlightIdEventTurnon((err, msg, streetlight_id) => { - return new Promise((resolve, reject) => { - console.log(`StreetLightController: Received request that streetlight ${streetlight_id} is turned on message was: ${JSON.stringify(msg)}`); - const replyMessage = new GeneralReplyMessage.Convert.toGeneralReply(JSON.stringify({status_code: 200, status_message: "Ok"})); - resolve(replyMessage); - stopApplication(); - }); - }, (err) => { - console.log("StreetLightController: Could not setup reply"); - console.log(err); - }, streetlight); -}); - -async function connect(){ - console.log("Connecting all client"); - try{ - await natsTestClient.connectToHost("localhost:4222", {reconnectTimeWait: 1000, reconnect: true, waitOnFirstConnect: true, maxReconnectAttempts: -1}); - }catch(e){ - console.log("Could not connect client") - console.log(e); - } -} -connect(); - -// Wait a bit before sending the request. -const timeoutFunction = setTimeout(async () => { - if(!natsTestClient.isClosed()){ - clearTimeout(timeoutFunction); - console.log(`StreetLightController: Requesting to turn on the streetlight`) - const requestMessage = TurnonCommandMessage.Convert.toTurnonCommand(JSON.stringify({lumen: 100})); - const replyMessage = await natsTestClient.requestStreetlightStreetlightIdCommandTurnon(requestMessage, streetlight); - console.log(`StreetLightController: got reply from our request to streetlight ${streetlight}, response message was: ${JSON.stringify(replyMessage)}`) - } -}, 5000); \ No newline at end of file diff --git a/examples/request reply/bin/streetlight.js b/examples/request reply/bin/streetlight.js deleted file mode 100644 index bea45ce28..000000000 --- a/examples/request reply/bin/streetlight.js +++ /dev/null @@ -1,49 +0,0 @@ -const {AvailableEvents, NatsAsyncApiClient, GeneralReplyMessage, AnonymousMessage3Message} = require("nats-client"); -const natsClient = new NatsAsyncApiClient(); -const streetlight = "test_1"; -const stopApplication = () => { - natsClient.disconnect(); -} -natsClient.on(AvailableEvents.connect, (connection, serverURL, info) => { - console.log("NatsAsyncApiClient connected"); - - //Listen for when the controller want to turn on the streetlight - natsClient.replyToStreetlightStreetlightIdCommandTurnon( - (err, msg, streetlight_id) => { - return new Promise(async (resolve, reject) => { - console.log(`NatsClient: Received request to turn on the streetlight ${streetlight_id}, request message was: ${JSON.stringify(msg)}`) - const replyMessage = new GeneralReplyMessage.Convert.toGeneralReply(JSON.stringify({status_code: 200, status_message: "Ok"})); - resolve(replyMessage); - - //lets request that the light is turned on. - const request = async (lumen) => { - try{ - console.log(`NatsClient: requesting that the light is turned on`) - const newRequestMessage = new AnonymousMessage3Message.Convert.toAnonymousMessage3(JSON.stringify({lumen: lumen})); - const replyFromRequest = await natsClient.requestStreetlightStreetlightIdEventTurnon(newRequestMessage, streetlight); - console.log(`NatsClient: received reply to our request. Reply was: ${JSON.stringify(replyFromRequest)}`); - stopApplication(); - }catch(e){ - console.log("NatsClient: Something went wrong when requesting the event StreetlightStreetlightIdEventTurnon"); - console.log(e); - } - } - request(msg.lumen); - }); - }, (err) => { - console.log("NatsClient: Could not setup reply"); - console.log(err); - }, - streetlight - ); -}); -async function connect(){ - console.log("Connecting client"); - try{ - await natsClient.connectToHost("localhost:4222", {reconnectTimeWait: 1000, reconnect: true, waitOnFirstConnect: true, maxReconnectAttempts: -1}); - }catch(e){ - console.log("Could not connect client") - console.log(e); - } -} -connect(); diff --git a/examples/request reply/package-lock.json b/examples/request reply/package-lock.json deleted file mode 100644 index e7d445d33..000000000 --- a/examples/request reply/package-lock.json +++ /dev/null @@ -1,1346 +0,0 @@ -{ - "name": "request-reply", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "concurrently": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.2.0.tgz", - "integrity": "sha512-XxcDbQ4/43d6CxR7+iV8IZXhur4KbmEJk1CetVMUqCy34z9l0DkszbY+/9wvmSnToTej0SYomc2WSRH+L0zVJw==", - "requires": { - "chalk": "^2.4.2", - "date-fns": "^2.0.1", - "lodash": "^4.17.15", - "read-pkg": "^4.0.1", - "rxjs": "^6.5.2", - "spawn-command": "^0.0.2-1", - "supports-color": "^6.1.0", - "tree-kill": "^1.2.2", - "yargs": "^13.3.0" - } - }, - "date-fns": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.15.0.tgz", - "integrity": "sha512-ZCPzAMJZn3rNUvvQIMlXhDr4A+Ar07eLeGsGREoWU19a3Pqf5oYa+ccd+B3F6XVtQY6HANMFdOQ8A+ipFnvJdQ==" - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "nats-client": { - "version": "file:streetlight", - "requires": { - "@types/klaw-sync": "^6.0.0", - "@types/node": "13.9.5", - "ts-nats": "1.2.4", - "ts-nkeys": "1.0.16", - "typescript": "3.4.3" - }, - "dependencies": { - "@types/chai": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz", - "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==" - }, - "@types/klaw-sync": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@types/klaw-sync/-/klaw-sync-6.0.0.tgz", - "integrity": "sha512-Ibfb2jgpjYUxnl7RSVvUzOrv/vhkTVKEfPwQf9ZlDDsSyWVDp/2JtTBxO4eRrKBYtxc3cZQabdR38i8R0o1uww==", - "requires": { - "@types/node": "*" - } - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==" - }, - "@types/node": { - "version": "13.9.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.5.tgz", - "integrity": "sha512-hkzMMD3xu6BrJpGVLeQ3htQQNAcOrJjX7WFmtK8zWQpz2UJf13LCFF2ALA7c9OVdvc2vQJeDdjfR35M0sBCxvw==" - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "requires": { - "is-buffer": "~2.0.3" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "requires": { - "has-symbols": "^1.0.1" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "requires": { - "chalk": "^2.4.2" - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "nuid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/nuid/-/nuid-1.1.4.tgz", - "integrity": "sha512-PXiYyHhGfrq8H4g5HyC8enO1lz6SBe5z6x1yx/JG4tmADzDGJVQy3l1sRf3VtEvPsN8dGn9hRFRwDKWL62x0BA==" - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "requires": { - "picomatch": "^2.0.4" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } - }, - "ts-nats": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/ts-nats/-/ts-nats-1.2.4.tgz", - "integrity": "sha512-bIC+PlwHplRqhooa9kE+QPcQ9RPGUXD2ruvdf6LoFpP6MjE6exVoRhYSydm0e5wk7VfuXpTbH1NoopTKHwlOKA==", - "requires": { - "nuid": "^1.1.0", - "ts-nkeys": "^1.0.12" - } - }, - "ts-nkeys": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/ts-nkeys/-/ts-nkeys-1.0.16.tgz", - "integrity": "sha512-1qrhAlavbm36wtW+7NtKOgxpzl+70NTF8xlz9mEhiA5zHMlMxjj3sEVKWm3pGZhHXE0Q3ykjrj+OSRVaYw+Dqg==", - "requires": { - "tweetnacl": "^1.0.3" - } - }, - "ts-node": { - "version": "8.10.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", - "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", - "requires": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" - } - } - }, - "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" - }, - "typescript": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.3.tgz", - "integrity": "sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ==" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" - } - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" - }, - "read-pkg": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", - "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", - "requires": { - "normalize-package-data": "^2.3.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "rxjs": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz", - "integrity": "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==", - "requires": { - "tslib": "^1.9.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "spawn-command": { - "version": "0.0.2-1", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", - "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=" - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" - }, - "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } -} diff --git a/examples/request reply/package.json b/examples/request reply/package.json deleted file mode 100644 index 959fdca05..000000000 --- a/examples/request reply/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "request-reply", - "version": "1.0.0", - "description": "Request and reply example", - "scripts": { - "start": "concurrently \"node ./bin/streetlight\" \"node ./bin/streetlightController\"" - }, - "dependencies": { - "nats-client": "file:./streetlight", - "concurrently": "5.2.0" - }, - "author": "", - "license": "ISC" -} From f28f22aa6df45dcc729e6fc70ef70fbe5a19249b Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Tue, 29 Sep 2020 12:20:09 +0200 Subject: [PATCH 105/110] Updated README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 44b2dbd9a..1865aa320 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ connect(); ``` # Features -* Supports wildcard channels. AsyncAPI describes the channel path to be defined as [RFC 6570 URI](https://www.asyncapi.com/docs/specifications/2.0.0/#a-name-channelsobject-a-channels-object). So a channel containing a wildcard needs to be defined as `smartylighting/streetlights/*`. This also works with parameters such as `smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured`, ensure to define the type of the parameter as a String if you want to use wildcards. +* Supports wildcard channels. AsyncAPI describes the channel path to be defined as [RFC 6570 URI](https://www.asyncapi.com/docs/specifications/2.0.0/#a-name-channelsobject-a-channels-object). So a channel containing a wildcard needs to be defined with parameters such as `smartylighting/streetlights/{wildcard}`. * Supports [test/mirror client](#test-client) for testing or other useful scenarios. * This template can be used as a javascript library as well since the generated code works directly in Node.js. * This template uses [quicktype](https://quicktype.io/) to generate the corresponding message payloads. @@ -197,7 +197,7 @@ These are the available template parameters: | promisifyReplyCallback | Boolean | Use this parameter to change from the default regular callback when using the request operation. Add the following to the CLI when generating your code `--param "promisifyReplyCallback=true"` # Test Client -The test client is like a mirror client. It does everything the opposite, when you define a subscription operation it will generate a subscription operation in the test client. This is opposite to what the specification dictates. This client can be used to create integration tests or other useful scenarios. +The test client is like a mirror client. It does everything the opposite, when you define a subscription operation it will generate a subscription operation in the test client. This is opposite to what the specification dictates. This client can be used to create integration tests or in other useful scenarios. # Supported Content Types The following payload types are supported, this is limited to the underlying NATS TypeScript library: @@ -245,7 +245,7 @@ There are different hook restrictions based on the payload type. The first hook always receives the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return a buffer to transmit. ### JSON payloads -The first hook always receives the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return the correct message type. +The first hook always receives the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return a JSON message. ### String payloads The first hook always receives the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return a string representation of the message. From cb640d69fa4902c58752ca68540799d2e9df5257 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Wed, 18 Nov 2020 16:10:31 +0100 Subject: [PATCH 106/110] Updated package file --- package-lock.json | 6013 ++++++++++++++++++++++++++++++++++++++++++++- package.json | 68 +- 2 files changed, 6033 insertions(+), 48 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5ecfdd256..7f80d8d5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,32 @@ "openapi-sampler": "^1.0.0-beta.15" } }, + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, "@mark.probst/unicode-properties": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@mark.probst/unicode-properties/-/unicode-properties-1.1.0.tgz", @@ -23,11 +49,350 @@ "unicode-trie": "^0.3.0" } }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, + "@octokit/auth-token": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.3.tgz", + "integrity": "sha512-fdGoOQ3kQJh+hrilc0Plg50xSfaCKOeYN9t6dpJKXN9BxhhfquL0OzoQXg3spLYymL5rm29uPeI3KEXRaZQ9zg==", + "dev": true, + "requires": { + "@octokit/types": "^5.0.0" + } + }, + "@octokit/core": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.2.1.tgz", + "integrity": "sha512-XfFSDDwv6tclUenS0EmB6iA7u+4aOHBT1Lz4PtQNQQg3hBbNaR/+Uv5URU+egeIuuGAiMRiDyY92G4GBOWOqDA==", + "dev": true, + "requires": { + "@octokit/auth-token": "^2.4.0", + "@octokit/graphql": "^4.3.1", + "@octokit/request": "^5.4.0", + "@octokit/types": "^5.0.0", + "before-after-hook": "^2.1.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/endpoint": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.9.tgz", + "integrity": "sha512-3VPLbcCuqji4IFTclNUtGdp9v7g+nspWdiCUbK3+iPMjJCZ6LEhn1ts626bWLOn0GiDb6j+uqGvPpqLnY7pBgw==", + "dev": true, + "requires": { + "@octokit/types": "^5.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/graphql": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.5.7.tgz", + "integrity": "sha512-Gk0AR+DcwIK/lK/GX+OQ99UqtenQhcbrhHHfOYlrCQe17ADnX3EKAOKRsAZ9qZvpi5MuwWm/Nm+9aO2kTDSdyA==", + "dev": true, + "requires": { + "@octokit/request": "^5.3.0", + "@octokit/types": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/plugin-paginate-rest": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.6.0.tgz", + "integrity": "sha512-o+O8c1PqsC5++BHXfMZabRRsBIVb34tXPWyQLyp2IXq5MmkxdipS7TXM4Y9ldL1PzY9CTrCsn/lzFFJGM3oRRA==", + "dev": true, + "requires": { + "@octokit/types": "^5.5.0" + } + }, + "@octokit/plugin-request-log": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.2.tgz", + "integrity": "sha512-oTJSNAmBqyDR41uSMunLQKMX0jmEXbwD1fpz8FG27lScV3RhtGfBa1/BBLym+PxcC16IBlF7KH9vP1BUYxA+Eg==", + "dev": true + }, + "@octokit/plugin-rest-endpoint-methods": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-4.2.1.tgz", + "integrity": "sha512-QyFr4Bv807Pt1DXZOC5a7L5aFdrwz71UHTYoHVajYV5hsqffWm8FUl9+O7nxRu5PDMtB/IKrhFqTmdBTK5cx+A==", + "dev": true, + "requires": { + "@octokit/types": "^5.5.0", + "deprecation": "^2.3.1" + } + }, + "@octokit/request": { + "version": "5.4.10", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.10.tgz", + "integrity": "sha512-egA49HkqEORVGDZGav1mh+VD+7uLgOxtn5oODj6guJk0HCy+YBSYapFkSLFgeYj3Fr18ZULKGURkjyhkAChylw==", + "dev": true, + "requires": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.0.0", + "@octokit/types": "^5.0.0", + "deprecation": "^2.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.1", + "once": "^1.4.0", + "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "dev": true + } + } + }, + "@octokit/request-error": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.3.tgz", + "integrity": "sha512-GgD5z8Btm301i2zfvJLk/mkhvGCdjQ7wT8xF9ov5noQY8WbKZDH9cOBqXzoeKd1mLr1xH2FwbtGso135zGBgTA==", + "dev": true, + "requires": { + "@octokit/types": "^5.0.1", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/rest": { + "version": "18.0.9", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.0.9.tgz", + "integrity": "sha512-CC5+cIx974Ygx9lQNfUn7/oXDQ9kqGiKUC6j1A9bAVZZ7aoTF8K6yxu0pQhQrLBwSl92J6Z3iVDhGhGFgISCZg==", + "dev": true, + "requires": { + "@octokit/core": "^3.0.0", + "@octokit/plugin-paginate-rest": "^2.2.0", + "@octokit/plugin-request-log": "^1.0.0", + "@octokit/plugin-rest-endpoint-methods": "4.2.1" + } + }, + "@octokit/types": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-5.5.0.tgz", + "integrity": "sha512-UZ1pErDue6bZNjYOotCNveTXArOMZQFG6hKJfOnGnulVCMcVVi7YIIuuR4WfBhjo7zgpmzn/BkPDnUXtNx+PcQ==", + "dev": true, + "requires": { + "@types/node": ">= 8" + } + }, + "@semantic-release/commit-analyzer": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-8.0.1.tgz", + "integrity": "sha512-5bJma/oB7B4MtwUkZC2Bf7O1MHfi4gWe4mA+MIQ3lsEV0b422Bvl1z5HRpplDnMLHH3EXMoRdEng6Ds5wUqA3A==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^5.0.0", + "conventional-commits-filter": "^2.0.0", + "conventional-commits-parser": "^3.0.7", + "debug": "^4.0.0", + "import-from": "^3.0.0", + "lodash": "^4.17.4", + "micromatch": "^4.0.2" + } + }, + "@semantic-release/error": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", + "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", + "dev": true + }, + "@semantic-release/github": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-7.2.0.tgz", + "integrity": "sha512-tMRnWiiWb43whRHvbDGXq4DGEbKRi56glDpXDJZit4PIiwDPX7Kx3QzmwRtDOcG+8lcpGjpdPabYZ9NBxoI2mw==", + "dev": true, + "requires": { + "@octokit/rest": "^18.0.0", + "@semantic-release/error": "^2.2.0", + "aggregate-error": "^3.0.0", + "bottleneck": "^2.18.1", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "fs-extra": "^9.0.0", + "globby": "^11.0.0", + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "issue-parser": "^6.0.0", + "lodash": "^4.17.4", + "mime": "^2.4.3", + "p-filter": "^2.0.0", + "p-retry": "^4.0.0", + "url-join": "^4.0.0" + } + }, + "@semantic-release/npm": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-7.0.8.tgz", + "integrity": "sha512-8c1TLwKB/xT5E1FNs5l4GFtaNTznHesJk7tw3pGSlVxRqDXa1EZI+DfziZlO58Wk3PpS2ecu661kvBdz9aMgYQ==", + "dev": true, + "requires": { + "@semantic-release/error": "^2.2.0", + "aggregate-error": "^3.0.0", + "execa": "^4.0.0", + "fs-extra": "^9.0.0", + "lodash": "^4.17.15", + "nerf-dart": "^1.0.0", + "normalize-url": "^5.0.0", + "npm": "^6.14.8", + "rc": "^1.2.8", + "read-pkg": "^5.0.0", + "registry-auth-token": "^4.0.0", + "semver": "^7.1.2", + "tempy": "^1.0.0" + } + }, + "@semantic-release/release-notes-generator": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-9.0.1.tgz", + "integrity": "sha512-bOoTiH6SiiR0x2uywSNR7uZcRDl22IpZhj+Q5Bn0v+98MFtOMhCxFhbrKQjhbYoZw7vps1mvMRmFkp/g6R9cvQ==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^5.0.0", + "conventional-changelog-writer": "^4.0.0", + "conventional-commits-filter": "^2.0.0", + "conventional-commits-parser": "^3.0.0", + "debug": "^4.0.0", + "get-stream": "^5.0.0", + "import-from": "^3.0.0", + "into-stream": "^5.0.0", + "lodash": "^4.17.4", + "read-pkg-up": "^7.0.0" + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, + "@types/minimist": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", + "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", + "dev": true + }, + "@types/node": { + "version": "14.14.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.8.tgz", + "integrity": "sha512-z/5Yd59dCKI5kbxauAJgw6dLPzW+TNOItNE00PkpzNwUIEwdj/Lsqwq94H5DdYBX7C13aRA0CY32BK76+neEUA==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, "acorn": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==" }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=", + "dev": true + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -36,6 +401,73 @@ "sprintf-js": "~1.0.2" } }, + "argv-formatter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", + "integrity": "sha1-oMoMvCmltz6Dbuvhy/bF4OTrgvk=", + "dev": true + }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "before-after-hook": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.1.0.tgz", + "integrity": "sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==", + "dev": true + }, + "bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "brfs": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/brfs/-/brfs-1.6.1.tgz", @@ -57,11 +489,118 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } + }, + "cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha1-fMEFXYItISlU0HsIXeolHMe8VQU=", + "dev": true, + "requires": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-table": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", + "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", + "dev": true, + "requires": { + "colors": "1.0.3" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, "collection-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collection-utils/-/collection-utils-1.0.1.tgz", "integrity": "sha512-LA2YTIlR7biSpXkKYwwuzGjwL5rjWEZVOSnvdUc7gObvWe4WkjxOpfrdhoP7Hs09YWDVfg0Mal9BpAqLfVEzQg==" }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + }, + "compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "requires": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, "concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", @@ -73,6 +612,120 @@ "typedarray": "^0.0.6" } }, + "conventional-changelog-angular": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.12.tgz", + "integrity": "sha512-5GLsbnkR/7A89RyHLvvoExbiGbd9xKdKqDTrArnPbOqBqG/2wIosu0fHwpeIRI8Tl94MhVNBXcLJZl92ZQ5USw==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + } + }, + "conventional-changelog-conventionalcommits": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.5.0.tgz", + "integrity": "sha512-buge9xDvjjOxJlyxUnar/+6i/aVEVGA7EEh4OafBCXPlLUQPGbRUBhBUveWRxzvR8TEjhKEP4BdepnpG2FSZXw==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "lodash": "^4.17.15", + "q": "^1.5.1" + } + }, + "conventional-changelog-writer": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.18.tgz", + "integrity": "sha512-mAQDCKyB9HsE8Ko5cCM1Jn1AWxXPYV0v8dFPabZRkvsiWUul2YyAqbIaoMKF88Zf2ffnOPSvKhboLf3fnjo5/A==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.6", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + } + } + }, + "conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "dev": true, + "requires": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + } + }, + "conventional-commits-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.0.tgz", + "integrity": "sha512-XmJiXPxsF0JhAKyfA2Nn+rZwYKJ60nanlbSWwwkGwLQFbugsc0gv1rzc7VbbUWAzJfR1qR87/pNgv9NgmxtBMQ==", + "dev": true, + "requires": { + "JSONStream": "^1.0.4", + "is-text-path": "^1.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^2.0.0", + "through2": "^4.0.0", + "trim-off-newlines": "^1.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + } + } + }, "convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", @@ -86,11 +739,137 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + } + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, + "del": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz", + "integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==", + "dev": true, + "requires": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "dependencies": { + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + } + } + }, + "deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, "duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", @@ -99,6 +878,12 @@ "readable-stream": "^2.0.2" } }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "encoding": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", @@ -107,11 +892,39 @@ "iconv-lite": "^0.6.2" } }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, "entities": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" }, + "env-ci": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-5.0.2.tgz", + "integrity": "sha512-Xc41mKvjouTXD3Oy9AqySz1IeyvJvHZ20Twf5ZLYbNpPPIuCnL/qHCmNlD01LoNy0JTunw9HPYVptD19Ac7Mbw==", + "dev": true, + "requires": { + "execa": "^4.0.0", + "java-properties": "^1.0.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -151,6 +964,31 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, + "execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "dependencies": { + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + } + } + }, "falafel": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.2.4.tgz", @@ -169,11 +1007,43 @@ } } }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, + "fastq": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz", + "integrity": "sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, "filename-reserved-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", @@ -189,16 +1059,174 @@ "trim-repeated": "^1.0.0" } }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "find-versions": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz", + "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==", + "dev": true, + "requires": { + "semver-regex": "^2.0.0" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-extra": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "git-log-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz", + "integrity": "sha1-LmpMGxP8AAKCB7p5WnrDFme5/Uo=", + "dev": true, + "requires": { + "argv-formatter": "~1.0.0", + "spawn-error-forwarder": "~1.0.0", + "split2": "~1.0.0", + "stream-combiner2": "~1.1.1", + "through2": "~2.0.0", + "traverse": "~0.6.6" + }, + "dependencies": { + "split2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", + "integrity": "sha1-UuLiIdiMdfmnP5BVbiY/+WdysxQ=", + "dev": true, + "requires": { + "through2": "~2.0.0" + } + } + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "handlebars": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", + "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -207,6 +1235,54 @@ "function-bind": "^1.1.1" } }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "hook-std": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-2.0.0.tgz", + "integrity": "sha512-zZ6T5WcuBMIUVh49iPQS9t977t7C0l7OtHrpeMb5uk48JdflRX0NSFvCekfYNmGQETnLq9W/isMyHl69kxGi8g==", + "dev": true + }, + "hosted-git-info": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.7.tgz", + "integrity": "sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, "iconv-lite": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", @@ -215,16 +1291,153 @@ "safer-buffer": ">= 2.1.2 < 3.0.0" } }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "import-fresh": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", + "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "import-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-3.0.0.tgz", + "integrity": "sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "into-stream": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-5.1.1.tgz", + "integrity": "sha512-krrAJ7McQxGGmvaYbB7Q1mcA+cRwg9Ij2RfWIeVesNBgVDZmzY/Fa4IpZUT3bmdRzMzdf/mzltCG2Dq99IZGBA==", + "dev": true, + "requires": { + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, + "is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "dev": true, + "requires": { + "text-extensions": "^1.0.0" + } + }, "is-url": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", @@ -235,6 +1448,12 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, "isomorphic-fetch": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", @@ -244,11 +1463,48 @@ "whatwg-fetch": ">=0.10.0" } }, + "issue-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", + "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", + "dev": true, + "requires": { + "lodash.capitalize": "^4.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.uniqby": "^4.7.0" + } + }, + "java-properties": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", + "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", + "dev": true + }, "js-base64": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.3.tgz", "integrity": "sha512-fiUvdfCaAXoQTHdKMgTvg6IkecXDcVz6V5rlftUTclF9IKBjMizvSdQaCl/z/6TApDeby5NL+axYou3i0mu1Pg==" }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, "json-pointer": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/json-pointer/-/json-pointer-0.6.0.tgz", @@ -257,6 +1513,42 @@ "foreach": "^2.0.4" } }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -266,6 +1558,12 @@ "type-check": "~0.3.2" } }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, "linkify-it": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", @@ -274,10 +1572,94 @@ "uc.micro": "^1.0.1" } }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + } + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, + "lodash.capitalize": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", + "integrity": "sha1-+CbJtOKoUR2E46yinbBeGk87cqk=", + "dev": true + }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=", + "dev": true + }, + "lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=", + "dev": true + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "dev": true + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", + "dev": true + }, + "lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=", + "dev": true + }, + "lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI=", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } }, "magic-string": { "version": "0.22.5", @@ -287,6 +1669,12 @@ "vlq": "^0.2.2" } }, + "map-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", + "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", + "dev": true + }, "markdown-it": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", @@ -299,11 +1687,101 @@ "uc.micro": "^1.0.5" } }, + "marked": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.4.tgz", + "integrity": "sha512-6x5TFGCTKSQBLTZtOburGxCxFEBJEGYVLwCMTBCxzvyuisGcC20UNzDSJhCr/cJ/Kmh6ulfJm10g6WWEAJ3kvg==", + "dev": true + }, + "marked-terminal": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-4.1.0.tgz", + "integrity": "sha512-5KllfAOW02WS6hLRQ7cNvGOxvKW1BKuXELH4EtbWfyWgxQhROoMxEvuQ/3fTgkNjledR0J48F4HbapvYp1zWkQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.1", + "cardinal": "^2.1.1", + "chalk": "^4.0.0", + "cli-table": "^0.3.1", + "node-emoji": "^1.10.0", + "supports-hyperlinks": "^2.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" }, + "meow": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.0.0.tgz", + "integrity": "sha512-nbsTRz2fwniJBFgUkcdISq8y/q9n9VbiHYbfwklFh5V4V2uAcxtKQkDc0yCLPM/kP0d+inZBewn3zJqewHE7kg==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + } + }, "merge-source-map": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz", @@ -319,11 +1797,104 @@ } } }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mime": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", + "dev": true + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + } + }, + "modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "nerf-dart": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", + "integrity": "sha1-5tq3/r9a2Bbqgc9cYpxaDr3nLBo=", + "dev": true + }, + "node-emoji": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", + "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==", + "dev": true, + "requires": { + "lodash.toarray": "^4.4.0" + } + }, "node-fetch": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", @@ -333,11 +1904,3573 @@ "is-stream": "^1.0.1" } }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, + "normalize-package-data": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.0.tgz", + "integrity": "sha512-6lUjEI0d3v6kFrtgA/lOx4zHCWULXsFNIjHolnZCKCTLA6m/G625cdn3O7eNmT0iD3jfo6HZ9cdImGZwf21prw==", + "dev": true, + "requires": { + "hosted-git-info": "^3.0.6", + "resolve": "^1.17.0", + "semver": "^7.3.2", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-url": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-5.3.0.tgz", + "integrity": "sha512-9/nOVLYYe/dO/eJeQUNaGUF4m4Z5E7cb9oNTKabH+bNf19mqj60txTcveQxL0GlcWLXCxkOu2/LwL8oW0idIDA==", + "dev": true + }, + "npm": { + "version": "6.14.8", + "resolved": "https://registry.npmjs.org/npm/-/npm-6.14.8.tgz", + "integrity": "sha512-HBZVBMYs5blsj94GTeQZel7s9odVuuSUHy1+AlZh7rPVux1os2ashvEGLy/STNK7vUjbrCg5Kq9/GXisJgdf6A==", + "dev": true, + "requires": { + "JSONStream": "^1.3.5", + "abbrev": "~1.1.1", + "ansicolors": "~0.3.2", + "ansistyles": "~0.1.3", + "aproba": "^2.0.0", + "archy": "~1.0.0", + "bin-links": "^1.1.8", + "bluebird": "^3.5.5", + "byte-size": "^5.0.1", + "cacache": "^12.0.3", + "call-limit": "^1.1.1", + "chownr": "^1.1.4", + "ci-info": "^2.0.0", + "cli-columns": "^3.1.2", + "cli-table3": "^0.5.1", + "cmd-shim": "^3.0.3", + "columnify": "~1.5.4", + "config-chain": "^1.1.12", + "debuglog": "*", + "detect-indent": "~5.0.0", + "detect-newline": "^2.1.0", + "dezalgo": "~1.0.3", + "editor": "~1.0.0", + "figgy-pudding": "^3.5.1", + "find-npm-prefix": "^1.0.2", + "fs-vacuum": "~1.2.10", + "fs-write-stream-atomic": "~1.0.10", + "gentle-fs": "^2.3.1", + "glob": "^7.1.6", + "graceful-fs": "^4.2.4", + "has-unicode": "~2.0.1", + "hosted-git-info": "^2.8.8", + "iferr": "^1.0.2", + "imurmurhash": "*", + "infer-owner": "^1.0.4", + "inflight": "~1.0.6", + "inherits": "^2.0.4", + "ini": "^1.3.5", + "init-package-json": "^1.10.3", + "is-cidr": "^3.0.0", + "json-parse-better-errors": "^1.0.2", + "lazy-property": "~1.0.0", + "libcipm": "^4.0.8", + "libnpm": "^3.0.1", + "libnpmaccess": "^3.0.2", + "libnpmhook": "^5.0.3", + "libnpmorg": "^1.0.1", + "libnpmsearch": "^2.0.2", + "libnpmteam": "^1.0.2", + "libnpx": "^10.2.4", + "lock-verify": "^2.1.0", + "lockfile": "^1.0.4", + "lodash._baseindexof": "*", + "lodash._baseuniq": "~4.6.0", + "lodash._bindcallback": "*", + "lodash._cacheindexof": "*", + "lodash._createcache": "*", + "lodash._getnative": "*", + "lodash.clonedeep": "~4.5.0", + "lodash.restparam": "*", + "lodash.union": "~4.6.0", + "lodash.uniq": "~4.5.0", + "lodash.without": "~4.4.0", + "lru-cache": "^5.1.1", + "meant": "^1.0.2", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.5", + "move-concurrently": "^1.0.1", + "node-gyp": "^5.1.0", + "nopt": "^4.0.3", + "normalize-package-data": "^2.5.0", + "npm-audit-report": "^1.3.3", + "npm-cache-filename": "~1.0.2", + "npm-install-checks": "^3.0.2", + "npm-lifecycle": "^3.1.5", + "npm-package-arg": "^6.1.1", + "npm-packlist": "^1.4.8", + "npm-pick-manifest": "^3.0.2", + "npm-profile": "^4.0.4", + "npm-registry-fetch": "^4.0.7", + "npm-user-validate": "~1.0.0", + "npmlog": "~4.1.2", + "once": "~1.4.0", + "opener": "^1.5.1", + "osenv": "^0.1.5", + "pacote": "^9.5.12", + "path-is-inside": "~1.0.2", + "promise-inflight": "~1.0.1", + "qrcode-terminal": "^0.12.0", + "query-string": "^6.8.2", + "qw": "~1.0.1", + "read": "~1.0.7", + "read-cmd-shim": "^1.0.5", + "read-installed": "~4.0.3", + "read-package-json": "^2.1.1", + "read-package-tree": "^5.3.1", + "readable-stream": "^3.6.0", + "readdir-scoped-modules": "^1.1.0", + "request": "^2.88.0", + "retry": "^0.12.0", + "rimraf": "^2.7.1", + "safe-buffer": "^5.1.2", + "semver": "^5.7.1", + "sha": "^3.0.0", + "slide": "~1.1.6", + "sorted-object": "~2.0.1", + "sorted-union-stream": "~2.1.3", + "ssri": "^6.0.1", + "stringify-package": "^1.0.1", + "tar": "^4.4.13", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "uid-number": "0.0.6", + "umask": "~1.1.0", + "unique-filename": "^1.1.1", + "unpipe": "~1.0.0", + "update-notifier": "^2.5.0", + "uuid": "^3.3.3", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "~3.0.0", + "which": "^1.3.1", + "worker-farm": "^1.7.0", + "write-file-atomic": "^2.4.3" + }, + "dependencies": { + "JSONStream": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "agent-base": { + "version": "4.3.0", + "bundled": true, + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "agentkeepalive": { + "version": "3.5.2", + "bundled": true, + "dev": true, + "requires": { + "humanize-ms": "^1.2.1" + } + }, + "ajv": { + "version": "5.5.2", + "bundled": true, + "dev": true, + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "ansi-align": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.0.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "bundled": true, + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "ansicolors": { + "version": "0.3.2", + "bundled": true, + "dev": true + }, + "ansistyles": { + "version": "0.1.3", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "asap": { + "version": "2.0.6", + "bundled": true, + "dev": true + }, + "asn1": { + "version": "0.2.4", + "bundled": true, + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "bundled": true, + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "bundled": true, + "dev": true + }, + "aws4": { + "version": "1.8.0", + "bundled": true, + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bin-links": { + "version": "1.1.8", + "bundled": true, + "dev": true, + "requires": { + "bluebird": "^3.5.3", + "cmd-shim": "^3.0.0", + "gentle-fs": "^2.3.0", + "graceful-fs": "^4.1.15", + "npm-normalize-package-bin": "^1.0.0", + "write-file-atomic": "^2.3.0" + } + }, + "bluebird": { + "version": "3.5.5", + "bundled": true, + "dev": true + }, + "boxen": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "builtins": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "byline": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "byte-size": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "cacache": { + "version": "12.0.3", + "bundled": true, + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "call-limit": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "capture-stack-trace": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "caseless": { + "version": "0.12.0", + "bundled": true, + "dev": true + }, + "chalk": { + "version": "2.4.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chownr": { + "version": "1.1.4", + "bundled": true, + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "cidr-regex": { + "version": "2.0.10", + "bundled": true, + "dev": true, + "requires": { + "ip-regex": "^2.1.0" + } + }, + "cli-boxes": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "cli-columns": { + "version": "3.1.2", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.0.0", + "strip-ansi": "^3.0.1" + } + }, + "cli-table3": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + } + }, + "cliui": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "clone": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "cmd-shim": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "mkdirp": "~0.5.0" + } + }, + "co": { + "version": "4.6.0", + "bundled": true, + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "color-convert": { + "version": "1.9.1", + "bundled": true, + "dev": true, + "requires": { + "color-name": "^1.1.1" + } + }, + "color-name": { + "version": "1.1.3", + "bundled": true, + "dev": true + }, + "colors": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true + }, + "columnify": { + "version": "1.5.4", + "bundled": true, + "dev": true, + "requires": { + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + } + }, + "combined-stream": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "bundled": true, + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "config-chain": { + "version": "1.1.12", + "bundled": true, + "dev": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "configstore": { + "version": "3.1.5", + "bundled": true, + "dev": true, + "requires": { + "dot-prop": "^4.2.1", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + }, + "dependencies": { + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "iferr": { + "version": "0.1.5", + "bundled": true, + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "create-error-class": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, + "cross-spawn": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + } + } + }, + "crypto-random-string": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "cyclist": { + "version": "0.2.2", + "bundled": true, + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "bundled": true, + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true + } + } + }, + "debuglog": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "bundled": true, + "dev": true + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true + }, + "defaults": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "define-properties": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "delayed-stream": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "detect-indent": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "detect-newline": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "dezalgo": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "dot-prop": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "dotenv": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "duplexer3": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "duplexify": { + "version": "3.6.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "editor": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "bundled": true, + "dev": true + }, + "encoding": { + "version": "0.1.12", + "bundled": true, + "dev": true, + "requires": { + "iconv-lite": "~0.4.13" + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "env-paths": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "err-code": { + "version": "1.1.2", + "bundled": true, + "dev": true + }, + "errno": { + "version": "0.1.7", + "bundled": true, + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "es-abstract": { + "version": "1.12.0", + "bundled": true, + "dev": true, + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-promise": { + "version": "4.2.8", + "bundled": true, + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "es6-promise": "^4.0.3" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "execa": { + "version": "0.7.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "bundled": true, + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "extsprintf": { + "version": "1.3.0", + "bundled": true, + "dev": true + }, + "fast-deep-equal": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "figgy-pudding": { + "version": "3.5.1", + "bundled": true, + "dev": true + }, + "find-npm-prefix": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "flush-write-stream": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.4" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true, + "dev": true + }, + "form-data": { + "version": "2.3.2", + "bundled": true, + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "1.0.6", + "mime-types": "^2.1.12" + } + }, + "from2": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^2.6.0" + }, + "dependencies": { + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } + } + }, + "fs-vacuum": { + "version": "1.2.10", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "path-is-inside": "^1.0.1", + "rimraf": "^2.5.2" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + }, + "dependencies": { + "iferr": { + "version": "0.1.5", + "bundled": true, + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "genfun": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "gentle-fs": { + "version": "2.3.1", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.1.2", + "chownr": "^1.1.2", + "cmd-shim": "^3.0.3", + "fs-vacuum": "^1.2.10", + "graceful-fs": "^4.1.11", + "iferr": "^0.1.5", + "infer-owner": "^1.0.4", + "mkdirp": "^0.5.1", + "path-is-inside": "^1.0.2", + "read-cmd-shim": "^1.0.1", + "slide": "^1.1.6" + }, + "dependencies": { + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "iferr": { + "version": "0.1.5", + "bundled": true, + "dev": true + } + } + }, + "get-caller-file": { + "version": "2.0.5", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "getpass": { + "version": "0.1.7", + "bundled": true, + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "global-dirs": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "got": { + "version": "6.7.1", + "bundled": true, + "dev": true, + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "bundled": true, + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.2.4", + "bundled": true, + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "har-validator": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "ajv": "^5.3.0", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "hosted-git-info": { + "version": "2.8.8", + "bundled": true, + "dev": true + }, + "http-cache-semantics": { + "version": "3.8.1", + "bundled": true, + "dev": true + }, + "http-proxy-agent": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "4", + "debug": "3.1.0" + } + }, + "http-signature": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-proxy-agent": { + "version": "2.2.4", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + } + }, + "humanize-ms": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "requires": { + "ms": "^2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.23", + "bundled": true, + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "iferr": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "import-lazy": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true + }, + "init-package-json": { + "version": "1.10.3", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.1", + "npm-package-arg": "^4.0.0 || ^5.0.0 || ^6.0.0", + "promzard": "^0.3.0", + "read": "~1.0.1", + "read-package-json": "1 || 2", + "semver": "2.x || 3.x || 4 || 5", + "validate-npm-package-license": "^3.0.1", + "validate-npm-package-name": "^3.0.0" + } + }, + "ip": { + "version": "1.1.5", + "bundled": true, + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "bundled": true, + "dev": true + }, + "is-ci": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "requires": { + "ci-info": "^1.5.0" + }, + "dependencies": { + "ci-info": { + "version": "1.6.0", + "bundled": true, + "dev": true + } + } + }, + "is-cidr": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "cidr-regex": "^2.0.10" + } + }, + "is-date-object": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "bundled": true, + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-npm": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-obj": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "is-path-inside": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-redirect": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-retry-allowed": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "is-symbol": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true, + "dev": true + }, + "jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "bundled": true, + "dev": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "bundled": true, + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "bundled": true, + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "latest-version": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "package-json": "^4.0.0" + } + }, + "lazy-property": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "libcipm": { + "version": "4.0.8", + "bundled": true, + "dev": true, + "requires": { + "bin-links": "^1.1.2", + "bluebird": "^3.5.1", + "figgy-pudding": "^3.5.1", + "find-npm-prefix": "^1.0.2", + "graceful-fs": "^4.1.11", + "ini": "^1.3.5", + "lock-verify": "^2.1.0", + "mkdirp": "^0.5.1", + "npm-lifecycle": "^3.0.0", + "npm-logical-tree": "^1.2.1", + "npm-package-arg": "^6.1.0", + "pacote": "^9.1.0", + "read-package-json": "^2.0.13", + "rimraf": "^2.6.2", + "worker-farm": "^1.6.0" + } + }, + "libnpm": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "bin-links": "^1.1.2", + "bluebird": "^3.5.3", + "find-npm-prefix": "^1.0.2", + "libnpmaccess": "^3.0.2", + "libnpmconfig": "^1.2.1", + "libnpmhook": "^5.0.3", + "libnpmorg": "^1.0.1", + "libnpmpublish": "^1.1.2", + "libnpmsearch": "^2.0.2", + "libnpmteam": "^1.0.2", + "lock-verify": "^2.0.2", + "npm-lifecycle": "^3.0.0", + "npm-logical-tree": "^1.2.1", + "npm-package-arg": "^6.1.0", + "npm-profile": "^4.0.2", + "npm-registry-fetch": "^4.0.0", + "npmlog": "^4.1.2", + "pacote": "^9.5.3", + "read-package-json": "^2.0.13", + "stringify-package": "^1.0.0" + } + }, + "libnpmaccess": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "get-stream": "^4.0.0", + "npm-package-arg": "^6.1.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "libnpmconfig": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "find-up": "^3.0.0", + "ini": "^1.3.5" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "bundled": true, + "dev": true + } + } + }, + "libnpmhook": { + "version": "5.0.3", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.4.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "libnpmorg": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.4.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "libnpmpublish": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.5.1", + "get-stream": "^4.0.0", + "lodash.clonedeep": "^4.5.0", + "normalize-package-data": "^2.4.0", + "npm-package-arg": "^6.1.0", + "npm-registry-fetch": "^4.0.0", + "semver": "^5.5.1", + "ssri": "^6.0.1" + } + }, + "libnpmsearch": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "libnpmteam": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.4.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "libnpx": { + "version": "10.2.4", + "bundled": true, + "dev": true, + "requires": { + "dotenv": "^5.0.1", + "npm-package-arg": "^6.0.0", + "rimraf": "^2.6.2", + "safe-buffer": "^5.1.0", + "update-notifier": "^2.3.0", + "which": "^1.3.0", + "y18n": "^4.0.0", + "yargs": "^14.2.3" + } + }, + "lock-verify": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "npm-package-arg": "^6.1.0", + "semver": "^5.4.1" + } + }, + "lockfile": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "requires": { + "signal-exit": "^3.0.2" + } + }, + "lodash._baseindexof": { + "version": "3.1.0", + "bundled": true, + "dev": true + }, + "lodash._baseuniq": { + "version": "4.6.0", + "bundled": true, + "dev": true, + "requires": { + "lodash._createset": "~4.0.0", + "lodash._root": "~3.0.0" + } + }, + "lodash._bindcallback": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "lodash._cacheindexof": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "lodash._createcache": { + "version": "3.1.2", + "bundled": true, + "dev": true, + "requires": { + "lodash._getnative": "^3.0.0" + } + }, + "lodash._createset": { + "version": "4.0.3", + "bundled": true, + "dev": true + }, + "lodash._getnative": { + "version": "3.9.1", + "bundled": true, + "dev": true + }, + "lodash._root": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "bundled": true, + "dev": true + }, + "lodash.restparam": { + "version": "3.6.1", + "bundled": true, + "dev": true + }, + "lodash.union": { + "version": "4.6.0", + "bundled": true, + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "bundled": true, + "dev": true + }, + "lodash.without": { + "version": "4.4.0", + "bundled": true, + "dev": true + }, + "lowercase-keys": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "bundled": true, + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "make-fetch-happen": { + "version": "5.0.2", + "bundled": true, + "dev": true, + "requires": { + "agentkeepalive": "^3.4.1", + "cacache": "^12.0.0", + "http-cache-semantics": "^3.8.1", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "node-fetch-npm": "^2.0.2", + "promise-retry": "^1.1.1", + "socks-proxy-agent": "^4.0.0", + "ssri": "^6.0.0" + } + }, + "meant": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "mime-db": { + "version": "1.35.0", + "bundled": true, + "dev": true + }, + "mime-types": { + "version": "2.1.19", + "bundled": true, + "dev": true, + "requires": { + "mime-db": "~1.35.0" + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "bundled": true, + "dev": true + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^2.9.0" + }, + "dependencies": { + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } + } + }, + "mississippi": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "bundled": true, + "dev": true, + "requires": { + "minimist": "^1.2.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "bundled": true, + "dev": true + } + } + }, + "move-concurrently": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + }, + "dependencies": { + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "bundled": true, + "dev": true + }, + "node-fetch-npm": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "encoding": "^0.1.11", + "json-parse-better-errors": "^1.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node-gyp": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.2", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "npmlog": "^4.1.2", + "request": "^2.88.0", + "rimraf": "^2.6.3", + "semver": "^5.7.1", + "tar": "^4.4.12", + "which": "^1.3.1" + } + }, + "nopt": { + "version": "4.0.3", + "bundled": true, + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "bundled": true, + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "resolve": { + "version": "1.10.0", + "bundled": true, + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "npm-audit-report": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "requires": { + "cli-table3": "^0.5.0", + "console-control-strings": "^1.1.0" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-cache-filename": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "npm-install-checks": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "semver": "^2.3.0 || 3.x || 4 || 5" + } + }, + "npm-lifecycle": { + "version": "3.1.5", + "bundled": true, + "dev": true, + "requires": { + "byline": "^5.0.0", + "graceful-fs": "^4.1.15", + "node-gyp": "^5.0.2", + "resolve-from": "^4.0.0", + "slide": "^1.1.6", + "uid-number": "0.0.6", + "umask": "^1.1.0", + "which": "^1.3.1" + } + }, + "npm-logical-tree": { + "version": "1.2.1", + "bundled": true, + "dev": true + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "npm-package-arg": { + "version": "6.1.1", + "bundled": true, + "dev": true, + "requires": { + "hosted-git-info": "^2.7.1", + "osenv": "^0.1.5", + "semver": "^5.6.0", + "validate-npm-package-name": "^3.0.0" + } + }, + "npm-packlist": { + "version": "1.4.8", + "bundled": true, + "dev": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-pick-manifest": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "npm-package-arg": "^6.0.0", + "semver": "^5.4.1" + } + }, + "npm-profile": { + "version": "4.0.4", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.1.2 || 2", + "figgy-pudding": "^3.4.1", + "npm-registry-fetch": "^4.0.0" + } + }, + "npm-registry-fetch": { + "version": "4.0.7", + "bundled": true, + "dev": true, + "requires": { + "JSONStream": "^1.3.4", + "bluebird": "^3.5.1", + "figgy-pudding": "^3.4.1", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^5.0.0", + "npm-package-arg": "^6.1.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "bundled": true, + "dev": true + } + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "npm-user-validate": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "object-keys": { + "version": "1.0.12", + "bundled": true, + "dev": true + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opener": { + "version": "1.5.1", + "bundled": true, + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "package-json": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + } + }, + "pacote": { + "version": "9.5.12", + "bundled": true, + "dev": true, + "requires": { + "bluebird": "^3.5.3", + "cacache": "^12.0.2", + "chownr": "^1.1.2", + "figgy-pudding": "^3.5.1", + "get-stream": "^4.1.0", + "glob": "^7.1.3", + "infer-owner": "^1.0.4", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^5.0.0", + "minimatch": "^3.0.4", + "minipass": "^2.3.5", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "normalize-package-data": "^2.4.0", + "npm-normalize-package-bin": "^1.0.0", + "npm-package-arg": "^6.1.0", + "npm-packlist": "^1.1.12", + "npm-pick-manifest": "^3.0.0", + "npm-registry-fetch": "^4.0.0", + "osenv": "^0.1.5", + "promise-inflight": "^1.0.1", + "promise-retry": "^1.1.1", + "protoduck": "^5.0.1", + "rimraf": "^2.6.2", + "safe-buffer": "^5.1.2", + "semver": "^5.6.0", + "ssri": "^6.0.1", + "tar": "^4.4.10", + "unique-filename": "^1.1.1", + "which": "^1.3.1" + }, + "dependencies": { + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } + } + }, + "parallel-transform": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "cyclist": "~0.2.2", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "bundled": true, + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "pify": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "prepend-http": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "promise-retry": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "err-code": "^1.0.0", + "retry": "^0.10.0" + }, + "dependencies": { + "retry": { + "version": "0.10.1", + "bundled": true, + "dev": true + } + } + }, + "promzard": { + "version": "0.3.0", + "bundled": true, + "dev": true, + "requires": { + "read": "1" + } + }, + "proto-list": { + "version": "1.2.4", + "bundled": true, + "dev": true + }, + "protoduck": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "requires": { + "genfun": "^5.0.0" + } + }, + "prr": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "psl": { + "version": "1.1.29", + "bundled": true, + "dev": true + }, + "pump": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "bundled": true, + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "1.4.1", + "bundled": true, + "dev": true + }, + "qrcode-terminal": { + "version": "0.12.0", + "bundled": true, + "dev": true + }, + "qs": { + "version": "6.5.2", + "bundled": true, + "dev": true + }, + "query-string": { + "version": "6.8.2", + "bundled": true, + "dev": true, + "requires": { + "decode-uri-component": "^0.2.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + } + }, + "qw": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "read": { + "version": "1.0.7", + "bundled": true, + "dev": true, + "requires": { + "mute-stream": "~0.0.4" + } + }, + "read-cmd-shim": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2" + } + }, + "read-installed": { + "version": "4.0.3", + "bundled": true, + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "graceful-fs": "^4.1.2", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "slide": "~1.1.3", + "util-extend": "^1.0.1" + } + }, + "read-package-json": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "json-parse-better-errors": "^1.0.1", + "normalize-package-data": "^2.0.0", + "npm-normalize-package-bin": "^1.0.0" + } + }, + "read-package-tree": { + "version": "5.3.1", + "bundled": true, + "dev": true, + "requires": { + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "util-promisify": "^2.1.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "bundled": true, + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdir-scoped-modules": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "registry-auth-token": { + "version": "3.4.0", + "bundled": true, + "dev": true, + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "rc": "^1.0.1" + } + }, + "request": { + "version": "2.88.0", + "bundled": true, + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "retry": { + "version": "0.12.0", + "bundled": true, + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-queue": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.1.1" + }, + "dependencies": { + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true + } + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.7.1", + "bundled": true, + "dev": true + }, + "semver-diff": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "semver": "^5.0.3" + } + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "sha": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2" + } + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "slide": { + "version": "1.1.6", + "bundled": true, + "dev": true + }, + "smart-buffer": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "socks": { + "version": "2.3.3", + "bundled": true, + "dev": true, + "requires": { + "ip": "1.1.5", + "smart-buffer": "^4.1.0" + } + }, + "socks-proxy-agent": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "~4.2.1", + "socks": "~2.3.2" + }, + "dependencies": { + "agent-base": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + } + } + }, + "sorted-object": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "sorted-union-stream": { + "version": "2.1.3", + "bundled": true, + "dev": true, + "requires": { + "from2": "^1.3.0", + "stream-iterate": "^1.1.0" + }, + "dependencies": { + "from2": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "~1.1.10" + } + }, + "isarray": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "bundled": true, + "dev": true + } + } + }, + "spdx-correct": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "bundled": true, + "dev": true + }, + "split-on-first": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "sshpk": { + "version": "1.14.2", + "bundled": true, + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "ssri": { + "version": "6.0.1", + "bundled": true, + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "stream-each": { + "version": "1.2.2", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-iterate": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "readable-stream": "^2.1.5", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "stream-shift": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "strict-uri-encode": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string_decoder": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.0", + "bundled": true, + "dev": true + } + } + }, + "stringify-package": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "dev": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "dependencies": { + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } + } + }, + "term-size": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "^0.7.0" + } + }, + "text-table": { + "version": "0.2.0", + "bundled": true, + "dev": true + }, + "through": { + "version": "2.3.8", + "bundled": true, + "dev": true + }, + "through2": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "timed-out": { + "version": "4.0.1", + "bundled": true, + "dev": true + }, + "tiny-relative-date": { + "version": "1.3.0", + "bundled": true, + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "bundled": true, + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "bundled": true, + "dev": true, + "optional": true + }, + "typedarray": { + "version": "0.0.6", + "bundled": true, + "dev": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true, + "dev": true + }, + "umask": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "unique-filename": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unique-string": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + } + }, + "unpipe": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "unzip-response": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "update-notifier": { + "version": "2.5.0", + "bundled": true, + "dev": true, + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "url-parse-lax": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "util-extend": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "util-promisify": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "uuid": { + "version": "3.3.3", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "validate-npm-package-name": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtins": "^1.0.3" + } + }, + "verror": { + "version": "1.10.0", + "bundled": true, + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "wcwidth": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "which": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.2" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "widest-line": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.1.1" + } + }, + "worker-farm": { + "version": "1.7.0", + "bundled": true, + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "2.4.3", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "xtend": { + "version": "4.0.1", + "bundled": true, + "dev": true + }, + "y18n": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "14.2.3", + "bundled": true, + "dev": true, + "requires": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "15.0.1", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "bundled": true, + "dev": true + } + } + } + } + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, "openapi-sampler": { "version": "1.0.0-beta.15", "resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.0.0-beta.15.tgz", @@ -359,16 +5492,201 @@ "word-wrap": "~1.2.3" } }, + "p-each-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "dev": true + }, + "p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "requires": { + "p-map": "^2.0.0" + } + }, + "p-is-promise": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", + "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, + "p-reduce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", + "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", + "dev": true + }, + "p-retry": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.2.0.tgz", + "integrity": "sha512-jPH38/MRh263KKcq0wBNOGFJbm+U6784RilTmHjB/HM9kH9V8WlCpVUcdOmip9cjXOh6MxZ5yk1z2SjDUJfWmA==", + "dev": true, + "requires": { + "@types/retry": "^0.12.0", + "retry": "^0.12.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, "pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, "pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", @@ -384,6 +5702,28 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true + }, "quicktype-core": { "version": "6.0.66", "resolved": "https://registry.npmjs.org/quicktype-core/-/quicktype-core-6.0.66.tgz", @@ -419,6 +5759,81 @@ } } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, "readable-stream": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.0.tgz", @@ -448,6 +5863,46 @@ } } }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs=", + "dev": true, + "requires": { + "esprima": "~4.0.0" + } + }, + "registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -456,6 +5911,39 @@ "path-parse": "^1.0.6" } }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", + "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", + "dev": true + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -466,16 +5954,191 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "semantic-release": { + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-17.2.3.tgz", + "integrity": "sha512-MY1MlowGQrkOR7+leOD8ICkVOC6i1szbwDODdbJ0UdshtMx8Ms0bhpRQmEEliqYKEb5PLv/dqs6zKKuHT7UxTg==", + "dev": true, + "requires": { + "@semantic-release/commit-analyzer": "^8.0.0", + "@semantic-release/error": "^2.2.0", + "@semantic-release/github": "^7.0.0", + "@semantic-release/npm": "^7.0.0", + "@semantic-release/release-notes-generator": "^9.0.0", + "aggregate-error": "^3.0.0", + "cosmiconfig": "^6.0.0", + "debug": "^4.0.0", + "env-ci": "^5.0.0", + "execa": "^4.0.0", + "figures": "^3.0.0", + "find-versions": "^3.0.0", + "get-stream": "^5.0.0", + "git-log-parser": "^1.2.0", + "hook-std": "^2.0.0", + "hosted-git-info": "^3.0.0", + "lodash": "^4.17.15", + "marked": "^1.0.0", + "marked-terminal": "^4.0.0", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "p-reduce": "^2.0.0", + "read-pkg-up": "^7.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.3.2", + "semver-diff": "^3.1.1", + "signale": "^1.2.1", + "yargs": "^15.0.1" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "semver-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", + "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, "shallow-copy": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz", "integrity": "sha1-QV9CcC1z2BAzApLMXuhurhoRoXA=" }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "signale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz", + "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==", + "dev": true, + "requires": { + "chalk": "^2.3.2", + "figures": "^2.0.0", + "pkg-conf": "^2.1.0" + }, + "dependencies": { + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + } + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "spawn-error-forwarder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", + "integrity": "sha1-Gv2Uc46ZmwNG17n8NzvlXgdXcCk=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz", + "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==", + "dev": true + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "requires": { + "through": "2" + } + }, + "split2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", + "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", + "dev": true, + "requires": { + "through2": "^2.0.2" + } }, "sprintf-js": { "version": "1.0.3", @@ -546,6 +6209,27 @@ } } }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -554,6 +6238,42 @@ "safe-buffer": "~5.1.0" } }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, "strip-outer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", @@ -562,6 +6282,87 @@ "escape-string-regexp": "^1.0.2" } }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "dev": true + }, + "tempy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-1.0.0.tgz", + "integrity": "sha512-eLXG5B1G0mRPHmgH2WydPl5v4jH35qEn3y/rA/aahKhIa91Pn119SsU7n7v/433gtT9ONzC8ISvNHIh2JSTm0w==", + "dev": true, + "requires": { + "del": "^6.0.0", + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "dependencies": { + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "dev": true + } + } + }, + "text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", @@ -592,6 +6393,33 @@ "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==" }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "traverse": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", + "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", + "dev": true + }, + "trim-newlines": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", + "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", + "dev": true + }, + "trim-off-newlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "dev": true + }, "trim-repeated": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", @@ -608,6 +6436,12 @@ "prelude-ls": "~1.1.2" } }, + "type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -618,6 +6452,13 @@ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" }, + "uglify-js": { + "version": "3.11.6", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.11.6.tgz", + "integrity": "sha512-oASI1FOJ7BBFkSCNDZ446EgkSuHkOZBuqRFrwXIKWCoXw8ZXQETooTQjkAcBS03Acab7ubCKsXnwuV2svy061g==", + "dev": true, + "optional": true + }, "unicode-trie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-0.3.1.tgz", @@ -634,16 +6475,53 @@ } } }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", + "dev": true + }, + "universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "dev": true + }, "urijs": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.2.tgz", "integrity": "sha512-s/UIq9ap4JPZ7H1EB5ULo/aOUbWqfDi7FKzMC2Nz+0Si8GiT1rIEaprt8hy3Vy2Ex2aJPpOQv4P4DuOZ+K1c6w==" }, + "url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "vlq": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", @@ -654,6 +6532,21 @@ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.2.0.tgz", "integrity": "sha512-SdGPoQMMnzVYThUbSrEvqTlkvC1Ux27NehaJ/GUHBfNrh5Mjg+1/uRyFMwVnxO2MrikMWvWAqUGgQOfVU4hT7w==" }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -664,15 +6557,107 @@ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "yaml": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==" + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "dependencies": { + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true } } } diff --git a/package.json b/package.json index 7d93e9f50..974888ee4 100644 --- a/package.json +++ b/package.json @@ -10,16 +10,16 @@ "template" ], "repository": { - "type": "git", - "url": "git+https://github.com/asyncapi/ts-nats-template.git" + "type": "git", + "url": "git+https://github.com/asyncapi/ts-nats-template.git" }, "bugs": { - "url": "https://github.com/asyncapi/ts-nats-template/issues" + "url": "https://github.com/asyncapi/ts-nats-template/issues" }, "homepage": "https://github.com/asyncapi/ts-nats-template#readme", "author": "Jonas Lagoni (jonas-lt@live.dk)", "license": "Apache-2.0", - "scripts": { + "scripts": { "generate:examples": "npm run generate:examples:pubSub && npm run generate:examples:requestReply", "generate:examples:pubSub": "cd \"examples/publish subscribe\" && sh generate.sh", "generate:examples:requestReply": "cd \"examples/request reply\" && sh generate.sh", @@ -29,43 +29,43 @@ "get-version": "echo $npm_package_version" }, "dependencies": { - "filenamify": "^4.1.0", - "lodash": "^4.17.15", "@asyncapi/generator-filters": "^1.0.0", - "quicktype-core": "6.0.66", - "is-url": "1.2.4" + "filenamify": "^4.1.0", + "is-url": "1.2.4", + "lodash": "^4.17.20", + "quicktype-core": "6.0.66" }, "publishConfig": { - "access": "public" + "access": "public" }, "devDependencies": { - "@semantic-release/commit-analyzer": "^8.0.1", - "@semantic-release/github": "^7.0.4", - "@semantic-release/npm": "^7.0.3", - "@semantic-release/release-notes-generator": "^9.0.1", - "conventional-changelog-conventionalcommits": "^4.2.3", - "semantic-release": "^17.0.4" + "@semantic-release/commit-analyzer": "^8.0.1", + "@semantic-release/github": "^7.0.4", + "@semantic-release/npm": "^7.0.3", + "@semantic-release/release-notes-generator": "^9.0.1", + "conventional-changelog-conventionalcommits": "^4.2.3", + "semantic-release": "^17.0.4" }, "release": { - "branches": [ - "master" - ], - "plugins": [ - [ - "@semantic-release/commit-analyzer", - { - "preset": "conventionalcommits" - } + "branches": [ + "master" ], - [ - "@semantic-release/release-notes-generator", - { - "preset": "conventionalcommits" - } - ], - "@semantic-release/npm", - "@semantic-release/github" - ] + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits" + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits" + } + ], + "@semantic-release/npm", + "@semantic-release/github" + ] }, "generator": { "supportedProtocols": [ @@ -83,7 +83,7 @@ "required": false } }, - "generator": ">=1.0.0-rc.11", + "generator": ">=2.0.0", "filters": [ "@asyncapi/generator-filters" ] From 1fb8d71d1469e8848f1f0e4803d7604b76760b0d Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Fri, 20 Nov 2020 11:51:35 +0100 Subject: [PATCH 107/110] Added tests and fixed small bugs --- .../pull-request-integration-testing.yml | 31 + .github/workflows/pull-request-testing.yml | 1 + examples/GenerateAndTest.sh | 12 + .../{generate.sh => GenerateAndBuild.sh} | 0 examples/publish subscribe/Test.sh | 3 + .../streetlight/package-lock.json | 897 ++++++++++++++++++ .../streetlight/package.json | 9 +- .../streetlight/src/index.ts | 9 +- ...eetlightStreetlightIdCommandTurnon.spec.ts | 75 ++ ...treetlightStreetlightIdEventTurnon.spec.ts | 76 ++ .../streetlight/src/tests/testclient/index.ts | 9 +- .../{generate.sh => GenerateAndBuild.sh} | 0 examples/request reply/Test.sh | 3 + .../streetlight/package-lock.json | 897 ++++++++++++++++++ .../request reply/streetlight/package.json | 9 +- .../request reply/streetlight/src/index.ts | 9 +- ...eetlightStreetlightIdCommandTurnon.spec.ts | 77 ++ ...treetlightStreetlightIdEventTurnon.spec.ts | 78 ++ .../streetlight/src/tests/testclient/index.ts | 9 +- filters/all.js | 20 +- package-lock.json | 20 +- package.json | 10 +- partials/index/Standard.njk | 9 +- partials/tests/integration/Publish.njk | 44 + partials/tests/integration/Reply.njk | 42 + partials/tests/integration/Request.njk | 43 + partials/tests/integration/Subscribe.njk | 43 + template/package.json.njk | 9 +- template/src/tests/$$channel$$.spec.ts.njk | 58 ++ 29 files changed, 2458 insertions(+), 44 deletions(-) create mode 100644 .github/workflows/pull-request-integration-testing.yml create mode 100755 examples/GenerateAndTest.sh rename examples/publish subscribe/{generate.sh => GenerateAndBuild.sh} (100%) mode change 100644 => 100755 create mode 100755 examples/publish subscribe/Test.sh create mode 100644 examples/publish subscribe/streetlight/src/tests/StreetlightStreetlightIdCommandTurnon.spec.ts create mode 100644 examples/publish subscribe/streetlight/src/tests/StreetlightStreetlightIdEventTurnon.spec.ts rename examples/request reply/{generate.sh => GenerateAndBuild.sh} (100%) mode change 100644 => 100755 create mode 100755 examples/request reply/Test.sh create mode 100644 examples/request reply/streetlight/src/tests/StreetlightStreetlightIdCommandTurnon.spec.ts create mode 100644 examples/request reply/streetlight/src/tests/StreetlightStreetlightIdEventTurnon.spec.ts create mode 100644 partials/tests/integration/Publish.njk create mode 100644 partials/tests/integration/Reply.njk create mode 100644 partials/tests/integration/Request.njk create mode 100644 partials/tests/integration/Subscribe.njk create mode 100644 template/src/tests/$$channel$$.spec.ts.njk diff --git a/.github/workflows/pull-request-integration-testing.yml b/.github/workflows/pull-request-integration-testing.yml new file mode 100644 index 000000000..51e975ae2 --- /dev/null +++ b/.github/workflows/pull-request-integration-testing.yml @@ -0,0 +1,31 @@ +name: Pull request integration testing + +on: + pull_request, synchronize + +jobs: + test: + if: github.event.pull_request.draft == false + name: 'Run linter and tests' + runs-on: ubuntu-latest + services: + nats: + image: nats + ports: + - 4222 + restart: unless-stopped + steps: + - name: Checkout repo + uses: actions/checkout@v2 + - name: Setup Node.js + uses: actions/setup-node@v1 + with: + node-version: 13 + - name: Install dependencies + run: npm ci + - name: Generate and build examples + run: npm run test:examples:integration + env: + NATS_HOST: nats + NATS_PORT: ${{ job.services.redis.ports['6379'] }} + \ No newline at end of file diff --git a/.github/workflows/pull-request-testing.yml b/.github/workflows/pull-request-testing.yml index 7ea188087..fd0eadc95 100644 --- a/.github/workflows/pull-request-testing.yml +++ b/.github/workflows/pull-request-testing.yml @@ -20,3 +20,4 @@ jobs: run: npm run lint - name: Run tests run: npm test + \ No newline at end of file diff --git a/examples/GenerateAndTest.sh b/examples/GenerateAndTest.sh new file mode 100755 index 000000000..808091fc9 --- /dev/null +++ b/examples/GenerateAndTest.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -x + +cd ./publish\ subscribe +sh ./GenerateAndBuild.sh +sh ./Test.sh + +cd ../../request\ reply +sh ./GenerateAndBuild.sh +sh ./Test.sh + +cd ../../ \ No newline at end of file diff --git a/examples/publish subscribe/generate.sh b/examples/publish subscribe/GenerateAndBuild.sh old mode 100644 new mode 100755 similarity index 100% rename from examples/publish subscribe/generate.sh rename to examples/publish subscribe/GenerateAndBuild.sh diff --git a/examples/publish subscribe/Test.sh b/examples/publish subscribe/Test.sh new file mode 100755 index 000000000..3bcad8e5f --- /dev/null +++ b/examples/publish subscribe/Test.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +cd ./streetlight && npm run test:integration \ No newline at end of file diff --git a/examples/publish subscribe/streetlight/package-lock.json b/examples/publish subscribe/streetlight/package-lock.json index 54a9a1391..612ff2124 100644 --- a/examples/publish subscribe/streetlight/package-lock.json +++ b/examples/publish subscribe/streetlight/package-lock.json @@ -4,6 +4,12 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/chai": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.14.tgz", + "integrity": "sha512-G+ITQPXkwTrslfG5L/BksmbLUA0M1iybEsmCWPqzSxsRRhJZimBKJkoMi8fr/CPygPTj4zO5pJH7I2/cm9M7SQ==", + "dev": true + }, "@types/klaw-sync": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@types/klaw-sync/-/klaw-sync-6.0.0.tgz", @@ -12,34 +18,640 @@ "@types/node": "*" } }, + "@types/mocha": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.0.4.tgz", + "integrity": "sha512-M4BwiTJjHmLq6kjON7ZoI2JMlBvpY3BYSdiP6s/qCT3jb1s9/DeJF0JELpAxiVSIxXDzfNKe+r7yedMIoLbknQ==", + "dev": true + }, "@types/node": { "version": "13.9.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.5.tgz", "integrity": "sha512-hkzMMD3xu6BrJpGVLeQ3htQQNAcOrJjX7WFmtK8zWQpz2UJf13LCFF2ALA7c9OVdvc2vQJeDdjfR35M0sBCxvw==" }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chokidar": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mocha": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", + "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.4.3", + "debug": "4.2.0", + "diff": "4.0.2", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.14.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.2", + "nanoid": "3.1.12", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "7.2.0", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.0.2", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "2.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "nanoid": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", + "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, "nuid": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/nuid/-/nuid-1.1.4.tgz", "integrity": "sha512-PXiYyHhGfrq8H4g5HyC8enO1lz6SBe5z6x1yx/JG4tmADzDGJVQy3l1sRf3VtEvPsN8dGn9hRFRwDKWL62x0BA==" }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -56,6 +668,55 @@ "source-map": "^0.6.0" } }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "ts-nats": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/ts-nats/-/ts-nats-1.2.4.tgz", @@ -99,11 +760,247 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, "typescript": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.3.tgz", "integrity": "sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ==" }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "workerpool": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", + "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + } + } + }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/examples/publish subscribe/streetlight/package.json b/examples/publish subscribe/streetlight/package.json index 439f829c4..776edc8e7 100644 --- a/examples/publish subscribe/streetlight/package.json +++ b/examples/publish subscribe/streetlight/package.json @@ -6,7 +6,8 @@ "types": "dist/index.d.ts", "scripts": { "watch": "tsc --watch", - "build": "tsc" + "build": "tsc", + "test:integration": "./node_modules/.bin/mocha -r ts-node/register src/tests/**/*.spec.ts" }, "dependencies": { "@types/klaw-sync": "^6.0.0", @@ -16,6 +17,10 @@ "ts-nkeys": "1.0.16" }, "devDependencies": { - "ts-node": "^8.8.1" + "ts-node": "^8.10.2", + "@types/mocha": "^8.0.4", + "@types/chai": "^4.2.14", + "chai": "^4.2.0", + "mocha": "^8.2.1" } } diff --git a/examples/publish subscribe/streetlight/src/index.ts b/examples/publish subscribe/streetlight/src/index.ts index e8b683078..81d72ffbd 100644 --- a/examples/publish subscribe/streetlight/src/index.ts +++ b/examples/publish subscribe/streetlight/src/index.ts @@ -69,10 +69,10 @@ export declare interface NatsAsyncApiClient { export class NatsAsyncApiClient extends events.EventEmitter{ - public jsonClient?: Client; - public stringClient?: Client; - public binaryClient?: Client; - public options?: NatsConnectionOptions; + private jsonClient?: Client; + private stringClient?: Client; + private binaryClient?: Client; + private options?: NatsConnectionOptions; /** * @@ -107,6 +107,7 @@ export class NatsAsyncApiClient extends events.EventEmitter{ if (!this.jsonClient || this.jsonClient!.isClosed()){ return true; } + return false; } /** diff --git a/examples/publish subscribe/streetlight/src/tests/StreetlightStreetlightIdCommandTurnon.spec.ts b/examples/publish subscribe/streetlight/src/tests/StreetlightStreetlightIdCommandTurnon.spec.ts new file mode 100644 index 000000000..56ca949de --- /dev/null +++ b/examples/publish subscribe/streetlight/src/tests/StreetlightStreetlightIdCommandTurnon.spec.ts @@ -0,0 +1,75 @@ + + +import {describe, it} from 'mocha'; +import {expect} from 'chai'; +import * as Client from '../index' +import * as TestClient from './testclient/index' +import { NatsTypescriptTemplateError } from '../NatsTypescriptTemplateError'; + +describe('streetlight/{streetlight_id}/command/turnon can talk to it self', () => { + var client: Client.NatsAsyncApiClient; + var testClient: TestClient.NatsAsyncApiTestClient; + before(async () => { + client = new Client.NatsAsyncApiClient(); + testClient = new TestClient.NatsAsyncApiTestClient(); + const natsHost = process.env.NATS_HOST || "0.0.0.0" + const natsPort = process.env.NATS_PORT || "4222" + const natsUrl = `${natsHost}:${natsPort}` + await client.connectToHost(natsUrl); + await testClient.connectToHost(natsUrl); + }); + + it('Clients can connect', () => { + expect(client.isClosed()).to.be.false; + expect(testClient.isClosed()).to.be.false; + }); + + it('can send message', async () => { + + +var receivedError: NatsTypescriptTemplateError | undefined = undefined; +var receivedMsg: Client.TurnonCommandMessage.TurnonCommand | undefined = undefined; +var recievedStreetlightId : string | undefined = undefined + + +var publishMessage: Client.TurnonCommandMessage.TurnonCommand = { + "lumen": 0 +}; +var StreetlightIdToSend: string = "string" + + +const tryAndWaitForResponse = new Promise(resolve => { + setTimeout(resolve, 100); +}); + +const replySubscription = await client.subscribeToStreetlightStreetlightIdCommandTurnon((err, msg + + ,streetlight_id + ) => { + receivedError = err; + receivedMsg = msg; + recievedStreetlightId = streetlight_id + + } + , StreetlightIdToSend + +); +await testClient.publishToStreetlightStreetlightIdCommandTurnon(publishMessage + , StreetlightIdToSend + ); +await tryAndWaitForResponse; +expect(receivedError).to.be.undefined; +expect(receivedMsg).to.be.deep.equal(publishMessage); +expect(recievedStreetlightId).to.be.equal(StreetlightIdToSend); + + + }); + + it('Can shutdown', async () => { + await client.disconnect() + await testClient.disconnect() + expect(client.isClosed()).to.be.true; + expect(testClient.isClosed()).to.be.true; + }); + +}); \ No newline at end of file diff --git a/examples/publish subscribe/streetlight/src/tests/StreetlightStreetlightIdEventTurnon.spec.ts b/examples/publish subscribe/streetlight/src/tests/StreetlightStreetlightIdEventTurnon.spec.ts new file mode 100644 index 000000000..2b21deb4b --- /dev/null +++ b/examples/publish subscribe/streetlight/src/tests/StreetlightStreetlightIdEventTurnon.spec.ts @@ -0,0 +1,76 @@ + + +import {describe, it} from 'mocha'; +import {expect} from 'chai'; +import * as Client from '../index' +import * as TestClient from './testclient/index' +import { NatsTypescriptTemplateError } from '../NatsTypescriptTemplateError'; + +describe('streetlight/{streetlight_id}/event/turnon can talk to it self', () => { + var client: Client.NatsAsyncApiClient; + var testClient: TestClient.NatsAsyncApiTestClient; + before(async () => { + client = new Client.NatsAsyncApiClient(); + testClient = new TestClient.NatsAsyncApiTestClient(); + const natsHost = process.env.NATS_HOST || "0.0.0.0" + const natsPort = process.env.NATS_PORT || "4222" + const natsUrl = `${natsHost}:${natsPort}` + await client.connectToHost(natsUrl); + await testClient.connectToHost(natsUrl); + }); + + it('Clients can connect', () => { + expect(client.isClosed()).to.be.false; + expect(testClient.isClosed()).to.be.false; + }); + + it('can send message', async () => { + + +var receivedError: NatsTypescriptTemplateError | undefined = undefined; +var receivedMsg: TestClient.AnonymousMessage2Message.AnonymousMessage2 | undefined = undefined; +var recievedStreetlightId : string | undefined = undefined + + +var publishMessage: TestClient.AnonymousMessage2Message.AnonymousMessage2 = { + "lumen": 0 +}; +var StreetlightIdToSend: string = "string" + + +const tryAndWaitForResponse = new Promise(resolve => { + setTimeout(resolve, 100); +}); + + +const replySubscription = await testClient.subscribeToStreetlightStreetlightIdEventTurnon((err, msg + + ,streetlight_id + ) => { + receivedError = err; + receivedMsg = msg; + recievedStreetlightId = streetlight_id + + } + , StreetlightIdToSend + +); +await client.publishToStreetlightStreetlightIdEventTurnon(publishMessage + , StreetlightIdToSend + ); +await tryAndWaitForResponse; +expect(receivedError).to.be.undefined; +expect(receivedMsg).to.be.deep.equal(publishMessage); +expect(recievedStreetlightId).to.be.equal(StreetlightIdToSend); + + + }); + + it('Can shutdown', async () => { + await client.disconnect() + await testClient.disconnect() + expect(client.isClosed()).to.be.true; + expect(testClient.isClosed()).to.be.true; + }); + +}); \ No newline at end of file diff --git a/examples/publish subscribe/streetlight/src/tests/testclient/index.ts b/examples/publish subscribe/streetlight/src/tests/testclient/index.ts index d27935ddf..127735208 100644 --- a/examples/publish subscribe/streetlight/src/tests/testclient/index.ts +++ b/examples/publish subscribe/streetlight/src/tests/testclient/index.ts @@ -61,10 +61,10 @@ export declare interface NatsAsyncApiTestClient { export class NatsAsyncApiTestClient extends events.EventEmitter{ - public jsonClient?: Client; - public stringClient?: Client; - public binaryClient?: Client; - public options?: NatsConnectionOptions; + private jsonClient?: Client; + private stringClient?: Client; + private binaryClient?: Client; + private options?: NatsConnectionOptions; /** * @@ -99,6 +99,7 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ if (!this.jsonClient || this.jsonClient!.isClosed()){ return true; } + return false; } /** diff --git a/examples/request reply/generate.sh b/examples/request reply/GenerateAndBuild.sh old mode 100644 new mode 100755 similarity index 100% rename from examples/request reply/generate.sh rename to examples/request reply/GenerateAndBuild.sh diff --git a/examples/request reply/Test.sh b/examples/request reply/Test.sh new file mode 100755 index 000000000..3bcad8e5f --- /dev/null +++ b/examples/request reply/Test.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +cd ./streetlight && npm run test:integration \ No newline at end of file diff --git a/examples/request reply/streetlight/package-lock.json b/examples/request reply/streetlight/package-lock.json index 54a9a1391..612ff2124 100644 --- a/examples/request reply/streetlight/package-lock.json +++ b/examples/request reply/streetlight/package-lock.json @@ -4,6 +4,12 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/chai": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.14.tgz", + "integrity": "sha512-G+ITQPXkwTrslfG5L/BksmbLUA0M1iybEsmCWPqzSxsRRhJZimBKJkoMi8fr/CPygPTj4zO5pJH7I2/cm9M7SQ==", + "dev": true + }, "@types/klaw-sync": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@types/klaw-sync/-/klaw-sync-6.0.0.tgz", @@ -12,34 +18,640 @@ "@types/node": "*" } }, + "@types/mocha": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.0.4.tgz", + "integrity": "sha512-M4BwiTJjHmLq6kjON7ZoI2JMlBvpY3BYSdiP6s/qCT3jb1s9/DeJF0JELpAxiVSIxXDzfNKe+r7yedMIoLbknQ==", + "dev": true + }, "@types/node": { "version": "13.9.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.5.tgz", "integrity": "sha512-hkzMMD3xu6BrJpGVLeQ3htQQNAcOrJjX7WFmtK8zWQpz2UJf13LCFF2ALA7c9OVdvc2vQJeDdjfR35M0sBCxvw==" }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chokidar": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mocha": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", + "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.4.3", + "debug": "4.2.0", + "diff": "4.0.2", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.14.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.2", + "nanoid": "3.1.12", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "7.2.0", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.0.2", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "2.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "nanoid": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", + "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, "nuid": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/nuid/-/nuid-1.1.4.tgz", "integrity": "sha512-PXiYyHhGfrq8H4g5HyC8enO1lz6SBe5z6x1yx/JG4tmADzDGJVQy3l1sRf3VtEvPsN8dGn9hRFRwDKWL62x0BA==" }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -56,6 +668,55 @@ "source-map": "^0.6.0" } }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "ts-nats": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/ts-nats/-/ts-nats-1.2.4.tgz", @@ -99,11 +760,247 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, "typescript": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.3.tgz", "integrity": "sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ==" }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "workerpool": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", + "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + } + } + }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/examples/request reply/streetlight/package.json b/examples/request reply/streetlight/package.json index 439f829c4..776edc8e7 100644 --- a/examples/request reply/streetlight/package.json +++ b/examples/request reply/streetlight/package.json @@ -6,7 +6,8 @@ "types": "dist/index.d.ts", "scripts": { "watch": "tsc --watch", - "build": "tsc" + "build": "tsc", + "test:integration": "./node_modules/.bin/mocha -r ts-node/register src/tests/**/*.spec.ts" }, "dependencies": { "@types/klaw-sync": "^6.0.0", @@ -16,6 +17,10 @@ "ts-nkeys": "1.0.16" }, "devDependencies": { - "ts-node": "^8.8.1" + "ts-node": "^8.10.2", + "@types/mocha": "^8.0.4", + "@types/chai": "^4.2.14", + "chai": "^4.2.0", + "mocha": "^8.2.1" } } diff --git a/examples/request reply/streetlight/src/index.ts b/examples/request reply/streetlight/src/index.ts index 0c9527d9b..709f082e1 100644 --- a/examples/request reply/streetlight/src/index.ts +++ b/examples/request reply/streetlight/src/index.ts @@ -71,10 +71,10 @@ export declare interface NatsAsyncApiClient { export class NatsAsyncApiClient extends events.EventEmitter{ - public jsonClient?: Client; - public stringClient?: Client; - public binaryClient?: Client; - public options?: NatsConnectionOptions; + private jsonClient?: Client; + private stringClient?: Client; + private binaryClient?: Client; + private options?: NatsConnectionOptions; /** * @@ -109,6 +109,7 @@ export class NatsAsyncApiClient extends events.EventEmitter{ if (!this.jsonClient || this.jsonClient!.isClosed()){ return true; } + return false; } /** diff --git a/examples/request reply/streetlight/src/tests/StreetlightStreetlightIdCommandTurnon.spec.ts b/examples/request reply/streetlight/src/tests/StreetlightStreetlightIdCommandTurnon.spec.ts new file mode 100644 index 000000000..f76244e14 --- /dev/null +++ b/examples/request reply/streetlight/src/tests/StreetlightStreetlightIdCommandTurnon.spec.ts @@ -0,0 +1,77 @@ + + +import {describe, it} from 'mocha'; +import {expect} from 'chai'; +import * as Client from '../index' +import * as TestClient from './testclient/index' +import { NatsTypescriptTemplateError } from '../NatsTypescriptTemplateError'; + +describe('streetlight/{streetlight_id}/command/turnon can talk to it self', () => { + var client: Client.NatsAsyncApiClient; + var testClient: TestClient.NatsAsyncApiTestClient; + before(async () => { + client = new Client.NatsAsyncApiClient(); + testClient = new TestClient.NatsAsyncApiTestClient(); + const natsHost = process.env.NATS_HOST || "0.0.0.0" + const natsPort = process.env.NATS_PORT || "4222" + const natsUrl = `${natsHost}:${natsPort}` + await client.connectToHost(natsUrl); + await testClient.connectToHost(natsUrl); + }); + + it('Clients can connect', () => { + expect(client.isClosed()).to.be.false; + expect(testClient.isClosed()).to.be.false; + }); + + it('can send message', async () => { + +var receivedError: NatsTypescriptTemplateError | undefined = undefined; +var receivedMsg: TestClient.TurnonCommandMessage.TurnonCommand | undefined = undefined; +var recievedStreetlightId : string | undefined = undefined + + +var replyMessage: Client.GeneralReplyMessage.GeneralReply = { + "status_code": 0, + "status_message": "string" +}; +var receiveMessage: TestClient.TurnonCommandMessage.TurnonCommand = { + "lumen": 0 +}; +var StreetlightIdToSend: string = "string" + + +const replySubscription = await client.replyToStreetlightStreetlightIdCommandTurnon((err, msg + + ,streetlight_id + ) => { + return new Promise((resolve, reject) => { + receivedError = err; + receivedMsg = msg; + recievedStreetlightId = streetlight_id + + resolve(replyMessage); + })}, + (err) => {console.log(err)} + , StreetlightIdToSend + +); +var reply = await testClient.requestStreetlightStreetlightIdCommandTurnon(receiveMessage + , StreetlightIdToSend + ); +expect(reply).to.be.deep.equal(replyMessage) +expect(receivedError).to.be.undefined; +expect(receivedMsg).to.be.deep.equal(receiveMessage); +expect(recievedStreetlightId).to.be.equal(StreetlightIdToSend); + + + }); + + it('Can shutdown', async () => { + await client.disconnect() + await testClient.disconnect() + expect(client.isClosed()).to.be.true; + expect(testClient.isClosed()).to.be.true; + }); + +}); \ No newline at end of file diff --git a/examples/request reply/streetlight/src/tests/StreetlightStreetlightIdEventTurnon.spec.ts b/examples/request reply/streetlight/src/tests/StreetlightStreetlightIdEventTurnon.spec.ts new file mode 100644 index 000000000..42e0cb88d --- /dev/null +++ b/examples/request reply/streetlight/src/tests/StreetlightStreetlightIdEventTurnon.spec.ts @@ -0,0 +1,78 @@ + + +import {describe, it} from 'mocha'; +import {expect} from 'chai'; +import * as Client from '../index' +import * as TestClient from './testclient/index' +import { NatsTypescriptTemplateError } from '../NatsTypescriptTemplateError'; + +describe('streetlight/{streetlight_id}/event/turnon can talk to it self', () => { + var client: Client.NatsAsyncApiClient; + var testClient: TestClient.NatsAsyncApiTestClient; + before(async () => { + client = new Client.NatsAsyncApiClient(); + testClient = new TestClient.NatsAsyncApiTestClient(); + const natsHost = process.env.NATS_HOST || "0.0.0.0" + const natsPort = process.env.NATS_PORT || "4222" + const natsUrl = `${natsHost}:${natsPort}` + await client.connectToHost(natsUrl); + await testClient.connectToHost(natsUrl); + }); + + it('Clients can connect', () => { + expect(client.isClosed()).to.be.false; + expect(testClient.isClosed()).to.be.false; + }); + + it('can send message', async () => { + +var receivedError: NatsTypescriptTemplateError | undefined = undefined; +var receivedMsg: Client.AnonymousMessage4Message.AnonymousMessage4 | undefined = undefined; +var recievedStreetlightId : string | undefined = undefined + + + +var replyMessage: TestClient.GeneralReplyMessage.GeneralReply = { + "status_code": 0, + "status_message": "string" +}; +var requestMessage: Client.AnonymousMessage4Message.AnonymousMessage4 = { + "lumen": 0 +}; +var StreetlightIdToSend: string = "string" + + +const replySubscription = await testClient.replyToStreetlightStreetlightIdEventTurnon((err, msg + + ,streetlight_id + ) => { + return new Promise((resolve, reject) => { + receivedError = err; + receivedMsg = msg; + recievedStreetlightId = streetlight_id + + resolve(replyMessage); + })}, + (err) => {console.log(err)} + , StreetlightIdToSend + +); +var reply = await client.requestStreetlightStreetlightIdEventTurnon(requestMessage + , StreetlightIdToSend + ); +expect(reply).to.be.deep.equal(replyMessage) +expect(receivedError).to.be.undefined; +expect(receivedMsg).to.be.deep.equal(requestMessage); +expect(recievedStreetlightId).to.be.equal(StreetlightIdToSend); + + + }); + + it('Can shutdown', async () => { + await client.disconnect() + await testClient.disconnect() + expect(client.isClosed()).to.be.true; + expect(testClient.isClosed()).to.be.true; + }); + +}); \ No newline at end of file diff --git a/examples/request reply/streetlight/src/tests/testclient/index.ts b/examples/request reply/streetlight/src/tests/testclient/index.ts index d74570505..5833c14a8 100644 --- a/examples/request reply/streetlight/src/tests/testclient/index.ts +++ b/examples/request reply/streetlight/src/tests/testclient/index.ts @@ -63,10 +63,10 @@ export declare interface NatsAsyncApiTestClient { export class NatsAsyncApiTestClient extends events.EventEmitter{ - public jsonClient?: Client; - public stringClient?: Client; - public binaryClient?: Client; - public options?: NatsConnectionOptions; + private jsonClient?: Client; + private stringClient?: Client; + private binaryClient?: Client; + private options?: NatsConnectionOptions; /** * @@ -101,6 +101,7 @@ export class NatsAsyncApiTestClient extends events.EventEmitter{ if (!this.jsonClient || this.jsonClient!.isClosed()){ return true; } + return false; } /** diff --git a/filters/all.js b/filters/all.js index 6bd97e7f5..ac0803d5b 100644 --- a/filters/all.js +++ b/filters/all.js @@ -141,6 +141,7 @@ function toTsType(jsonSchemaType, property) { default: return 'any'; } } +filter.toTsType = toTsType; /** @@ -182,12 +183,12 @@ filter.realizeChannelNameWithoutParameters = (channelName) => { } /** - * Realize parameters without using types without trailing comma + * Realize parameters without using types and without trailing comma */ filter.realizeParametersForChannelWithoutType = (parameters) => { let returnString = ''; for (paramName in parameters) { - returnString += `${paramName},`; + returnString += `${filter.realizeParameterForChannelWithoutType(paramName)},`; } if (returnString.length >= 1) { returnString = returnString.slice(0, -1); @@ -195,16 +196,23 @@ filter.realizeParametersForChannelWithoutType = (parameters) => { return returnString; } +filter.realizeParameterForChannelWithoutType = (parameterName) => { + return `${parameterName}`; +} +filter.realizeParameterForChannelWithType = (parameterName, parameter, required = true) => { + const requiredType = !required ? '?' : '' + return `${parameterName}${requiredType}: ${toTsType( + parameter.schema().type() + )}`; +} + /** * Realize parameters using types without trailing comma */ filter.realizeParametersForChannel = (parameters, required = true) => { let returnString = ''; - const requiredType = !required ? '?' : '' for (paramName in parameters) { - returnString += `${paramName}${requiredType}: ${toTsType( - parameters[paramName].schema().type() - )},`; + returnString += filter.realizeParameterForChannelWithType(paramName, parameters[paramName], required) + ","; } if (returnString.length >= 1) { returnString = returnString.slice(0, -1); diff --git a/package-lock.json b/package-lock.json index 7f80d8d5c..efcb99849 100644 --- a/package-lock.json +++ b/package-lock.json @@ -752,11 +752,18 @@ "yaml": "^1.7.2" } }, + "cross-env": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.2.tgz", + "integrity": "sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw==", + "requires": { + "cross-spawn": "^7.0.1" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1451,8 +1458,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isomorphic-fetch": { "version": "2.2.1", @@ -5600,8 +5606,7 @@ "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" }, "path-parse": { "version": "1.0.6", @@ -6034,7 +6039,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "requires": { "shebang-regex": "^3.0.0" } @@ -6042,8 +6046,7 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, "signal-exit": { "version": "3.0.3", @@ -6536,7 +6539,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "requires": { "isexe": "^2.0.0" } diff --git a/package.json b/package.json index 974888ee4..a687dac7f 100644 --- a/package.json +++ b/package.json @@ -21,15 +21,19 @@ "license": "Apache-2.0", "scripts": { "generate:examples": "npm run generate:examples:pubSub && npm run generate:examples:requestReply", - "generate:examples:pubSub": "cd \"examples/publish subscribe\" && sh generate.sh", - "generate:examples:requestReply": "cd \"examples/request reply\" && sh generate.sh", + "generate:examples:pubSub": "cd \"examples/publish subscribe\" && sh GenerateAndBuild.sh", + "generate:examples:requestReply": "cd \"examples/request reply\" && sh GenerateAndBuild.sh", "release": "semantic-release", "lint": "echo \"No linter specified yet\"", "test": "echo \"No tests specified yet\"", + "test:examples:integration": "npm run test:examples:integration:pubsub && npm run test:examples:integration:requestreply", + "test:examples:integration:pubsub": "cd \"examples/publish subscribe\" && sh ./Test.sh", + "test:examples:integration:requestreply": "cd \"examples/request reply\" && sh ./Test.sh", "get-version": "echo $npm_package_version" }, "dependencies": { "@asyncapi/generator-filters": "^1.0.0", + "cross-env": "^7.0.2", "filenamify": "^4.1.0", "is-url": "1.2.4", "lodash": "^4.17.20", @@ -83,7 +87,7 @@ "required": false } }, - "generator": ">=2.0.0", + "generator": "<=2.0.0", "filters": [ "@asyncapi/generator-filters" ] diff --git a/partials/index/Standard.njk b/partials/index/Standard.njk index 602b9b8e6..9da799a8d 100644 --- a/partials/index/Standard.njk +++ b/partials/index/Standard.njk @@ -1,10 +1,10 @@ {% macro standard(asyncapi) %} - public jsonClient?: Client; - public stringClient?: Client; - public binaryClient?: Client; - public options?: NatsConnectionOptions; + private jsonClient?: Client; + private stringClient?: Client; + private binaryClient?: Client; + private options?: NatsConnectionOptions; /** * @@ -67,6 +67,7 @@ return true; } {%- endif %} + return false; } /** diff --git a/partials/tests/integration/Publish.njk b/partials/tests/integration/Publish.njk new file mode 100644 index 000000000..a4f2f8171 --- /dev/null +++ b/partials/tests/integration/Publish.njk @@ -0,0 +1,44 @@ + +{% macro publish(defaultContentType, channelName, message, messageDescription, channelParameters) %} + +var receivedError: NatsTypescriptTemplateError | undefined = undefined; +var receivedMsg: TestClient.{{message | getMessageType}} | undefined = undefined; +{%- for paramName, param in channelParameters %} +var recieved{{paramName | pascalCase }} : {{param.schema().type() | toTsType}} | undefined = undefined +{% endfor %} + +var publishMessage: TestClient.{{message | getMessageType}} = {{message.payload().json() | generateExample | safe}}; +{%- for paramName, param in channelParameters %} +var {{paramName | pascalCase }}ToSend: {{param.schema().type() | toTsType}} = {{param.schema().json() | generateExample | safe}} +{% endfor %} + +const tryAndWaitForResponse = new Promise(resolve => { + setTimeout(resolve, 100); +}); + + +const replySubscription = await testClient.subscribeTo{{channelName | pascalCase}}((err, msg + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannelWithoutType}} + {% endif %}) => { + receivedError = err; + receivedMsg = msg; + {%- for paramName, param in channelParameters %} + recieved{{paramName | realizeParameterForChannelWithoutType | pascalCase }} = {{paramName}} + {% endfor %} + } + {%- for paramName, param in channelParameters %} + , {{paramName | pascalCase }}ToSend + {% endfor %} +); +await client.publishTo{{channelName | pascalCase}}(publishMessage + {%- for paramName, param in channelParameters %} + , {{paramName | pascalCase }}ToSend + {% endfor %}); +await tryAndWaitForResponse; +expect(receivedError).to.be.undefined; +expect(receivedMsg).to.be.deep.equal(publishMessage); +{%- for paramName, param in channelParameters %} +expect(recieved{{paramName | realizeParameterForChannelWithoutType | pascalCase }}).to.be.equal({{paramName | pascalCase }}ToSend); +{% endfor %} +{% endmacro %} diff --git a/partials/tests/integration/Reply.njk b/partials/tests/integration/Reply.njk new file mode 100644 index 000000000..b9f39d3ea --- /dev/null +++ b/partials/tests/integration/Reply.njk @@ -0,0 +1,42 @@ + +{% macro reply(defaultContentType, channelName, replyMessage, receiveMessage, messageDescription, channelParameters, params) %} +var receivedError: NatsTypescriptTemplateError | undefined = undefined; +var receivedMsg: TestClient.{{receiveMessage | getMessageType}} | undefined = undefined; +{%- for paramName, param in channelParameters %} +var recieved{{paramName | pascalCase }} : {{param.schema().type() | toTsType}} | undefined = undefined +{% endfor %} + +var replyMessage: Client.{{replyMessage | getMessageType}} = {{replyMessage.payload().json() | generateExample | safe}}; +var receiveMessage: TestClient.{{receiveMessage | getMessageType}} = {{receiveMessage.payload().json() | generateExample | safe}}; +{%- for paramName, param in channelParameters %} +var {{paramName | pascalCase }}ToSend: {{param.schema().type() | toTsType}} = {{param.schema().json() | generateExample | safe}} +{% endfor %} + +const replySubscription = await client.replyTo{{channelName | pascalCase}}((err, msg + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannelWithoutType}} + {% endif %}) => { + return new Promise((resolve, reject) => { + receivedError = err; + receivedMsg = msg; + {%- for paramName, param in channelParameters %} + recieved{{paramName | realizeParameterForChannelWithoutType | pascalCase }} = {{paramName}} + {% endfor %} + resolve(replyMessage); + })}, + (err) => {console.log(err)} + {%- for paramName, param in channelParameters %} + , {{paramName | pascalCase }}ToSend + {% endfor %} +); +var reply = await testClient.request{{channelName | pascalCase}}(receiveMessage + {%- for paramName, param in channelParameters %} + , {{paramName | pascalCase }}ToSend + {% endfor %}); +expect(reply).to.be.deep.equal(replyMessage) +expect(receivedError).to.be.undefined; +expect(receivedMsg).to.be.deep.equal(receiveMessage); +{%- for paramName, param in channelParameters %} +expect(recieved{{paramName | realizeParameterForChannelWithoutType | pascalCase }}).to.be.equal({{paramName | pascalCase }}ToSend); +{% endfor %} +{% endmacro %} diff --git a/partials/tests/integration/Request.njk b/partials/tests/integration/Request.njk new file mode 100644 index 000000000..27e40e2ad --- /dev/null +++ b/partials/tests/integration/Request.njk @@ -0,0 +1,43 @@ + +{% macro request(defaultContentType, channelName, requestMessage, replyMessage, messageDescription, channelParameters) %} +var receivedError: NatsTypescriptTemplateError | undefined = undefined; +var receivedMsg: Client.{{requestMessage | getMessageType}} | undefined = undefined; +{%- for paramName, param in channelParameters %} +var recieved{{paramName | pascalCase }} : {{param.schema().type() | toTsType}} | undefined = undefined +{% endfor %} + + +var replyMessage: TestClient.{{replyMessage | getMessageType}} = {{replyMessage.payload().json() | generateExample | safe}}; +var requestMessage: Client.{{requestMessage | getMessageType}} = {{requestMessage.payload().json() | generateExample | safe}}; +{%- for paramName, param in channelParameters %} +var {{paramName | pascalCase }}ToSend: {{param.schema().type() | toTsType}} = {{param.schema().json() | generateExample | safe}} +{% endfor %} + +const replySubscription = await testClient.replyTo{{channelName | pascalCase}}((err, msg + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannelWithoutType}} + {% endif %}) => { + return new Promise((resolve, reject) => { + receivedError = err; + receivedMsg = msg; + {%- for paramName, param in channelParameters %} + recieved{{paramName | realizeParameterForChannelWithoutType | pascalCase }} = {{paramName}} + {% endfor %} + resolve(replyMessage); + })}, + (err) => {console.log(err)} + {%- for paramName, param in channelParameters %} + , {{paramName | pascalCase }}ToSend + {% endfor %} +); +var reply = await client.request{{channelName | pascalCase}}(requestMessage + {%- for paramName, param in channelParameters %} + , {{paramName | pascalCase }}ToSend + {% endfor %}); +expect(reply).to.be.deep.equal(replyMessage) +expect(receivedError).to.be.undefined; +expect(receivedMsg).to.be.deep.equal(requestMessage); +{%- for paramName, param in channelParameters %} +expect(recieved{{paramName | realizeParameterForChannelWithoutType | pascalCase }}).to.be.equal({{paramName | pascalCase }}ToSend); +{% endfor %} +{% endmacro %} diff --git a/partials/tests/integration/Subscribe.njk b/partials/tests/integration/Subscribe.njk new file mode 100644 index 000000000..c3b72e5e0 --- /dev/null +++ b/partials/tests/integration/Subscribe.njk @@ -0,0 +1,43 @@ + +{% macro subscribe(defaultContentType, channelName, message, messageDescription, channelParameters) %} + +var receivedError: NatsTypescriptTemplateError | undefined = undefined; +var receivedMsg: Client.{{message | getMessageType}} | undefined = undefined; +{%- for paramName, param in channelParameters %} +var recieved{{paramName | pascalCase }} : {{param.schema().type() | toTsType}} | undefined = undefined +{% endfor %} + +var publishMessage: Client.{{message | getMessageType}} = {{message.payload().json() | generateExample | safe}}; +{%- for paramName, param in channelParameters %} +var {{paramName | pascalCase }}ToSend: {{param.schema().type() | toTsType}} = {{param.schema().json() | generateExample | safe}} +{% endfor %} + +const tryAndWaitForResponse = new Promise(resolve => { + setTimeout(resolve, 100); +}); + +const replySubscription = await client.subscribeTo{{channelName | pascalCase}}((err, msg + {% if channelParameters | length %} + ,{{channelParameters | realizeParametersForChannelWithoutType}} + {% endif %}) => { + receivedError = err; + receivedMsg = msg; + {%- for paramName, param in channelParameters %} + recieved{{paramName | realizeParameterForChannelWithoutType | pascalCase }} = {{paramName}} + {% endfor %} + } + {%- for paramName, param in channelParameters %} + , {{paramName | pascalCase }}ToSend + {% endfor %} +); +await testClient.publishTo{{channelName | pascalCase}}(publishMessage + {%- for paramName, param in channelParameters %} + , {{paramName | pascalCase }}ToSend + {% endfor %}); +await tryAndWaitForResponse; +expect(receivedError).to.be.undefined; +expect(receivedMsg).to.be.deep.equal(publishMessage); +{%- for paramName, param in channelParameters %} +expect(recieved{{paramName | realizeParameterForChannelWithoutType | pascalCase }}).to.be.equal({{paramName | pascalCase }}ToSend); +{% endfor %} +{% endmacro %} diff --git a/template/package.json.njk b/template/package.json.njk index 41b2ff0f3..651ebf1b8 100644 --- a/template/package.json.njk +++ b/template/package.json.njk @@ -20,7 +20,8 @@ "types": "dist/index.d.ts", "scripts": { "watch": "tsc --watch", - "build": "tsc" + "build": "tsc", + "test:integration": "./node_modules/.bin/mocha -r ts-node/register src/tests/**/*.spec.ts" }, "dependencies": { "@types/klaw-sync": "^6.0.0", @@ -30,6 +31,10 @@ "ts-nkeys":"1.0.16" }, "devDependencies": { - "ts-node": "^8.8.1" + "ts-node": "^8.10.2", + "@types/mocha": "^8.0.4", + "@types/chai": "^4.2.14", + "chai": "^4.2.0", + "mocha": "^8.2.1" } } diff --git a/template/src/tests/$$channel$$.spec.ts.njk b/template/src/tests/$$channel$$.spec.ts.njk new file mode 100644 index 000000000..24672161d --- /dev/null +++ b/template/src/tests/$$channel$$.spec.ts.njk @@ -0,0 +1,58 @@ + +{%- from "../../../partials/tests/integration/Publish.njk" import publish %} +{%- from "../../../partials/tests/integration/Reply.njk" import reply %} +{%- from "../../../partials/tests/integration/Request.njk" import request %} +{%- from "../../../partials/tests/integration/Subscribe.njk" import subscribe %} + +import {describe, it} from 'mocha'; +import {expect} from 'chai'; +import * as Client from '../index' +import * as TestClient from './testclient/index' +import { NatsTypescriptTemplateError } from '../NatsTypescriptTemplateError'; + +describe('{{channelName}} can talk to it self', () => { + var client: Client.NatsAsyncApiClient; + var testClient: TestClient.NatsAsyncApiTestClient; + before(async () => { + client = new Client.NatsAsyncApiClient(); + testClient = new TestClient.NatsAsyncApiTestClient(); + const natsHost = process.env.NATS_HOST || "0.0.0.0" + const natsPort = process.env.NATS_PORT || "4222" + const natsUrl = `${natsHost}:${natsPort}` + await client.connectToHost(natsUrl); + await testClient.connectToHost(natsUrl); + }); + + it('Clients can connect', () => { + expect(client.isClosed()).to.be.false; + expect(testClient.isClosed()).to.be.false; + }); + + it('can send message', async () => { + {%- if channel | isRequestReply %} + {%- if channel | isRequester %} + {{request(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters())}} + {%- endif %} + {%- if channel | isReplier %} + {{reply(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.publish().message(0), channel.description(), channel.parameters(), params)}} + {%- endif %} + {%- endif %} + + {%- if channel | isPubsub %} + {%- if channel.hasSubscribe() %} + {{publish(asyncapi.defaultContentType(), channelName, channel.subscribe().message(0), channel.description(), channel.parameters())}} + {%- endif %} + {%- if channel.hasPublish() %} + {{subscribe(asyncapi.defaultContentType(), channelName, channel.publish().message(0), channel.description(), channel.parameters())}} + {%- endif %} + {%- endif %} + }); + + it('Can shutdown', async () => { + await client.disconnect() + await testClient.disconnect() + expect(client.isClosed()).to.be.true; + expect(testClient.isClosed()).to.be.true; + }); + +}); \ No newline at end of file From f3e5c2c8ad737a0652637d20c6c7c27ddb72358d Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Fri, 20 Nov 2020 12:24:57 +0100 Subject: [PATCH 108/110] Switch over to use filter for quicktype --- .../pull-request-integration-testing.yml | 5 ++- README.md | 20 ++++++---- hooks/quicktype-schema.js | 40 +++++-------------- package-lock.json | 10 +++++ package.json | 3 +- 5 files changed, 37 insertions(+), 41 deletions(-) diff --git a/.github/workflows/pull-request-integration-testing.yml b/.github/workflows/pull-request-integration-testing.yml index 51e975ae2..72b20423a 100644 --- a/.github/workflows/pull-request-integration-testing.yml +++ b/.github/workflows/pull-request-integration-testing.yml @@ -1,7 +1,8 @@ name: Pull request integration testing -on: - pull_request, synchronize +on: + pull_request: + types: [synchronize] jobs: test: diff --git a/README.md b/README.md index 1865aa320..f3f783d8f 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This template is for generating a TypeScript/Node.js NATS client based on an Asy # How to use Example generations can be found under [examples](./examples) which includes [publish and subscribe](./examples/publish%20subscribe) example as well as [request and reply](./examples/request%20reply). ## Requirements -* @asyncapi/generator <= v1.0.0-rc.11 +* @asyncapi/generator < v2.0.0 >v1.0.0 Install the generator through [npm or run it from docker official installer](https://github.com/asyncapi/generator#install). @@ -17,10 +17,10 @@ The leading examples are both in TypeScript and in Node.js since this template c Given any AsyncAPI file (`AsyncAPI.yml`) first generate the client with the [AsyncAPI generator](https://github.com/asyncapi/generator) such as ```bash -ag --install --output ./nats-client ./AsyncAPI.yml @asyncapi/ts-nats-template --force-write --param "generateTestClient=true" --param "promisifyReplyCallback=true" +ag --install --output ./nats-client ./AsyncAPI.yml @asyncapi/ts-nats-template --param "generateTestClient=true" --param "promisifyReplyCallback=true" ``` -Afterward, `cd` into the generated folder `nats-client` and run the commands `npm i` and `npm run build`. The generated NATS client is now ready to be used in either TypeScript or Node.js. +Afterward, go into the generated folder `nats-client` and run the commands `npm i` and `npm run build`. The generated NATS client is now ready to be used in either TypeScript or Node.js. ### TypeScript @@ -59,7 +59,7 @@ connect(); # Restrictions * Empty objects are not supported, use `null` types instead. -* This template has not been tested with payloads with different specs other than JSON Schema draft 7. +* Recursive objects are not currently supported # Connection options Currently the generated client offers 4 standard methods of connecting to your NATS server `connectWithUserCreds`, `connectWithUserPass`, `connectToHost` and `connectWithNkey`. If you need something customized use the standard `connect` method with your custom options. Currently, the template does not care which security details you have defined in your AsyncAPI document. @@ -242,10 +242,16 @@ Hooks.getInstance().registerreceivedData(decode); There are different hook restrictions based on the payload type. ### Binary payloads -The first hook always receives the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return a buffer to transmit. +If you only have 1 hook then you must ensure that it returns a buffer. + +If you have multiple hooks then the following applies: The first hook always receives the message type as is. Any intermediary hooks receives what the last hook returned and can return any type of your choosing. The last hook is required to return a buffer to transmit. ### JSON payloads -The first hook always receives the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return a JSON message. +If you only have 1 hook then you must ensure that it returns a JSON object. + +If you have multiple hooks then the following applies: The first hook always receives the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return a JSON object. ### String payloads -The first hook always receives the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return a string representation of the message. +If you only have 1 hook then you must ensure that it returns a string. + +If you have multiple hooks then the following applies: The first hook always receives the message type as is. Any intermediary hooks can return any type of your choosing. The last hook is required to return a string representation of the message. diff --git a/hooks/quicktype-schema.js b/hooks/quicktype-schema.js index 1f568b95a..150dc3eed 100644 --- a/hooks/quicktype-schema.js +++ b/hooks/quicktype-schema.js @@ -1,26 +1,4 @@ -const fs = require('fs'); -const Path = require('path'); -const filters = require("../filters/all") -const { quicktype, InputData, JSONSchemaInput, JSONSchemaStore } = require("quicktype-core"); - -/** - * Generate a typescript structure from a schema. - * - * @param {String} schemaPath Path to the folder to store the generated files - * @param {*} schemaName The name of the schema to generate - * @param {*} jsonSchema The schema to generate - */ -async function genSchema(schemaPath, schemaName, jsonSchema){ - const schemaString = JSON.stringify(jsonSchema.json()); - const schemaInput = new JSONSchemaInput(new JSONSchemaStore()); - await schemaInput.addSource({ name: schemaName, schema: schemaString }); - const inputData = new InputData(); - inputData.addInput(schemaInput) - const { lines } = await quicktype({ lang: "typescript", inputData }); - await fs.promises.mkdir(schemaPath, { recursive: true }).catch(console.error); - fs.mkdirSync(schemaPath, { recursive: true }); - fs.writeFileSync(Path.join(schemaPath, filters.pascalCase(schemaName)+".ts"), lines.join("\n")); -} +const quicktypeFilter = require('@lagoni/asyncapi-quicktype-filter'); /** * Use quicktype to generate messages with their payload. @@ -28,13 +6,13 @@ async function genSchema(schemaPath, schemaName, jsonSchema){ module.exports = { 'generate:after': async (generator) => { const allMessages = generator.asyncapi.allMessages(); - for (let [messageId, message] of allMessages) { - const payloadSchema = message.payload(); - //Null payload is not supported by quicktype, and cannot be generated. - if(payloadSchema.type()+"" != "null"){ - const filepath = Path.join(generator.targetDir, "src/messages/"); - await genSchema(filepath, messageId, message.payload()); - } - } + await quicktypeFilter.generateAllMessagePayloads( + generator.targetDir, + { + quicktypeLanguage: "typescript", + subTargetDir: "src/messages/" + }, + allMessages + ); } }; diff --git a/package-lock.json b/package-lock.json index efcb99849..368d0d8c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,6 +40,16 @@ "js-tokens": "^4.0.0" } }, + "@lagoni/asyncapi-quicktype-filter": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@lagoni/asyncapi-quicktype-filter/-/asyncapi-quicktype-filter-1.2.3.tgz", + "integrity": "sha512-v8vsK2IhvJP0MhYPF9YAF+YLfbQrlcS6Qa9G3g7aFNgh2PMLIrf1uiD9ZzPpyF94vaRZCMlli3iaTKhZYkpYYA==", + "requires": { + "is-url": "^1.2.4", + "lodash": "^4.17.15", + "quicktype-core": "6.0.66" + } + }, "@mark.probst/unicode-properties": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@mark.probst/unicode-properties/-/unicode-properties-1.1.0.tgz", diff --git a/package.json b/package.json index a687dac7f..052f830e7 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ }, "dependencies": { "@asyncapi/generator-filters": "^1.0.0", + "@lagoni/asyncapi-quicktype-filter": "^1.2.3", "cross-env": "^7.0.2", "filenamify": "^4.1.0", "is-url": "1.2.4", @@ -87,7 +88,7 @@ "required": false } }, - "generator": "<=2.0.0", + "generator": "<2.0.0 >1.0.0", "filters": [ "@asyncapi/generator-filters" ] From bc25cd89121d2c9f9f5761d418a492fe55b5f260 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Fri, 20 Nov 2020 12:29:00 +0100 Subject: [PATCH 109/110] Updated readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f3f783d8f..4061e0cd0 100644 --- a/README.md +++ b/README.md @@ -54,12 +54,12 @@ connect(); # Features * Supports wildcard channels. AsyncAPI describes the channel path to be defined as [RFC 6570 URI](https://www.asyncapi.com/docs/specifications/2.0.0/#a-name-channelsobject-a-channels-object). So a channel containing a wildcard needs to be defined with parameters such as `smartylighting/streetlights/{wildcard}`. * Supports [test/mirror client](#test-client) for testing or other useful scenarios. -* This template can be used as a javascript library as well since the generated code works directly in Node.js. +* This template can be used as a NodeJS library. * This template uses [quicktype](https://quicktype.io/) to generate the corresponding message payloads. # Restrictions * Empty objects are not supported, use `null` types instead. -* Recursive objects are not currently supported +* Recursive objects are not currently supported. # Connection options Currently the generated client offers 4 standard methods of connecting to your NATS server `connectWithUserCreds`, `connectWithUserPass`, `connectToHost` and `connectWithNkey`. If you need something customized use the standard `connect` method with your custom options. Currently, the template does not care which security details you have defined in your AsyncAPI document. From 752f867fc80491965dbf4e6f9ee6fcbc4f500eca Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Mon, 7 Dec 2020 13:27:09 +0100 Subject: [PATCH 110/110] Removed already existing workflows --- .../workflows/automerge-release-pr-bump.yml | 47 ------------------- .github/workflows/sentiment-analysis.yml | 41 ---------------- .../workflows/welcome-first-time-contrib.yml | 25 ---------- 3 files changed, 113 deletions(-) delete mode 100644 .github/workflows/automerge-release-pr-bump.yml delete mode 100644 .github/workflows/sentiment-analysis.yml delete mode 100644 .github/workflows/welcome-first-time-contrib.yml diff --git a/.github/workflows/automerge-release-pr-bump.yml b/.github/workflows/automerge-release-pr-bump.yml deleted file mode 100644 index e84abcbb1..000000000 --- a/.github/workflows/automerge-release-pr-bump.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Automerge release bump PR - -on: - pull_request: - types: - - labeled - - unlabeled - - synchronize - - opened - - edited - - ready_for_review - - reopened - - unlocked - pull_request_review: - types: - - submitted - check_suite: - types: - - completed - status: {} - -jobs: - - autoapprove: - runs-on: ubuntu-latest - steps: - - name: Autoapproving - uses: hmarr/auto-approve-action@v2.0.0 - if: github.actor == 'asyncapi-bot' - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - - automerge: - needs: [autoapprove] - runs-on: ubuntu-latest - steps: - - name: Automerging - uses: pascalgn/automerge-action@v0.7.5 - if: github.actor == 'asyncapi-bot' - env: - GITHUB_TOKEN: "${{ secrets.GH_TOKEN }}" - GITHUB_LOGIN: asyncapi-bot - MERGE_LABELS: "" - MERGE_METHOD: "squash" - MERGE_COMMIT_MESSAGE: "pull-request-title" - MERGE_RETRIES: "10" - MERGE_RETRY_SLEEP: "10000" \ No newline at end of file diff --git a/.github/workflows/sentiment-analysis.yml b/.github/workflows/sentiment-analysis.yml deleted file mode 100644 index 90607cfe6..000000000 --- a/.github/workflows/sentiment-analysis.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: 'Sentiment Analysis' - -on: - issue_comment: - types: - - created - - edited - issues: - types: - - opened - - edited - pull_request: - types: - - opened - - edited - pull_request_review: - types: - - submitted - - edited - pull_request_review_comment: - types: - - created - - edited -jobs: - test: - name: Checking sentiments - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Check sentiment - uses: derberg/code-of-conduct-sentiment-analysis-github-action@v1 - id: sentiments - with: - gcp_key: ${{ secrets.GCP_KEY_SENTIMENT }} - - uses: someimportantcompany/github-actions-slack-message@v1 - # this step runs only if sentiment is a negative number - if: steps.sentiments.outputs.sentiment < -0.6 - with: - webhook-url: ${{ secrets.SLACK_SENTIMENTS }} - text: Here ${{steps.sentiments.outputs.source}} you can find a potential negative text that requires your attention as the sentiment analysis score is ${{steps.sentiments.outputs.sentiment}} - color: orange \ No newline at end of file diff --git a/.github/workflows/welcome-first-time-contrib.yml b/.github/workflows/welcome-first-time-contrib.yml deleted file mode 100644 index 73e15166f..000000000 --- a/.github/workflows/welcome-first-time-contrib.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Welcome first time contributors - -on: - pull_request_target: - types: - - opened - issues: - types: - - opened - -jobs: - welcome: - runs-on: ubuntu-latest - steps: - - uses: actions/first-interaction@v1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - issue-message: | - Welcome to AsyncAPI. Thanks a lot for reporting your first issue. - Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out [this issue](https://github.com/asyncapi/asyncapi/issues/115). - pr-message: | - Welcome to AsyncAPI. Thanks a lot for creating your first pull request. - - Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out [this issue](https://github.com/asyncapi/asyncapi/issues/115). -