Skip to content

Commit 993c603

Browse files
refactor: add tests for old api (asyncapi#622)
1 parent 571fac9 commit 993c603

38 files changed

+4172
-92
lines changed

src/custom-operations/anonymous-naming.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function assignNameToComponentMessages(document: AsyncAPIDocumentInterface) {
2828
function assignNameToAnonymousMessages(document: AsyncAPIDocumentInterface) {
2929
let anonymousMessageCounter = 0;
3030
document.messages().forEach(message => {
31-
if (message.name() === undefined && message.extensions().get(xParserMessageName) === undefined) {
31+
if (message.name() === undefined && message.extensions().get(xParserMessageName)?.value() === undefined) {
3232
setExtension(xParserMessageName, `<anonymous-message-${++anonymousMessageCounter}>`, message);
3333
}
3434
});

src/iterator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export enum SchemaTypesToIterate {
3939

4040
export type TraverseOptions = {
4141
callback: TraverseCallback
42-
schemaTypesToIterate: SchemaTypesToIterate[]
42+
schemaTypesToIterate: Array<`${SchemaTypesToIterate}`>;
4343
seenSchemas: Set<any>
4444
}
4545

@@ -48,7 +48,7 @@ export type TraverseCallback = (schema: SchemaInterface, propOrIndex: string | n
4848
/**
4949
* Go through each channel and for each parameter, and message payload and headers recursively call the callback for each schema.
5050
*/
51-
export function traverseAsyncApiDocument(doc: AsyncAPIDocumentInterface, callback: TraverseCallback, schemaTypesToIterate: SchemaTypesToIterate[] = []) {
51+
export function traverseAsyncApiDocument(doc: AsyncAPIDocumentInterface, callback: TraverseCallback, schemaTypesToIterate: Array<`${SchemaTypesToIterate}`> = []) {
5252
if (schemaTypesToIterate.length === 0) {
5353
schemaTypesToIterate = Object.values(SchemaTypesToIterate);
5454
}

src/models/v2/asyncapi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export class AsyncAPIDocument extends BaseModel<v2.AsyncAPIObject> implements As
8888
}
8989

9090
components(): ComponentsInterface {
91-
return new Components(this._json.components || {});
91+
return this.createModel(Components, this._json.components || {}, { pointer: '/components' });
9292
}
9393

9494
extensions(): ExtensionsInterface {

src/old-api/asyncapi.ts

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import { Message } from './message';
77
import { Schema } from './schema';
88

99
import { traverseAsyncApiDocument } from './iterator';
10-
import { xParserCircular } from '../constants';
11-
import { stringify, unstringify } from '../stringify';
10+
import { xParserCircular, xParserSpecStringified, xParserSpecParsed } from '../constants';
11+
import { refReplacer, traverseStringifiedData } from '../stringify';
1212

1313
import type { v2 } from '../spec-types';
1414
import type { Operation } from './operation';
@@ -154,16 +154,41 @@ export class AsyncAPIDocument extends SpecificationExtensionsModel<v2.AsyncAPIOb
154154
return !!this._json[xParserCircular];
155155
}
156156

157-
traverseSchemas(callback: TraverseCallback, schemaTypesToIterate: SchemaTypesToIterate[]) {
157+
traverseSchemas(callback: TraverseCallback, schemaTypesToIterate: Array<`${SchemaTypesToIterate}`> = []) {
158158
traverseAsyncApiDocument(this, callback, schemaTypesToIterate);
159159
}
160160

161-
static stringify(doc: AsyncAPIDocument, space: number): string | undefined {
162-
return stringify(doc, { space });
161+
static stringify(doc: AsyncAPIDocument, space?: number): string | undefined {
162+
const rawDoc = doc.json();
163+
const copiedDoc = { ...rawDoc };
164+
copiedDoc[xParserSpecStringified] = true;
165+
return JSON.stringify(copiedDoc, refReplacer(), space);
163166
}
164167

165-
static parse(doc: string): AsyncAPIDocument | undefined {
166-
const possibleDocument = unstringify(doc);
167-
return possibleDocument ? new AsyncAPIDocument(possibleDocument.json()) : undefined;
168+
static parse(doc: string | Record<string, any>): AsyncAPIDocument | undefined {
169+
let parsedJSON = doc;
170+
if (typeof doc === 'string') {
171+
parsedJSON = JSON.parse(doc);
172+
} else if (typeof doc === 'object') {
173+
// shall copy
174+
parsedJSON = { ...(parsedJSON as Record<string, any>) };
175+
}
176+
177+
// the `doc` must be an AsyncAPI parsed document
178+
if (typeof parsedJSON !== 'object' || !parsedJSON[xParserSpecParsed]) {
179+
throw new Error('Cannot parse invalid AsyncAPI document');
180+
}
181+
// if the `doc` is not stringified via the `stringify` static method then immediately return a model.
182+
if (!parsedJSON[xParserSpecStringified]) {
183+
return new AsyncAPIDocument(parsedJSON as v2.AsyncAPIObject);
184+
}
185+
// remove `x-parser-spec-stringified` extension
186+
delete parsedJSON[String(xParserSpecStringified)];
187+
188+
const objToPath = new Map();
189+
const pathToObj = new Map();
190+
traverseStringifiedData(parsedJSON, undefined, parsedJSON, objToPath, pathToObj);
191+
192+
return new AsyncAPIDocument(parsedJSON as v2.AsyncAPIObject);
168193
}
169-
}
194+
}

src/old-api/iterator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export enum SchemaTypesToIterate {
3838

3939
export type TraverseOptions = {
4040
callback: TraverseCallback
41-
schemaTypesToIterate: SchemaTypesToIterate[]
41+
schemaTypesToIterate: Array<`${SchemaTypesToIterate}`>;
4242
seenSchemas: Set<any>
4343
}
4444

@@ -47,7 +47,7 @@ export type TraverseCallback = (schema: Schema, propOrIndex: string | number | n
4747
/**
4848
* Go through each channel and for each parameter, and message payload and headers recursively call the callback for each schema.
4949
*/
50-
export function traverseAsyncApiDocument(doc: AsyncAPIDocument, callback: TraverseCallback, schemaTypesToIterate: SchemaTypesToIterate[] = []) {
50+
export function traverseAsyncApiDocument(doc: AsyncAPIDocument, callback: TraverseCallback, schemaTypesToIterate: Array<`${SchemaTypesToIterate}`> = []) {
5151
if (schemaTypesToIterate.length === 0) {
5252
schemaTypesToIterate = Object.values(SchemaTypesToIterate);
5353
}

src/old-api/mixins.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,20 @@ export function hasDescription(model: Base<{ description?: string }>) {
4444
return Boolean(model.json('description'));
4545
}
4646

47-
export function description(model: Base<{ description?: string }>): string | undefined {
48-
return model.json('description');
47+
export function description(model: Base<{ description?: string }>): string | null {
48+
const description = model.json('description');
49+
return typeof description === 'string' ? description : null;
4950
}
5051

5152
export function hasExternalDocs(model: Base<{ externalDocs?: v2.ExternalDocumentationObject }>): boolean {
5253
return Object.keys(model.json('externalDocs') || {}).length > 0;
5354
}
5455

55-
export function externalDocs(model: Base<{ externalDocs?: v2.ExternalDocumentationObject }>): ExternalDocs | undefined {
56-
if (hasExternalDocs(model)) {
56+
export function externalDocs(model: Base<{ externalDocs?: v2.ExternalDocumentationObject }>): ExternalDocs | null {
57+
if (typeof model.json('externalDocs') === 'object') {
5758
return new ExternalDocs(model.json('externalDocs') as v2.ExternalDocumentationObject);
5859
}
60+
return null;
5961
}
6062

6163
export const extensionsMixins = {

src/old-api/schema.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { SpecificationExtensionsModel, createMapOfType, getMapValue, description, hasDescription, hasExternalDocs, externalDocs } from './mixins';
22
import { xParserCircular, xParserCircularProps } from '../constants';
3+
import { hasRef } from '../utils';
34

45
import type { Base } from './base';
56
import type { v2 } from '../spec-types';
@@ -117,15 +118,19 @@ export class Schema extends SpecificationExtensionsModel<v2.AsyncAPISchemaObject
117118
additionalProperties() {
118119
if (typeof this._json === 'boolean') return this._json;
119120
const additionalProperties = this.__get('additionalProperties');
121+
if (typeof additionalProperties === 'boolean') return additionalProperties;
120122
if (additionalProperties === undefined) return true;
121-
return new Schema(additionalProperties as any, { parent: this });
123+
if (additionalProperties === null) return false;
124+
return this.__createChild(additionalProperties);
122125
}
123126

124127
additionalItems() {
125128
if (typeof this._json === 'boolean') return this._json;
126129
const additionalItems = this.__get('additionalItems');
130+
if (typeof additionalItems === 'boolean') return additionalItems;
127131
if (additionalItems === undefined) return true;
128-
return new Schema(additionalItems as any, { parent: this });
132+
if (additionalItems === null) return false;
133+
return this.__createChild(additionalItems);
129134
}
130135

131136
patternProperties() {
@@ -236,7 +241,7 @@ export class Schema extends SpecificationExtensionsModel<v2.AsyncAPISchemaObject
236241
}
237242

238243
isCircular() {
239-
if (this.ext(xParserCircular)) {
244+
if (hasRef(this._json) || this.ext(xParserCircular)) {
240245
return true;
241246
}
242247

src/spec-types/v2.ts

Lines changed: 64 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,22 @@ export interface ServerVariableObject extends SpecificationExtensions {
5656
}
5757

5858
export interface ServerBindingsObject extends SpecificationExtensions {
59-
http: Binding;
60-
ws: Binding;
61-
kafka: Binding;
62-
anypointmq: Binding;
63-
amqp: Binding;
64-
amqp1: Binding;
65-
mqtt: Binding;
66-
mqtt5: Binding;
67-
nats: Binding;
68-
jms: Binding;
69-
sns: Binding;
70-
sqs: Binding;
71-
stomp: Binding;
72-
redis: Binding;
73-
mercure: Binding;
74-
ibmmq: Binding;
59+
http?: Binding;
60+
ws?: Binding;
61+
kafka?: Binding;
62+
anypointmq?: Binding;
63+
amqp?: Binding;
64+
amqp1?: Binding;
65+
mqtt?: Binding;
66+
mqtt5?: Binding;
67+
nats?: Binding;
68+
jms?: Binding;
69+
sns?: Binding;
70+
sqs?: Binding;
71+
stomp?: Binding;
72+
redis?: Binding;
73+
mercure?: Binding;
74+
ibmmq?: Binding;
7575
}
7676

7777
export type ChannelsObject = Record<string, ChannelObject>;
@@ -86,22 +86,22 @@ export interface ChannelObject extends SpecificationExtensions {
8686
}
8787

8888
export interface ChannelBindingsObject extends SpecificationExtensions {
89-
http: Binding;
90-
ws: Binding;
91-
kafka: Binding;
92-
anypointmq: Binding;
93-
amqp: Binding;
94-
amqp1: Binding;
95-
mqtt: Binding;
96-
mqtt5: Binding;
97-
nats: Binding;
98-
jms: Binding;
99-
sns: Binding;
100-
sqs: Binding;
101-
stomp: Binding;
102-
redis: Binding;
103-
mercure: Binding;
104-
ibmmq: Binding;
89+
http?: Binding;
90+
ws?: Binding;
91+
kafka?: Binding;
92+
anypointmq?: Binding;
93+
amqp?: Binding;
94+
amqp1?: Binding;
95+
mqtt?: Binding;
96+
mqtt5?: Binding;
97+
nats?: Binding;
98+
jms?: Binding;
99+
sns?: Binding;
100+
sqs?: Binding;
101+
stomp?: Binding;
102+
redis?: Binding;
103+
mercure?: Binding;
104+
ibmmq?: Binding;
105105
}
106106

107107
export interface OperationObject extends OperationTraitObject, SpecificationExtensions {
@@ -120,22 +120,22 @@ export interface OperationTraitObject extends SpecificationExtensions {
120120
}
121121

122122
export interface OperationBindingsObject extends SpecificationExtensions {
123-
http: Binding;
124-
ws: Binding;
125-
kafka: Binding;
126-
anypointmq: Binding;
127-
amqp: Binding;
128-
amqp1: Binding;
129-
mqtt: Binding;
130-
mqtt5: Binding;
131-
nats: Binding;
132-
jms: Binding;
133-
sns: Binding;
134-
sqs: Binding;
135-
stomp: Binding;
136-
redis: Binding;
137-
mercure: Binding;
138-
ibmmq: Binding;
123+
http?: Binding;
124+
ws?: Binding;
125+
kafka?: Binding;
126+
anypointmq?: Binding;
127+
amqp?: Binding;
128+
amqp1?: Binding;
129+
mqtt?: Binding;
130+
mqtt5?: Binding;
131+
nats?: Binding;
132+
jms?: Binding;
133+
sns?: Binding;
134+
sqs?: Binding;
135+
stomp?: Binding;
136+
redis?: Binding;
137+
mercure?: Binding;
138+
ibmmq?: Binding;
139139
}
140140

141141
export type ParametersObject = Record<string, ParameterObject | ReferenceObject>;
@@ -175,22 +175,22 @@ export interface MessageExampleObject extends SpecificationExtensions {
175175
}
176176

177177
export interface MessageBindingsObject extends SpecificationExtensions {
178-
http: Binding;
179-
ws: Binding;
180-
kafka: Binding;
181-
anypointmq: Binding;
182-
amqp: Binding;
183-
amqp1: Binding;
184-
mqtt: Binding;
185-
mqtt5: Binding;
186-
nats: Binding;
187-
jms: Binding;
188-
sns: Binding;
189-
sqs: Binding;
190-
stomp: Binding;
191-
redis: Binding;
192-
mercure: Binding;
193-
ibmmq: Binding;
178+
http?: Binding;
179+
ws?: Binding;
180+
kafka?: Binding;
181+
anypointmq?: Binding;
182+
amqp?: Binding;
183+
amqp1?: Binding;
184+
mqtt?: Binding;
185+
mqtt5?: Binding;
186+
nats?: Binding;
187+
jms?: Binding;
188+
sns?: Binding;
189+
sqs?: Binding;
190+
stomp?: Binding;
191+
redis?: Binding;
192+
mercure?: Binding;
193+
ibmmq?: Binding;
194194
}
195195

196196
export type TagsObject = Array<TagObject>;

src/stringify.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export function copy(data: Record<string, any>) {
5757
return unstringifiedData;
5858
}
5959

60-
function refReplacer() {
60+
export function refReplacer() {
6161
const modelPaths = new Map();
6262
const paths = new Map();
6363
let init: unknown = null;
@@ -90,7 +90,7 @@ function refReplacer() {
9090
}
9191

9292
const refRoot = '$ref:$';
93-
function traverseStringifiedData(parent: any, field: string | undefined, root: any, objToPath: Map<unknown, unknown>, pathToObj: Map<unknown, unknown>) {
93+
export function traverseStringifiedData(parent: any, field: string | undefined, root: any, objToPath: Map<unknown, unknown>, pathToObj: Map<unknown, unknown>) {
9494
let objOrPath = parent;
9595
let path = refRoot;
9696

0 commit comments

Comments
 (0)