@asyncapi/converter 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -11
- package/lib/convert.js +7 -169
- package/lib/first-version.d.ts +2 -0
- package/lib/first-version.js +20 -0
- package/lib/index.d.ts +1 -1
- package/lib/interfaces.d.ts +25 -3
- package/lib/second-version.d.ts +2 -0
- package/lib/second-version.js +217 -0
- package/lib/third-version.d.ts +2 -0
- package/lib/third-version.js +452 -0
- package/lib/utils.d.ts +9 -9
- package/lib/utils.js +70 -58
- package/package.json +5 -31
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ Convert [AsyncAPI](https://asyncapi.com) documents older to newer versions.
|
|
|
15
15
|
* [From CLI](#from-cli)
|
|
16
16
|
* [In JS](#in-js)
|
|
17
17
|
* [In TS](#in-ts)
|
|
18
|
+
- [Conversion 2.x.x to 3.x.x](#conversion-2xx-to-3xx)
|
|
18
19
|
- [Known missing features](#known-missing-features)
|
|
19
20
|
- [Development](#development)
|
|
20
21
|
- [Contribution](#contribution)
|
|
@@ -32,7 +33,7 @@ npm i @asyncapi/converter
|
|
|
32
33
|
|
|
33
34
|
### From CLI
|
|
34
35
|
|
|
35
|
-
To convert an
|
|
36
|
+
To convert an AsyncAPI document in the console needs the official [AsyncAPI CLI](https://github.com/asyncapi/cli).
|
|
36
37
|
|
|
37
38
|
If you don't have CLI installed, run this command to install the CLI globally on your system:
|
|
38
39
|
|
|
@@ -51,7 +52,7 @@ channels:
|
|
|
51
52
|
...
|
|
52
53
|
```
|
|
53
54
|
|
|
54
|
-
Convert to specific version:
|
|
55
|
+
Convert to a specific version:
|
|
55
56
|
|
|
56
57
|
```sh
|
|
57
58
|
asyncapi convert streetlights.yml -o streetlights2.yml -t 2.3.0
|
|
@@ -70,9 +71,7 @@ const { convert } = require('@asyncapi/converter')
|
|
|
70
71
|
|
|
71
72
|
try {
|
|
72
73
|
const asyncapi = fs.readFileSync('streetlights.yml', 'utf-8')
|
|
73
|
-
console.log(convert(asyncapi, '2.
|
|
74
|
-
id: 'urn:com.asyncapi.streetlights'
|
|
75
|
-
}));
|
|
74
|
+
console.log(convert(asyncapi, '2.6.0'));
|
|
76
75
|
} catch (e) {
|
|
77
76
|
console.error(e);
|
|
78
77
|
}
|
|
@@ -85,18 +84,83 @@ import { convert } from '@asyncapi/converter';
|
|
|
85
84
|
import type { ConvertVersion, ConvertOptions } from '@asyncapi/converter';
|
|
86
85
|
|
|
87
86
|
try {
|
|
88
|
-
const toVersion: ConvertVersion = '2.
|
|
89
|
-
const options: ConvertOptions = {
|
|
90
|
-
id: 'urn:com.asyncapi.streetlights'
|
|
91
|
-
};
|
|
92
|
-
|
|
87
|
+
const toVersion: ConvertVersion = '2.6.0';
|
|
93
88
|
const asyncapi = fs.readFileSync('streetlights.yml', 'utf-8')
|
|
94
|
-
console.log(convert(asyncapi, toVersion
|
|
89
|
+
console.log(convert(asyncapi, toVersion));
|
|
95
90
|
} catch (e) {
|
|
96
91
|
console.error(e)
|
|
97
92
|
}
|
|
98
93
|
```
|
|
99
94
|
|
|
95
|
+
## Conversion 2.x.x to 3.x.x
|
|
96
|
+
|
|
97
|
+
> **NOTE**: This feature is still WIP, and is until the final release of `3.0.0`.
|
|
98
|
+
|
|
99
|
+
Conversion to version `3.x.x` from `2.x.x` has several assumptions that should be know before converting:
|
|
100
|
+
|
|
101
|
+
- The input must be valid AsyncAPI document.
|
|
102
|
+
- External references are not resolved and converted, they remain untouched, even if they are incorrect.
|
|
103
|
+
- In version `3.0.0`, the channel identifier is no longer its address, but due to the difficulty of defining a unique identifier, we still treat the address as an identifier. If there is a need to assign an identifier other than an address, an `x-channelId` extension should be defined at the level of the given channel.
|
|
104
|
+
|
|
105
|
+
```yaml
|
|
106
|
+
# 2.x.x
|
|
107
|
+
channels:
|
|
108
|
+
users/signup:
|
|
109
|
+
x-channelId: 'userSignUp'
|
|
110
|
+
...
|
|
111
|
+
users/logout:
|
|
112
|
+
...
|
|
113
|
+
|
|
114
|
+
# 3.0.0
|
|
115
|
+
channels:
|
|
116
|
+
userSignUp:
|
|
117
|
+
...
|
|
118
|
+
users/logout:
|
|
119
|
+
...
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
- The `publish` operation is treated as a `receive` action, and `subscribe` is treated as a `send` action. Conversion by default is embraced from the application perspective. If you want to change this logic, you need to specify `v2tov3.pointOfView` configuration as `client`.
|
|
123
|
+
- If the operation does not have an `operationId` field defined, the unique identifier of the operation will be defined as a combination of the identifier of the channel on which the operation was defined + the type of operation, `publish` or `subscribe`. Identical situation is with messages. However, here the priority is the `messageId` field and then the concatenation `{publish|subscribe}.messages.{optional index of oneOf messages}`.
|
|
124
|
+
|
|
125
|
+
```yaml
|
|
126
|
+
# 2.x.x
|
|
127
|
+
channels:
|
|
128
|
+
users/signup:
|
|
129
|
+
publish:
|
|
130
|
+
message:
|
|
131
|
+
...
|
|
132
|
+
subscribe:
|
|
133
|
+
operationId: 'userSignUpEvent'
|
|
134
|
+
message:
|
|
135
|
+
oneOf:
|
|
136
|
+
- messageId: 'userSignUpEventMessage'
|
|
137
|
+
...
|
|
138
|
+
- ...
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
# 3.0.0
|
|
142
|
+
channels:
|
|
143
|
+
users/signup:
|
|
144
|
+
messages:
|
|
145
|
+
publish.message:
|
|
146
|
+
...
|
|
147
|
+
userSignUpEventMessage:
|
|
148
|
+
...
|
|
149
|
+
userSignUpEvent.message.1:
|
|
150
|
+
...
|
|
151
|
+
operations:
|
|
152
|
+
users/signup.publish:
|
|
153
|
+
action: receive
|
|
154
|
+
...
|
|
155
|
+
userSignUpEvent:
|
|
156
|
+
action: send
|
|
157
|
+
...
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
- Security requirements that use scopes are defined in the appropriate places inline, the rest as a reference to the `components.securitySchemes` objects.
|
|
161
|
+
- If servers are defined at the channel level, they are converted as references to the corresponding objects defined in the `servers` field.
|
|
162
|
+
- Channels and servers defined in components are also converted (unless configured otherwise).
|
|
163
|
+
|
|
100
164
|
## Known missing features
|
|
101
165
|
|
|
102
166
|
* When converting from 1.x to 2.x, Streaming APIs (those using `stream` instead of `topics` or `events`) are converted correctly but information about framing type and delimiter is missing until a [protocolInfo](https://github.com/asyncapi/extensions-catalog/issues/1) for that purpose is created.
|
package/lib/convert.js
CHANGED
|
@@ -1,37 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
-
var t = {};
|
|
4
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
-
t[p] = s[p];
|
|
6
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
-
t[p[i]] = s[p[i]];
|
|
10
|
-
}
|
|
11
|
-
return t;
|
|
12
|
-
};
|
|
13
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
3
|
exports.convert = void 0;
|
|
15
4
|
const js_yaml_1 = require("js-yaml");
|
|
5
|
+
const first_version_1 = require("./first-version");
|
|
6
|
+
const second_version_1 = require("./second-version");
|
|
7
|
+
const third_version_1 = require("./third-version");
|
|
16
8
|
const utils_1 = require("./utils");
|
|
17
9
|
/**
|
|
18
10
|
* Value for key (version) represents the function which converts specification from previous version to the given as key.
|
|
19
11
|
*/
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
'1.1.0': from__1_0_0__to__1_1_0,
|
|
23
|
-
'1.2.0': from__1_1_0__to__1_2_0,
|
|
24
|
-
'2.0.0-rc1': from__1_2_0__to__2_0_0_rc1,
|
|
25
|
-
'2.0.0-rc2': from__2_0_0_rc1__to__2_0_0_rc2,
|
|
26
|
-
'2.0.0': from__2_0_0_rc2__to__2_0_0,
|
|
27
|
-
'2.1.0': from__2_0_0__to__2_1_0,
|
|
28
|
-
'2.2.0': from__2_1_0__to__2_2_0,
|
|
29
|
-
'2.3.0': from__2_2_0__to__2_3_0,
|
|
30
|
-
'2.4.0': from__2_3_0__to__2_4_0,
|
|
31
|
-
'2.5.0': from__2_4_0__to__2_5_0,
|
|
32
|
-
'2.6.0': from__2_5_0__to__2_6_0,
|
|
33
|
-
};
|
|
34
|
-
const conversionVersions = Object.keys(conversions);
|
|
12
|
+
const converters = Object.assign(Object.assign(Object.assign({}, first_version_1.converters), second_version_1.converters), third_version_1.converters);
|
|
13
|
+
const conversionVersions = Object.keys(converters);
|
|
35
14
|
function convert(asyncapi, version = '2.6.0', options = {}) {
|
|
36
15
|
const { format, document } = (0, utils_1.serializeInput)(asyncapi);
|
|
37
16
|
const asyncapiVersion = document.asyncapi;
|
|
@@ -50,7 +29,8 @@ function convert(asyncapi, version = '2.6.0', options = {}) {
|
|
|
50
29
|
fromVersion++;
|
|
51
30
|
let converted = document;
|
|
52
31
|
for (let i = fromVersion; i <= toVersion; i++) {
|
|
53
|
-
|
|
32
|
+
const v = conversionVersions[i];
|
|
33
|
+
converted = converters[v](converted, options);
|
|
54
34
|
}
|
|
55
35
|
if (format === 'yaml') {
|
|
56
36
|
return (0, js_yaml_1.dump)(converted, { skipInvalid: true });
|
|
@@ -58,145 +38,3 @@ function convert(asyncapi, version = '2.6.0', options = {}) {
|
|
|
58
38
|
return converted;
|
|
59
39
|
}
|
|
60
40
|
exports.convert = convert;
|
|
61
|
-
function from__undefined__to__1_0_0(asyncapi, _) {
|
|
62
|
-
asyncapi.asyncapi = '1.0.0';
|
|
63
|
-
return asyncapi;
|
|
64
|
-
}
|
|
65
|
-
function from__1_0_0__to__1_1_0(asyncapi, _) {
|
|
66
|
-
asyncapi.asyncapi = '1.1.0';
|
|
67
|
-
return asyncapi;
|
|
68
|
-
}
|
|
69
|
-
function from__1_1_0__to__1_2_0(asyncapi, _) {
|
|
70
|
-
asyncapi.asyncapi = '1.2.0';
|
|
71
|
-
return asyncapi;
|
|
72
|
-
}
|
|
73
|
-
function from__1_2_0__to__2_0_0_rc1(asyncapi, _) {
|
|
74
|
-
asyncapi.asyncapi = '2.0.0-rc1';
|
|
75
|
-
if (asyncapi.servers) {
|
|
76
|
-
const security = asyncapi.security;
|
|
77
|
-
asyncapi.servers = asyncapi.servers.map((server) => {
|
|
78
|
-
const { scheme, schemeVersion } = server, rest = __rest(server, ["scheme", "schemeVersion"]);
|
|
79
|
-
const out = Object.assign(Object.assign({}, rest), { protocol: scheme });
|
|
80
|
-
if (schemeVersion) {
|
|
81
|
-
out.protocolVersion = schemeVersion;
|
|
82
|
-
}
|
|
83
|
-
if (security) {
|
|
84
|
-
out.security = security;
|
|
85
|
-
}
|
|
86
|
-
return out;
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
if (asyncapi.topics) {
|
|
90
|
-
const baseTopic = asyncapi.baseTopic ? `${asyncapi.baseTopic}.` : "";
|
|
91
|
-
asyncapi.channels = Object.entries(asyncapi.topics).reduce((newChannels, [channelName, channel]) => {
|
|
92
|
-
if (channel.publish) {
|
|
93
|
-
channel.publish = { message: channel.publish };
|
|
94
|
-
}
|
|
95
|
-
if (channel.subscribe) {
|
|
96
|
-
channel.subscribe = { message: channel.subscribe };
|
|
97
|
-
}
|
|
98
|
-
channelName = (0, utils_1.dotsToSlashes)(`${baseTopic}${channelName}`);
|
|
99
|
-
newChannels[channelName] = channel;
|
|
100
|
-
return newChannels;
|
|
101
|
-
}, {});
|
|
102
|
-
}
|
|
103
|
-
else if (asyncapi.stream) {
|
|
104
|
-
asyncapi.channels = {
|
|
105
|
-
'/': (0, utils_1.streamToChannel)(asyncapi.stream),
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
else if (asyncapi.events) {
|
|
109
|
-
asyncapi.channels = {
|
|
110
|
-
'/': (0, utils_1.eventToChannel)(asyncapi.events),
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
delete asyncapi.topics;
|
|
114
|
-
delete asyncapi.stream;
|
|
115
|
-
delete asyncapi.events;
|
|
116
|
-
delete asyncapi.baseTopic;
|
|
117
|
-
delete asyncapi.security;
|
|
118
|
-
return asyncapi;
|
|
119
|
-
}
|
|
120
|
-
function from__2_0_0_rc1__to__2_0_0_rc2(asyncapi, _) {
|
|
121
|
-
asyncapi.asyncapi = '2.0.0-rc2';
|
|
122
|
-
if (asyncapi.servers) {
|
|
123
|
-
const serverMap = {};
|
|
124
|
-
asyncapi.servers.forEach((server, index) => {
|
|
125
|
-
if (server.baseChannel)
|
|
126
|
-
delete server.baseChannel;
|
|
127
|
-
const name = index === 0 ? 'default' : `server${index}`;
|
|
128
|
-
serverMap[name] = server;
|
|
129
|
-
});
|
|
130
|
-
asyncapi.servers = serverMap;
|
|
131
|
-
}
|
|
132
|
-
if (asyncapi.channels) {
|
|
133
|
-
Object.entries(asyncapi.channels).forEach(([channelName, channel]) => {
|
|
134
|
-
if (channel.parameters) {
|
|
135
|
-
const parametersMap = {};
|
|
136
|
-
const paramNames = channelName.match(/\{([^\}]{1,100})\}/g).map(p => p.substr(1, p.length - 2)); // NOSONAR
|
|
137
|
-
channel.parameters.forEach((parameter, index) => {
|
|
138
|
-
const name = parameter.name || paramNames[index];
|
|
139
|
-
if (parameter.name)
|
|
140
|
-
delete parameter.name;
|
|
141
|
-
parametersMap[name] = parameter;
|
|
142
|
-
});
|
|
143
|
-
channel.parameters = parametersMap;
|
|
144
|
-
}
|
|
145
|
-
if (channel.publish && channel.publish.message) {
|
|
146
|
-
const message = channel.publish.message;
|
|
147
|
-
(0, utils_1.convertMessage)(message);
|
|
148
|
-
}
|
|
149
|
-
if (channel.subscribe && channel.subscribe.message) {
|
|
150
|
-
const message = channel.subscribe.message;
|
|
151
|
-
(0, utils_1.convertMessage)(message);
|
|
152
|
-
}
|
|
153
|
-
if (channel.protocolInfo) {
|
|
154
|
-
channel.bindings = channel.protocolInfo;
|
|
155
|
-
delete channel.protocolInfo;
|
|
156
|
-
}
|
|
157
|
-
if (channel.publish && channel.publish.protocolInfo) {
|
|
158
|
-
channel.publish.bindings = channel.publish.protocolInfo;
|
|
159
|
-
delete channel.publish.protocolInfo;
|
|
160
|
-
}
|
|
161
|
-
if (channel.subscribe && channel.subscribe.protocolInfo) {
|
|
162
|
-
channel.subscribe.bindings = channel.subscribe.protocolInfo;
|
|
163
|
-
delete channel.subscribe.protocolInfo;
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
if (asyncapi.components && asyncapi.components.parameters) {
|
|
168
|
-
Object.values(asyncapi.components.parameters).forEach((parameter) => {
|
|
169
|
-
if (parameter.name)
|
|
170
|
-
delete parameter.name;
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
return asyncapi;
|
|
174
|
-
}
|
|
175
|
-
function from__2_0_0_rc2__to__2_0_0(asyncapi, _) {
|
|
176
|
-
asyncapi.asyncapi = '2.0.0';
|
|
177
|
-
return asyncapi;
|
|
178
|
-
}
|
|
179
|
-
function from__2_0_0__to__2_1_0(asyncapi, _) {
|
|
180
|
-
asyncapi.asyncapi = '2.1.0';
|
|
181
|
-
return asyncapi;
|
|
182
|
-
}
|
|
183
|
-
function from__2_1_0__to__2_2_0(asyncapi, _) {
|
|
184
|
-
asyncapi.asyncapi = '2.2.0';
|
|
185
|
-
return asyncapi;
|
|
186
|
-
}
|
|
187
|
-
function from__2_2_0__to__2_3_0(asyncapi, _) {
|
|
188
|
-
asyncapi.asyncapi = '2.3.0';
|
|
189
|
-
return asyncapi;
|
|
190
|
-
}
|
|
191
|
-
function from__2_3_0__to__2_4_0(asyncapi, _) {
|
|
192
|
-
asyncapi.asyncapi = '2.4.0';
|
|
193
|
-
return asyncapi;
|
|
194
|
-
}
|
|
195
|
-
function from__2_4_0__to__2_5_0(asyncapi, _) {
|
|
196
|
-
asyncapi.asyncapi = '2.5.0';
|
|
197
|
-
return asyncapi;
|
|
198
|
-
}
|
|
199
|
-
function from__2_5_0__to__2_6_0(asyncapi, _) {
|
|
200
|
-
asyncapi.asyncapi = '2.6.0';
|
|
201
|
-
return asyncapi;
|
|
202
|
-
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.converters = void 0;
|
|
4
|
+
exports.converters = {
|
|
5
|
+
'1.0.0': from__undefined__to__1_0_0,
|
|
6
|
+
'1.1.0': from__1_0_0__to__1_1_0,
|
|
7
|
+
'1.2.0': from__1_1_0__to__1_2_0,
|
|
8
|
+
};
|
|
9
|
+
function from__undefined__to__1_0_0(asyncapi, _) {
|
|
10
|
+
asyncapi.asyncapi = '1.0.0';
|
|
11
|
+
return asyncapi;
|
|
12
|
+
}
|
|
13
|
+
function from__1_0_0__to__1_1_0(asyncapi, _) {
|
|
14
|
+
asyncapi.asyncapi = '1.1.0';
|
|
15
|
+
return asyncapi;
|
|
16
|
+
}
|
|
17
|
+
function from__1_1_0__to__1_2_0(asyncapi, _) {
|
|
18
|
+
asyncapi.asyncapi = '1.2.0';
|
|
19
|
+
return asyncapi;
|
|
20
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { convert } from './convert';
|
|
2
|
-
export type { ConvertVersion, ConvertOptions } from './interfaces';
|
|
2
|
+
export type { AsyncAPIDocument, ConvertVersion, ConvertOptions } from './interfaces';
|
package/lib/interfaces.d.ts
CHANGED
|
@@ -1,6 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PUBLIC TYPES
|
|
3
|
+
*/
|
|
1
4
|
export declare type AsyncAPIDocument = {
|
|
2
5
|
asyncapi: string;
|
|
3
6
|
} & Record<string, any>;
|
|
4
|
-
export declare type ConvertVersion = '1.1.0' | '1.2.0' | '2.0.0-rc1' | '2.0.0-rc2' | '2.0.0' | '2.1.0' | '2.2.0' | '2.3.0' | '2.4.0' | '2.5.0' | '2.6.0';
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
+
export declare type ConvertVersion = '1.1.0' | '1.2.0' | '2.0.0-rc1' | '2.0.0-rc2' | '2.0.0' | '2.1.0' | '2.2.0' | '2.3.0' | '2.4.0' | '2.5.0' | '2.6.0' | '3.0.0';
|
|
8
|
+
export declare type ConvertV2ToV3Options = {
|
|
9
|
+
idGenerator?: (data: {
|
|
10
|
+
asyncapi: AsyncAPIDocument;
|
|
11
|
+
kind: 'channel' | 'operation' | 'message';
|
|
12
|
+
key: string | number | undefined;
|
|
13
|
+
path: Array<string | number>;
|
|
14
|
+
object: any;
|
|
15
|
+
parentId?: string;
|
|
16
|
+
}) => string;
|
|
17
|
+
pointOfView?: 'application' | 'client';
|
|
18
|
+
useChannelIdExtension?: boolean;
|
|
19
|
+
convertServerComponents?: boolean;
|
|
20
|
+
convertChannelComponents?: boolean;
|
|
21
|
+
};
|
|
22
|
+
export declare type ConvertOptions = {
|
|
23
|
+
v2tov3?: ConvertV2ToV3Options;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* PRIVATE TYPES
|
|
27
|
+
*/
|
|
28
|
+
export declare type ConvertFunction = (asyncapi: AsyncAPIDocument, options: ConvertOptions) => AsyncAPIDocument;
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.converters = void 0;
|
|
15
|
+
const utils_1 = require("./utils");
|
|
16
|
+
exports.converters = {
|
|
17
|
+
'2.0.0-rc1': from__1_2_0__to__2_0_0_rc1,
|
|
18
|
+
'2.0.0-rc2': from__2_0_0_rc1__to__2_0_0_rc2,
|
|
19
|
+
'2.0.0': from__2_0_0_rc2__to__2_0_0,
|
|
20
|
+
'2.1.0': from__2_0_0__to__2_1_0,
|
|
21
|
+
'2.2.0': from__2_1_0__to__2_2_0,
|
|
22
|
+
'2.3.0': from__2_2_0__to__2_3_0,
|
|
23
|
+
'2.4.0': from__2_3_0__to__2_4_0,
|
|
24
|
+
'2.5.0': from__2_4_0__to__2_5_0,
|
|
25
|
+
'2.6.0': from__2_5_0__to__2_6_0,
|
|
26
|
+
};
|
|
27
|
+
function from__1_2_0__to__2_0_0_rc1(asyncapi, _) {
|
|
28
|
+
asyncapi.asyncapi = '2.0.0-rc1';
|
|
29
|
+
if (asyncapi.servers) {
|
|
30
|
+
const security = asyncapi.security;
|
|
31
|
+
asyncapi.servers = asyncapi.servers.map((server) => {
|
|
32
|
+
const { scheme, schemeVersion } = server, rest = __rest(server, ["scheme", "schemeVersion"]);
|
|
33
|
+
const out = Object.assign(Object.assign({}, rest), { protocol: scheme });
|
|
34
|
+
if (schemeVersion) {
|
|
35
|
+
out.protocolVersion = schemeVersion;
|
|
36
|
+
}
|
|
37
|
+
if (security) {
|
|
38
|
+
out.security = security;
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
if (asyncapi.topics) {
|
|
44
|
+
const baseTopic = asyncapi.baseTopic ? `${asyncapi.baseTopic}.` : "";
|
|
45
|
+
asyncapi.channels = Object.entries(asyncapi.topics).reduce((newChannels, [channelName, channel]) => {
|
|
46
|
+
if (channel.publish) {
|
|
47
|
+
channel.publish = { message: channel.publish };
|
|
48
|
+
}
|
|
49
|
+
if (channel.subscribe) {
|
|
50
|
+
channel.subscribe = { message: channel.subscribe };
|
|
51
|
+
}
|
|
52
|
+
channelName = (0, utils_1.dotsToSlashes)(`${baseTopic}${channelName}`);
|
|
53
|
+
newChannels[channelName] = channel;
|
|
54
|
+
return newChannels;
|
|
55
|
+
}, {});
|
|
56
|
+
}
|
|
57
|
+
else if (asyncapi.stream) {
|
|
58
|
+
asyncapi.channels = {
|
|
59
|
+
'/': streamToChannel(asyncapi.stream),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
else if (asyncapi.events) {
|
|
63
|
+
asyncapi.channels = {
|
|
64
|
+
'/': eventToChannel(asyncapi.events),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
delete asyncapi.topics;
|
|
68
|
+
delete asyncapi.stream;
|
|
69
|
+
delete asyncapi.events;
|
|
70
|
+
delete asyncapi.baseTopic;
|
|
71
|
+
delete asyncapi.security;
|
|
72
|
+
return asyncapi;
|
|
73
|
+
}
|
|
74
|
+
function from__2_0_0_rc1__to__2_0_0_rc2(asyncapi, _) {
|
|
75
|
+
asyncapi.asyncapi = '2.0.0-rc2';
|
|
76
|
+
if (asyncapi.servers) {
|
|
77
|
+
const serverMap = {};
|
|
78
|
+
asyncapi.servers.forEach((server, index) => {
|
|
79
|
+
if (server.baseChannel)
|
|
80
|
+
delete server.baseChannel;
|
|
81
|
+
const name = index === 0 ? 'default' : `server${index}`;
|
|
82
|
+
serverMap[name] = server;
|
|
83
|
+
});
|
|
84
|
+
asyncapi.servers = serverMap;
|
|
85
|
+
}
|
|
86
|
+
if (asyncapi.channels) {
|
|
87
|
+
Object.entries(asyncapi.channels).forEach(([channelName, channel]) => {
|
|
88
|
+
if (channel.parameters) {
|
|
89
|
+
const parametersMap = {};
|
|
90
|
+
const paramNames = channelName.match(/\{([^\}]{1,100})\}/g).map(p => p.substr(1, p.length - 2)); // NOSONAR
|
|
91
|
+
channel.parameters.forEach((parameter, index) => {
|
|
92
|
+
const name = parameter.name || paramNames[index];
|
|
93
|
+
if (parameter.name)
|
|
94
|
+
delete parameter.name;
|
|
95
|
+
parametersMap[name] = parameter;
|
|
96
|
+
});
|
|
97
|
+
channel.parameters = parametersMap;
|
|
98
|
+
}
|
|
99
|
+
if (channel.publish && channel.publish.message) {
|
|
100
|
+
const message = channel.publish.message;
|
|
101
|
+
convertMessage(message);
|
|
102
|
+
}
|
|
103
|
+
if (channel.subscribe && channel.subscribe.message) {
|
|
104
|
+
const message = channel.subscribe.message;
|
|
105
|
+
convertMessage(message);
|
|
106
|
+
}
|
|
107
|
+
if (channel.protocolInfo) {
|
|
108
|
+
channel.bindings = channel.protocolInfo;
|
|
109
|
+
delete channel.protocolInfo;
|
|
110
|
+
}
|
|
111
|
+
if (channel.publish && channel.publish.protocolInfo) {
|
|
112
|
+
channel.publish.bindings = channel.publish.protocolInfo;
|
|
113
|
+
delete channel.publish.protocolInfo;
|
|
114
|
+
}
|
|
115
|
+
if (channel.subscribe && channel.subscribe.protocolInfo) {
|
|
116
|
+
channel.subscribe.bindings = channel.subscribe.protocolInfo;
|
|
117
|
+
delete channel.subscribe.protocolInfo;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (asyncapi.components && asyncapi.components.parameters) {
|
|
122
|
+
Object.values(asyncapi.components.parameters).forEach((parameter) => {
|
|
123
|
+
if (parameter.name)
|
|
124
|
+
delete parameter.name;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return asyncapi;
|
|
128
|
+
}
|
|
129
|
+
function from__2_0_0_rc2__to__2_0_0(asyncapi, _) {
|
|
130
|
+
asyncapi.asyncapi = '2.0.0';
|
|
131
|
+
return asyncapi;
|
|
132
|
+
}
|
|
133
|
+
function from__2_0_0__to__2_1_0(asyncapi, _) {
|
|
134
|
+
asyncapi.asyncapi = '2.1.0';
|
|
135
|
+
return asyncapi;
|
|
136
|
+
}
|
|
137
|
+
function from__2_1_0__to__2_2_0(asyncapi, _) {
|
|
138
|
+
asyncapi.asyncapi = '2.2.0';
|
|
139
|
+
return asyncapi;
|
|
140
|
+
}
|
|
141
|
+
function from__2_2_0__to__2_3_0(asyncapi, _) {
|
|
142
|
+
asyncapi.asyncapi = '2.3.0';
|
|
143
|
+
return asyncapi;
|
|
144
|
+
}
|
|
145
|
+
function from__2_3_0__to__2_4_0(asyncapi, _) {
|
|
146
|
+
asyncapi.asyncapi = '2.4.0';
|
|
147
|
+
return asyncapi;
|
|
148
|
+
}
|
|
149
|
+
function from__2_4_0__to__2_5_0(asyncapi, _) {
|
|
150
|
+
asyncapi.asyncapi = '2.5.0';
|
|
151
|
+
return asyncapi;
|
|
152
|
+
}
|
|
153
|
+
function from__2_5_0__to__2_6_0(asyncapi, _) {
|
|
154
|
+
asyncapi.asyncapi = '2.6.0';
|
|
155
|
+
return asyncapi;
|
|
156
|
+
}
|
|
157
|
+
function eventToChannel(event) {
|
|
158
|
+
const out = {};
|
|
159
|
+
if (event.receive) {
|
|
160
|
+
out.publish = {
|
|
161
|
+
message: {
|
|
162
|
+
oneOf: event.receive
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
if (event.send) {
|
|
167
|
+
out.subscribe = {
|
|
168
|
+
message: {
|
|
169
|
+
oneOf: event.send
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return out;
|
|
174
|
+
}
|
|
175
|
+
function streamToChannel(stream) {
|
|
176
|
+
const out = {};
|
|
177
|
+
if (stream.read) {
|
|
178
|
+
out.publish = {
|
|
179
|
+
message: {
|
|
180
|
+
oneOf: stream.read
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
if (stream.write) {
|
|
185
|
+
out.subscribe = {
|
|
186
|
+
message: {
|
|
187
|
+
oneOf: stream.write
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
return out;
|
|
192
|
+
}
|
|
193
|
+
function convertMessage(message) {
|
|
194
|
+
if (message.oneOf) {
|
|
195
|
+
message.oneOf.forEach((m) => {
|
|
196
|
+
if (m.protocolInfo) {
|
|
197
|
+
m.bindings = m.protocolInfo;
|
|
198
|
+
delete m.protocolInfo;
|
|
199
|
+
}
|
|
200
|
+
if (m.headers) {
|
|
201
|
+
m.headers = objectToSchema(m.headers);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
if (message.protocolInfo) {
|
|
207
|
+
message.bindings = message.protocolInfo;
|
|
208
|
+
delete message.protocolInfo;
|
|
209
|
+
}
|
|
210
|
+
if (message.headers) {
|
|
211
|
+
message.headers = objectToSchema(message.headers);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function objectToSchema(obj) {
|
|
216
|
+
return { type: 'object', properties: Object.assign({}, obj) };
|
|
217
|
+
}
|
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.converters = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
exports.converters = {
|
|
6
|
+
'3.0.0': from__2_6_0__to__3_0_0,
|
|
7
|
+
};
|
|
8
|
+
function from__2_6_0__to__3_0_0(asyncapi, options) {
|
|
9
|
+
var _a;
|
|
10
|
+
asyncapi.asyncapi = '3.0.0';
|
|
11
|
+
const v2tov3Options = Object.assign({ pointOfView: 'application', useChannelIdExtension: true, convertServerComponents: true, convertChannelComponents: true }, ((_a = options.v2tov3) !== null && _a !== void 0 ? _a : {}));
|
|
12
|
+
v2tov3Options.idGenerator = v2tov3Options.idGenerator || idGeneratorFactory(v2tov3Options);
|
|
13
|
+
const context = {
|
|
14
|
+
refs: new Map(),
|
|
15
|
+
};
|
|
16
|
+
convertInfoObject(asyncapi, context);
|
|
17
|
+
if ((0, utils_1.isPlainObject)(asyncapi.servers)) {
|
|
18
|
+
asyncapi.servers = convertServerObjects(asyncapi.servers, asyncapi);
|
|
19
|
+
}
|
|
20
|
+
if ((0, utils_1.isPlainObject)(asyncapi.channels)) {
|
|
21
|
+
asyncapi.channels = convertChannelObjects(asyncapi.channels, asyncapi, v2tov3Options, context);
|
|
22
|
+
}
|
|
23
|
+
convertComponents(asyncapi, v2tov3Options, context);
|
|
24
|
+
replaceDeepRefs(asyncapi, context.refs, '', asyncapi);
|
|
25
|
+
return (0, utils_1.sortObjectKeys)(asyncapi, ['asyncapi', 'id', 'info', 'defaultContentType', 'servers', 'channels', 'operations', 'components']);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Moving Tags and ExternalDocs to the Info Object.
|
|
29
|
+
*/
|
|
30
|
+
function convertInfoObject(asyncapi, context) {
|
|
31
|
+
if (asyncapi.tags) {
|
|
32
|
+
asyncapi.info.tags = asyncapi.tags;
|
|
33
|
+
context.refs.set((0, utils_1.createRefPath)('tags'), (0, utils_1.createRefPath)('info', 'tags'));
|
|
34
|
+
delete asyncapi.tags;
|
|
35
|
+
}
|
|
36
|
+
if (asyncapi.externalDocs) {
|
|
37
|
+
asyncapi.info.externalDocs = asyncapi.externalDocs;
|
|
38
|
+
context.refs.set((0, utils_1.createRefPath)('externalDocs'), (0, utils_1.createRefPath)('info', 'externalDocs'));
|
|
39
|
+
delete asyncapi.externalDocs;
|
|
40
|
+
}
|
|
41
|
+
asyncapi.info = (0, utils_1.sortObjectKeys)(asyncapi.info, ['title', 'version', 'description', 'termsOfService', 'contact', 'license', 'tags', 'externalDocs']);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Split `url` field to the `host` and `pathname` (optional) fields.
|
|
45
|
+
* Unify referencing mechanism in security field.
|
|
46
|
+
*/
|
|
47
|
+
function convertServerObjects(servers, asyncapi) {
|
|
48
|
+
const newServers = {};
|
|
49
|
+
Object.entries(servers).forEach(([serverName, server]) => {
|
|
50
|
+
if ((0, utils_1.isRefObject)(server)) {
|
|
51
|
+
newServers[serverName] = server;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const { host, pathname, protocol } = resolveServerUrl(server.url);
|
|
55
|
+
server.host = host;
|
|
56
|
+
if (pathname !== undefined) {
|
|
57
|
+
server.pathname = pathname;
|
|
58
|
+
}
|
|
59
|
+
// Dont overwrite anything
|
|
60
|
+
if (protocol !== undefined && server.protocol === undefined) {
|
|
61
|
+
server.protocol = protocol;
|
|
62
|
+
}
|
|
63
|
+
delete server.url;
|
|
64
|
+
if (server.security) {
|
|
65
|
+
server.security = convertSecurityObject(server.security, asyncapi);
|
|
66
|
+
}
|
|
67
|
+
newServers[serverName] = (0, utils_1.sortObjectKeys)(server, ['host', 'pathname', 'protocol', 'protocolVersion', 'title', 'summary', 'description', 'variables', 'security', 'tags', 'externalDocs', 'bindings']);
|
|
68
|
+
});
|
|
69
|
+
return newServers;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Convert operation part of channels into standalone operations
|
|
73
|
+
*/
|
|
74
|
+
function toStandaloneOperation(data) {
|
|
75
|
+
const { kind, channel, asyncapi, operations, context, inComponents, channelId, channelAddress, options, oldPath } = data;
|
|
76
|
+
let operation = channel[kind];
|
|
77
|
+
const operationPath = inComponents ? ['components', 'operations'] : ['operations'];
|
|
78
|
+
if ((0, utils_1.isPlainObject)(operation)) {
|
|
79
|
+
const { operationId, operation: newOperation, messages } = convertOperationObject({ asyncapi, kind, channel, channelId, oldChannelId: channelAddress, operation, inComponents }, options, context);
|
|
80
|
+
if (operation.security) {
|
|
81
|
+
newOperation.security = convertSecurityObject(operation.security, asyncapi);
|
|
82
|
+
}
|
|
83
|
+
operationPath.push(operationId);
|
|
84
|
+
context.refs.set((0, utils_1.createRefPath)(...oldPath, kind), (0, utils_1.createRefPath)(...operationPath));
|
|
85
|
+
operations[operationId] = newOperation;
|
|
86
|
+
delete channel[kind];
|
|
87
|
+
return messages !== null && messages !== void 0 ? messages : {};
|
|
88
|
+
}
|
|
89
|
+
return {};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Split Channel Objects to the Channel Objects and Operation Objects.
|
|
93
|
+
*/
|
|
94
|
+
function convertChannelObjects(channels, asyncapi, options, context, inComponents = false) {
|
|
95
|
+
const newChannels = {};
|
|
96
|
+
Object.entries(channels).forEach(([channelAddress, channel]) => {
|
|
97
|
+
const oldPath = inComponents ? ['components', 'channels', channelAddress] : ['channels', channelAddress];
|
|
98
|
+
const channelId = options.idGenerator({ asyncapi, kind: 'channel', key: channelAddress, path: oldPath, object: channel });
|
|
99
|
+
const newPath = inComponents ? ['components', 'channels', channelId] : ['channels', channelId];
|
|
100
|
+
context.refs.set((0, utils_1.createRefPath)(...oldPath), (0, utils_1.createRefPath)(...newPath));
|
|
101
|
+
if ((0, utils_1.isRefObject)(channel)) {
|
|
102
|
+
newChannels[channelId] = channel;
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// assign address
|
|
106
|
+
channel.address = channelAddress;
|
|
107
|
+
// change the Server names to the Refs
|
|
108
|
+
const servers = channel.servers;
|
|
109
|
+
if (Array.isArray(servers)) {
|
|
110
|
+
channel.servers = servers.map((serverName) => (0, utils_1.createRefObject)('servers', serverName));
|
|
111
|
+
}
|
|
112
|
+
const operations = {};
|
|
113
|
+
// serialize publish and subscribe Operation Objects to standalone object
|
|
114
|
+
const publishMessages = toStandaloneOperation({ kind: 'publish', channel, asyncapi, operations, context, inComponents, channelId, channelAddress, options, oldPath });
|
|
115
|
+
const subscribeMessages = toStandaloneOperation({ kind: 'subscribe', channel, asyncapi, operations, context, inComponents, channelId, channelAddress, options, oldPath });
|
|
116
|
+
if (publishMessages || subscribeMessages) {
|
|
117
|
+
const allOperationMessages = Object.assign(Object.assign({}, publishMessages), subscribeMessages);
|
|
118
|
+
channel.messages = convertMessages({
|
|
119
|
+
messages: allOperationMessages
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
setOperationsOnRoot({ operations, inComponents, asyncapi, oldPath });
|
|
123
|
+
newChannels[channelId] = (0, utils_1.sortObjectKeys)(channel, ['address', 'messages', 'title', 'summary', 'description', 'servers', 'parameters', 'tags', 'externalDocs', 'bindings']);
|
|
124
|
+
});
|
|
125
|
+
return newChannels;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Assign the operations to the root AsyncAPI object.
|
|
129
|
+
*/
|
|
130
|
+
function setOperationsOnRoot(data) {
|
|
131
|
+
var _a, _b, _c, _d, _e;
|
|
132
|
+
const { operations, inComponents, asyncapi, oldPath } = data;
|
|
133
|
+
if (Object.keys(operations)) {
|
|
134
|
+
if (inComponents) {
|
|
135
|
+
const components = asyncapi.components = (_a = asyncapi.components) !== null && _a !== void 0 ? _a : {};
|
|
136
|
+
components.operations = Object.assign(Object.assign({}, (_b = components.operations) !== null && _b !== void 0 ? _b : {}), operations);
|
|
137
|
+
// if given component is used in the `channels` object then create references for operations in the `operations` object
|
|
138
|
+
if (channelIsUsed((_c = asyncapi.channels) !== null && _c !== void 0 ? _c : {}, oldPath)) {
|
|
139
|
+
const referencedOperations = Object.keys(operations).reduce((acc, current) => {
|
|
140
|
+
acc[current] = (0, utils_1.createRefObject)('components', 'operations', current);
|
|
141
|
+
return acc;
|
|
142
|
+
}, {});
|
|
143
|
+
asyncapi.operations = Object.assign(Object.assign({}, (_d = asyncapi.operations) !== null && _d !== void 0 ? _d : {}), referencedOperations);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
asyncapi.operations = Object.assign(Object.assign({}, (_e = asyncapi.operations) !== null && _e !== void 0 ? _e : {}), operations);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Points to the connected channel and split messages for channel
|
|
153
|
+
*/
|
|
154
|
+
function convertOperationObject(data, options, context) {
|
|
155
|
+
const { asyncapi, channelId, oldChannelId, kind, inComponents } = data;
|
|
156
|
+
const operation = Object.assign({}, data.operation);
|
|
157
|
+
const oldChannelPath = ['channels', oldChannelId];
|
|
158
|
+
if (inComponents) {
|
|
159
|
+
oldChannelPath.unshift('components');
|
|
160
|
+
}
|
|
161
|
+
const newChannelPath = ['channels', channelId];
|
|
162
|
+
if (inComponents) {
|
|
163
|
+
newChannelPath.unshift('components');
|
|
164
|
+
}
|
|
165
|
+
const operationId = options.idGenerator({ asyncapi, kind: 'operation', key: kind, path: oldChannelPath, object: data.operation, parentId: channelId });
|
|
166
|
+
operation.channel = (0, utils_1.createRefObject)(...newChannelPath);
|
|
167
|
+
try {
|
|
168
|
+
delete operation.operationId;
|
|
169
|
+
}
|
|
170
|
+
catch (err) { }
|
|
171
|
+
const isPublish = kind === 'publish';
|
|
172
|
+
if (options.pointOfView === 'application') {
|
|
173
|
+
operation.action = isPublish ? 'receive' : 'send';
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
operation.action = isPublish ? 'send' : 'receive';
|
|
177
|
+
}
|
|
178
|
+
const message = operation.message;
|
|
179
|
+
let serializedMessages = {};
|
|
180
|
+
if (message) {
|
|
181
|
+
delete operation.message;
|
|
182
|
+
const oldMessagePath = ['channels', oldChannelId, kind, 'message'];
|
|
183
|
+
const newMessagePath = ['channels', channelId, 'messages'];
|
|
184
|
+
if (inComponents) {
|
|
185
|
+
oldMessagePath.unshift('components');
|
|
186
|
+
newMessagePath.unshift('components');
|
|
187
|
+
}
|
|
188
|
+
serializedMessages = moveMessagesFromOperation(message, newMessagePath, oldMessagePath, asyncapi, options, context, operationId);
|
|
189
|
+
applyMessageRefsToOperation(serializedMessages, newMessagePath, operation);
|
|
190
|
+
}
|
|
191
|
+
const sortedOperation = (0, utils_1.sortObjectKeys)(operation, ['action', 'channel', 'title', 'summary', 'description', 'security', 'tags', 'externalDocs', 'bindings', 'traits']);
|
|
192
|
+
return { operationId, operation: sortedOperation, messages: serializedMessages };
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Remove all messages under operations and return an object of them.
|
|
196
|
+
*/
|
|
197
|
+
function moveMessagesFromOperation(message, newMessagePath, oldMessagePath, asyncapi, options, context, operationId) {
|
|
198
|
+
if (Array.isArray(message.oneOf)) {
|
|
199
|
+
//Message oneOf no longer exists, it's implicit by having multiple entires in the message object.
|
|
200
|
+
return message.oneOf.reduce((acc, current, index) => {
|
|
201
|
+
const messagePath = [...oldMessagePath, 'oneOf', index];
|
|
202
|
+
const messageId = options.idGenerator({ asyncapi, kind: 'message', key: index, path: messagePath, object: current, parentId: operationId });
|
|
203
|
+
context.refs.set((0, utils_1.createRefPath)(...messagePath), (0, utils_1.createRefPath)(...newMessagePath, messageId));
|
|
204
|
+
acc[messageId] = current;
|
|
205
|
+
return acc;
|
|
206
|
+
}, {});
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
const messageId = options.idGenerator({ asyncapi, kind: 'message', key: 'message', path: oldMessagePath, object: message, parentId: operationId });
|
|
210
|
+
context.refs.set((0, utils_1.createRefPath)(...oldMessagePath), (0, utils_1.createRefPath)(...newMessagePath, messageId));
|
|
211
|
+
return { [messageId]: message };
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Add references of messages to operations.
|
|
216
|
+
*/
|
|
217
|
+
function applyMessageRefsToOperation(serializedMessages, newMessagePath, operation) {
|
|
218
|
+
if (Object.keys(serializedMessages !== null && serializedMessages !== void 0 ? serializedMessages : {}).length > 0) {
|
|
219
|
+
const newOperationMessages = [];
|
|
220
|
+
Object.entries(serializedMessages).forEach(([messageId, messageValue]) => {
|
|
221
|
+
if ((0, utils_1.isRefObject)(messageValue)) {
|
|
222
|
+
// shallow copy of JS reference
|
|
223
|
+
newOperationMessages.push(Object.assign({}, messageValue));
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
const messagePath = [...newMessagePath, messageId];
|
|
227
|
+
newOperationMessages.push((0, utils_1.createRefObject)(...messagePath));
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
operation.messages = newOperationMessages;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Convert messages that use custom schema format into schema union.
|
|
235
|
+
*/
|
|
236
|
+
function convertMessages(data) {
|
|
237
|
+
const messages = Object.assign({}, data.messages);
|
|
238
|
+
// Convert schema formats to union schemas
|
|
239
|
+
Object.entries(messages).forEach(([_, message]) => {
|
|
240
|
+
if (message.schemaFormat !== undefined) {
|
|
241
|
+
const payloadSchema = message.payload;
|
|
242
|
+
message.payload = {
|
|
243
|
+
schemaFormat: message.schemaFormat,
|
|
244
|
+
schema: payloadSchema
|
|
245
|
+
};
|
|
246
|
+
delete message.schemaFormat;
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
return messages;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Convert `channels`, `servers` and `securitySchemes` in components.
|
|
253
|
+
*/
|
|
254
|
+
function convertComponents(asyncapi, options, context) {
|
|
255
|
+
const components = asyncapi.components;
|
|
256
|
+
if (!(0, utils_1.isPlainObject)(components)) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (options.convertServerComponents && (0, utils_1.isPlainObject)(components.servers)) {
|
|
260
|
+
components.servers = convertServerObjects(components.servers, asyncapi);
|
|
261
|
+
}
|
|
262
|
+
if (options.convertChannelComponents && (0, utils_1.isPlainObject)(components.channels)) {
|
|
263
|
+
components.channels = convertChannelObjects(components.channels, asyncapi, options, context, true);
|
|
264
|
+
}
|
|
265
|
+
if ((0, utils_1.isPlainObject)(components.securitySchemes)) {
|
|
266
|
+
components.securitySchemes = convertSecuritySchemes(components.securitySchemes);
|
|
267
|
+
}
|
|
268
|
+
if ((0, utils_1.isPlainObject)(components.messages)) {
|
|
269
|
+
components.messages = convertMessages({
|
|
270
|
+
messages: components.messages
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Convert `channels`, `servers` and `securitySchemes` in components.
|
|
276
|
+
*/
|
|
277
|
+
function convertSecuritySchemes(securitySchemes) {
|
|
278
|
+
const newSecuritySchemes = {};
|
|
279
|
+
Object.entries(securitySchemes).forEach(([name, scheme]) => {
|
|
280
|
+
newSecuritySchemes[name] = convertSecuritySchemeObject(scheme);
|
|
281
|
+
});
|
|
282
|
+
return newSecuritySchemes;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Unify referencing mechanism in security field
|
|
286
|
+
*/
|
|
287
|
+
function convertSecurityObject(security, asyncapi) {
|
|
288
|
+
const newSecurity = [];
|
|
289
|
+
security.forEach(securityItem => {
|
|
290
|
+
Object.entries(securityItem).forEach(([securityName, scopes]) => {
|
|
291
|
+
// without scopes - use ref
|
|
292
|
+
if (!scopes.length) {
|
|
293
|
+
newSecurity.push((0, utils_1.createRefObject)('components', 'securitySchemes', securityName));
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
// create new security scheme in the components/securitySchemes with appropriate scopes
|
|
297
|
+
const securityScheme = (0, utils_1.getValueByPath)(asyncapi, ['components', 'securitySchemes', securityName]);
|
|
298
|
+
// handle logic only on `oauth2` and `openIdConnect` security mechanism
|
|
299
|
+
if (securityScheme.type === 'oauth2' || securityScheme.type === 'openIdConnect') {
|
|
300
|
+
const newSecurityScheme = convertSecuritySchemeObject(securityScheme);
|
|
301
|
+
newSecurity.push(Object.assign(Object.assign({}, newSecurityScheme), { scopes: [...scopes] }));
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
return newSecurity;
|
|
306
|
+
}
|
|
307
|
+
const flowKinds = ['implicit', 'password', 'clientCredentials', 'authorizationCode'];
|
|
308
|
+
/**
|
|
309
|
+
* Convert security scheme object to new from v3 version (flow.[x].scopes -> flow.[x].availableScopes).
|
|
310
|
+
*/
|
|
311
|
+
function convertSecuritySchemeObject(original) {
|
|
312
|
+
const securityScheme = JSON.parse(JSON.stringify(original));
|
|
313
|
+
if (securityScheme.flows) {
|
|
314
|
+
flowKinds.forEach(flow => {
|
|
315
|
+
const flowScheme = securityScheme.flows[flow];
|
|
316
|
+
if (flowScheme === null || flowScheme === void 0 ? void 0 : flowScheme.scopes) {
|
|
317
|
+
flowScheme.availableScopes = flowScheme.scopes;
|
|
318
|
+
delete flowScheme.scopes;
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
return securityScheme;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Split `url` to the `host` and `pathname` (optional) fields.
|
|
326
|
+
*
|
|
327
|
+
* This function takes care of https://github.com/asyncapi/spec/pull/888
|
|
328
|
+
*/
|
|
329
|
+
function resolveServerUrl(url) {
|
|
330
|
+
let [maybeProtocol, maybeHost] = url.split('://');
|
|
331
|
+
if (!maybeHost) {
|
|
332
|
+
maybeHost = maybeProtocol;
|
|
333
|
+
}
|
|
334
|
+
const [host, ...pathnames] = maybeHost.split('/');
|
|
335
|
+
if (pathnames.length) {
|
|
336
|
+
return { host, pathname: `/${pathnames.join('/')}`, protocol: maybeProtocol };
|
|
337
|
+
}
|
|
338
|
+
return { host, pathname: undefined, protocol: maybeProtocol };
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Check if given channel (based on path) is used in the `channels` object.
|
|
342
|
+
*/
|
|
343
|
+
function channelIsUsed(channels, path) {
|
|
344
|
+
for (const channel of Object.values(channels)) {
|
|
345
|
+
if ((0, utils_1.isRefObject)(channel) && (0, utils_1.createRefPath)(...path) === channel.$ref) {
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Replace all deep local references with the new beginning of ref (when object is moved to another place).
|
|
353
|
+
*/
|
|
354
|
+
function replaceDeepRefs(value, refs, key, parent) {
|
|
355
|
+
if (key === '$ref' && typeof value === 'string') {
|
|
356
|
+
const newRef = replaceRef(value, refs);
|
|
357
|
+
if (typeof newRef === 'string') {
|
|
358
|
+
parent[key] = newRef;
|
|
359
|
+
}
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
if (Array.isArray(value)) {
|
|
363
|
+
return value.forEach((item, idx) => replaceDeepRefs(item, refs, idx, value));
|
|
364
|
+
}
|
|
365
|
+
if (value && typeof value === 'object') {
|
|
366
|
+
for (const objKey in value) {
|
|
367
|
+
replaceDeepRefs(value[objKey], refs, objKey, value);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
function replaceRef(ref, refs) {
|
|
372
|
+
const allowed = [];
|
|
373
|
+
refs.forEach((_, key) => {
|
|
374
|
+
// few refs can be allowed
|
|
375
|
+
if (ref.startsWith(key)) {
|
|
376
|
+
allowed.push(key);
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
// find the longest one
|
|
380
|
+
allowed.sort((a, b) => a.length - b.length);
|
|
381
|
+
const from = allowed.pop();
|
|
382
|
+
if (!from) {
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
const toReplace = refs.get(from);
|
|
386
|
+
if (toReplace) {
|
|
387
|
+
return ref.replace(from, toReplace);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Default function to generate ids for objects.
|
|
392
|
+
*/
|
|
393
|
+
function idGeneratorFactory(options) {
|
|
394
|
+
const useChannelIdExtension = options.useChannelIdExtension;
|
|
395
|
+
return (data) => {
|
|
396
|
+
const { asyncapi, kind, object, key, parentId } = data;
|
|
397
|
+
switch (kind) {
|
|
398
|
+
case 'channel':
|
|
399
|
+
return generateIdForChannel(object, key, useChannelIdExtension);
|
|
400
|
+
case 'operation':
|
|
401
|
+
{
|
|
402
|
+
const oldOperationId = object.operationId;
|
|
403
|
+
const operationId = oldOperationId || (parentId ? `${parentId}.${key}` : kind);
|
|
404
|
+
return operationId;
|
|
405
|
+
}
|
|
406
|
+
;
|
|
407
|
+
case 'message':
|
|
408
|
+
return generateIdForMessage(object, asyncapi, parentId, key);
|
|
409
|
+
default: return '';
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
function generateIdForChannel(object, key, useChannelIdExtension) {
|
|
414
|
+
if ((0, utils_1.isRefObject)(object)) {
|
|
415
|
+
const id = key;
|
|
416
|
+
return id;
|
|
417
|
+
}
|
|
418
|
+
const channel = object;
|
|
419
|
+
let channelId;
|
|
420
|
+
if (useChannelIdExtension) {
|
|
421
|
+
channelId = channel['x-channelId'] || key;
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
channelId = key;
|
|
425
|
+
}
|
|
426
|
+
return channelId;
|
|
427
|
+
}
|
|
428
|
+
function generateIdForMessage(object, asyncapi, parentId, key) {
|
|
429
|
+
if ((0, utils_1.isRefObject)(object)) {
|
|
430
|
+
const possibleMessage = (0, utils_1.getValueByRef)(asyncapi, object.$ref);
|
|
431
|
+
if (possibleMessage === null || possibleMessage === void 0 ? void 0 : possibleMessage.messageId) {
|
|
432
|
+
const messageId = possibleMessage.messageId;
|
|
433
|
+
return messageId;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
const messageId = object.messageId;
|
|
437
|
+
if (messageId) {
|
|
438
|
+
return messageId;
|
|
439
|
+
}
|
|
440
|
+
let operationKind;
|
|
441
|
+
const splitParentId = parentId.split('.');
|
|
442
|
+
if (splitParentId.length === 1) {
|
|
443
|
+
operationKind = parentId;
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
operationKind = splitParentId.pop();
|
|
447
|
+
}
|
|
448
|
+
if (typeof key === 'number') {
|
|
449
|
+
return `${operationKind}.message.${key}`;
|
|
450
|
+
}
|
|
451
|
+
return `${operationKind}.message`;
|
|
452
|
+
}
|
package/lib/utils.d.ts
CHANGED
|
@@ -3,14 +3,6 @@ export declare function serializeInput(document: string | AsyncAPIDocument): {
|
|
|
3
3
|
format: 'json' | 'yaml';
|
|
4
4
|
document: AsyncAPIDocument;
|
|
5
5
|
} | never;
|
|
6
|
-
export declare function eventToChannel(event: any): {
|
|
7
|
-
publish: any;
|
|
8
|
-
subscribe: any;
|
|
9
|
-
};
|
|
10
|
-
export declare function streamToChannel(stream: any): {
|
|
11
|
-
publish: any;
|
|
12
|
-
subscribe: any;
|
|
13
|
-
};
|
|
14
6
|
export declare function objectToSchema(obj: Record<string, unknown>): {
|
|
15
7
|
type: string;
|
|
16
8
|
properties: {
|
|
@@ -18,4 +10,12 @@ export declare function objectToSchema(obj: Record<string, unknown>): {
|
|
|
18
10
|
};
|
|
19
11
|
};
|
|
20
12
|
export declare function dotsToSlashes(topic: string): string;
|
|
21
|
-
export declare function
|
|
13
|
+
export declare function isPlainObject(value: unknown): boolean;
|
|
14
|
+
export declare function createRefObject(...paths: Array<string | number>): {
|
|
15
|
+
$ref: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function createRefPath(...paths: Array<string | number>): string;
|
|
18
|
+
export declare function isRefObject(value: unknown): boolean;
|
|
19
|
+
export declare function getValueByRef(root: any, ref: string): any;
|
|
20
|
+
export declare function getValueByPath(value: any, path: string[]): any;
|
|
21
|
+
export declare function sortObjectKeys(obj: any, keys: string[]): any;
|
package/lib/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.sortObjectKeys = exports.getValueByPath = exports.getValueByRef = exports.isRefObject = exports.createRefPath = exports.createRefObject = exports.isPlainObject = exports.dotsToSlashes = exports.objectToSchema = exports.serializeInput = void 0;
|
|
4
4
|
const js_yaml_1 = require("js-yaml");
|
|
5
5
|
function serializeInput(document) {
|
|
6
6
|
let triedConvertToYaml = false;
|
|
@@ -43,44 +43,6 @@ function serializeInput(document) {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
exports.serializeInput = serializeInput;
|
|
46
|
-
function eventToChannel(event) {
|
|
47
|
-
const out = {};
|
|
48
|
-
if (event.receive) {
|
|
49
|
-
out.publish = {
|
|
50
|
-
message: {
|
|
51
|
-
oneOf: event.receive
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
if (event.send) {
|
|
56
|
-
out.subscribe = {
|
|
57
|
-
message: {
|
|
58
|
-
oneOf: event.send
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
return out;
|
|
63
|
-
}
|
|
64
|
-
exports.eventToChannel = eventToChannel;
|
|
65
|
-
function streamToChannel(stream) {
|
|
66
|
-
const out = {};
|
|
67
|
-
if (stream.read) {
|
|
68
|
-
out.publish = {
|
|
69
|
-
message: {
|
|
70
|
-
oneOf: stream.read
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
if (stream.write) {
|
|
75
|
-
out.subscribe = {
|
|
76
|
-
message: {
|
|
77
|
-
oneOf: stream.write
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
return out;
|
|
82
|
-
}
|
|
83
|
-
exports.streamToChannel = streamToChannel;
|
|
84
46
|
function objectToSchema(obj) {
|
|
85
47
|
return { type: 'object', properties: Object.assign({}, obj) };
|
|
86
48
|
}
|
|
@@ -89,26 +51,76 @@ function dotsToSlashes(topic) {
|
|
|
89
51
|
return topic.replace(/\./g, '/');
|
|
90
52
|
}
|
|
91
53
|
exports.dotsToSlashes = dotsToSlashes;
|
|
92
|
-
function
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
54
|
+
function isPlainObject(value) {
|
|
55
|
+
return Boolean(value && typeof value === 'object' && !Array.isArray(value));
|
|
56
|
+
}
|
|
57
|
+
exports.isPlainObject = isPlainObject;
|
|
58
|
+
function createRefObject(...paths) {
|
|
59
|
+
return {
|
|
60
|
+
$ref: createRefPath(...paths),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
exports.createRefObject = createRefObject;
|
|
64
|
+
function createRefPath(...paths) {
|
|
65
|
+
return `#/${paths.map(String).map(tilde).join('/')}`;
|
|
66
|
+
}
|
|
67
|
+
exports.createRefPath = createRefPath;
|
|
68
|
+
function isRefObject(value) {
|
|
69
|
+
return Boolean(value && '$ref' in value);
|
|
70
|
+
}
|
|
71
|
+
exports.isRefObject = isRefObject;
|
|
72
|
+
function getValueByRef(root, ref) {
|
|
73
|
+
if (!ref.startsWith('#')) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
// remove `#/` at start, split string by `/` and untilde (change ~1 to / etc)
|
|
77
|
+
const path = ref.substring(2).split('/').map(untilde);
|
|
78
|
+
return getValueByPath(root, path);
|
|
79
|
+
}
|
|
80
|
+
exports.getValueByRef = getValueByRef;
|
|
81
|
+
function getValueByPath(value, path) {
|
|
82
|
+
let index = 0;
|
|
83
|
+
const length = path.length;
|
|
84
|
+
while (value != null && index < length) {
|
|
85
|
+
value = value[path[index++]];
|
|
103
86
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
87
|
+
return index == length ? value : undefined;
|
|
88
|
+
}
|
|
89
|
+
exports.getValueByPath = getValueByPath;
|
|
90
|
+
function sortObjectKeys(obj, keys) {
|
|
91
|
+
const newObject = {};
|
|
92
|
+
// add sorted keys
|
|
93
|
+
keys.forEach(key => {
|
|
94
|
+
if (key in obj) {
|
|
95
|
+
newObject[key] = obj[key];
|
|
108
96
|
}
|
|
109
|
-
|
|
110
|
-
|
|
97
|
+
});
|
|
98
|
+
// add rest of keys
|
|
99
|
+
Object.keys(obj).forEach(key => {
|
|
100
|
+
if (!keys.includes(key)) {
|
|
101
|
+
newObject[key] = obj[key];
|
|
111
102
|
}
|
|
112
|
-
}
|
|
103
|
+
});
|
|
104
|
+
return newObject;
|
|
105
|
+
}
|
|
106
|
+
exports.sortObjectKeys = sortObjectKeys;
|
|
107
|
+
function tilde(str) {
|
|
108
|
+
return str.replace(/[~/]{1}/g, (sub) => {
|
|
109
|
+
switch (sub) {
|
|
110
|
+
case '/': return '~1';
|
|
111
|
+
case '~': return '~0';
|
|
112
|
+
}
|
|
113
|
+
return sub;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
function untilde(str) {
|
|
117
|
+
if (!str.includes('~'))
|
|
118
|
+
return str;
|
|
119
|
+
return str.replace(/~[01]/g, (sub) => {
|
|
120
|
+
switch (sub) {
|
|
121
|
+
case '~1': return '/';
|
|
122
|
+
case '~0': return '~';
|
|
123
|
+
}
|
|
124
|
+
return sub;
|
|
125
|
+
});
|
|
113
126
|
}
|
|
114
|
-
exports.convertMessage = convertMessage;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@asyncapi/converter",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Convert AsyncAPI documents from older to newer versions.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
"build": "tsc",
|
|
9
9
|
"test": "cross-env CI=true NODE_ENV=test jest --coverage",
|
|
10
10
|
"lint": "echo 'no linter configured yet'",
|
|
11
|
-
"release": "semantic-release",
|
|
12
11
|
"generate:assets": "npm run generate:readme:toc",
|
|
13
12
|
"generate:readme:toc": "markdown-toc -i README.md",
|
|
14
13
|
"bump:version": "npm --no-git-tag-version --allow-same-version version $VERSION",
|
|
@@ -39,44 +38,19 @@
|
|
|
39
38
|
"author": "Fran Mendez <fmvilas@gmail.com> (fmvilas.com)",
|
|
40
39
|
"license": "Apache-2.0",
|
|
41
40
|
"dependencies": {
|
|
41
|
+
"@asyncapi/parser": "^2.0.0-next-major.11",
|
|
42
42
|
"js-yaml": "^3.14.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@jest/types": "^27.5.1",
|
|
46
|
-
"@semantic-release/commit-analyzer": "^9.0.2",
|
|
47
|
-
"@semantic-release/github": "^8.0.2",
|
|
48
|
-
"@semantic-release/npm": "^8.0.3",
|
|
49
|
-
"@semantic-release/release-notes-generator": "^10.0.3",
|
|
50
46
|
"@types/jest": "^27.4.1",
|
|
51
47
|
"@types/js-yaml": "^4.0.5",
|
|
52
|
-
"conventional-changelog-conventionalcommits": "^
|
|
48
|
+
"conventional-changelog-conventionalcommits": "^5.0.0",
|
|
53
49
|
"cross-env": "^7.0.3",
|
|
54
50
|
"jest": "^27.5.1",
|
|
55
|
-
"
|
|
51
|
+
"markdown-toc": "^1.2.0",
|
|
56
52
|
"ts-jest": "^27.1.3",
|
|
57
53
|
"ts-node": "^10.7.0",
|
|
58
|
-
"typescript": "^4.6.2"
|
|
59
|
-
"markdown-toc": "^1.2.0"
|
|
60
|
-
},
|
|
61
|
-
"release": {
|
|
62
|
-
"branches": [
|
|
63
|
-
"master"
|
|
64
|
-
],
|
|
65
|
-
"plugins": [
|
|
66
|
-
[
|
|
67
|
-
"@semantic-release/commit-analyzer",
|
|
68
|
-
{
|
|
69
|
-
"preset": "conventionalcommits"
|
|
70
|
-
}
|
|
71
|
-
],
|
|
72
|
-
[
|
|
73
|
-
"@semantic-release/release-notes-generator",
|
|
74
|
-
{
|
|
75
|
-
"preset": "conventionalcommits"
|
|
76
|
-
}
|
|
77
|
-
],
|
|
78
|
-
"@semantic-release/npm",
|
|
79
|
-
"@semantic-release/github"
|
|
80
|
-
]
|
|
54
|
+
"typescript": "^4.6.2"
|
|
81
55
|
}
|
|
82
56
|
}
|