Skip to content

Commit

Permalink
Merge master into dependabot/npm_and_yarn/cross-spawn-7.0.6
Browse files Browse the repository at this point in the history
  • Loading branch information
asyncapi-bot-eve authored Nov 22, 2024
2 parents 9b61764 + 6b866c4 commit 3682d0f
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 5 deletions.
9 changes: 5 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
"strip-ansi": "^6.0.0",
"unzipper": "^0.10.11",
"uuid": "^9.0.1",
"ws": "^8.2.3"
"ws": "^8.2.3",
"yaml": "^2.6.1"
},
"devDependencies": {
"@asyncapi/minimaltemplate": "./test/fixtures/minimaltemplate",
Expand Down
67 changes: 67 additions & 0 deletions src/commands/pretty.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Args } from '@oclif/core';
import { promises as fs } from 'fs';
import * as yaml from 'yaml';
import Command from '../core/base';
import { load , retrieveFileFormat} from '../core/models/SpecificationFile';
import { ValidationError } from '../core/errors/validation-error';
import { prettyFlags } from '../core/flags/pretty.flags';

export default class Pretty extends Command {
static readonly description = 'Format AsyncAPI specification file';

static readonly examples = [
'asyncapi pretty ./asyncapi.yaml',
'asyncapi pretty ./asyncapi.yaml --output formatted-asyncapi.yaml',
];

static readonly flags = prettyFlags();

static readonly args = {
'spec-file': Args.string({description: 'spec path, url, or context-name', required: true}),
};

async run() {
const { args, flags } = await this.parse(Pretty);
const filePath = args['spec-file'];
const outputPath = flags.output;

try {
this.specFile = await load(filePath);
} catch (err) {
this.error(
new ValidationError({
type: 'invalid-file',
filepath: filePath,
})
);
}

const content = this.specFile.text();
let formatted: string;

try {
const fileFormat = retrieveFileFormat(this.specFile.text());
if (fileFormat === 'yaml' || fileFormat === 'yml') {
const yamlDoc = yaml.parseDocument(content);
formatted = yamlDoc.toString({
lineWidth: 0,
});
} else if (fileFormat === 'json') {
const jsonObj = JSON.parse(content);
formatted = JSON.stringify(jsonObj, null, 2);
} else {
throw new Error('Unsupported file format');
}
} catch (err) {
this.error(`Error formatting file: ${err}`);
}

if (outputPath) {
await fs.writeFile(outputPath, formatted, 'utf8');
this.log(`Asyncapi document has been beautified ${outputPath}`);
} else {
await fs.writeFile(filePath, formatted, 'utf8');
this.log(`Asyncapi document ${filePath} has been beautified in-place.`);
}
}
}
10 changes: 10 additions & 0 deletions src/core/flags/pretty.flags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Flags } from '@oclif/core';

export const prettyFlags = () => {
return {
output: Flags.string({
char: 'o',
description: 'Output file path',
}),
};
};
36 changes: 36 additions & 0 deletions test/fixtures/asyncapiValid_v1.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
asyncapi: "2.1.0"
info:
title: Streetlights API
version: "1.0.0"
description: |
The Smartylighting Streetlights API allows you
to remotely manage the city lights.
license:
name: Apache 2.0
url: "https://www.apache.org/licenses/LICENSE-2.0"
servers:
mosquitto:
url: mqtt://test.mosquitto.org
protocol: mqtt
channels:
light/measured:
publish:
summary: Inform about environmental lighting conditions for a particular streetlight.
operationId: onLightMeasured
message:
name: LightMeasured
payload:
type: object
properties:
id:
type: integer
minimum: 0
description: Id of the streetlight.
lumens:
type: integer
minimum: 0
description: Light intensity measured in lumens.
sentAt:
type: string
format: date-time
description: Date and time when the message was sent.
38 changes: 38 additions & 0 deletions test/fixtures/badFormatAsyncapi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"asyncapi": "2.2.0",
"info": {
"title": "Account Service",
"version": "1.0.0",
"description":
"This service is in charge of processing user signups"
},
"channels": {
"user/signedup": {
"subscribe": {
"message": {
"$ref": "#/components/messages/UserSignedUp"
}
}
}
},
"components": {
"messages": {
"UserSignedUp": {
"payload": {
"type": "object",
"properties": {
"displayName": {
"type": "string",
"description": "Name of the user"
},
"email": {
"type": "string",
"format": "email",
"description": "Email of the user"
}
}
}
}
}
}
}
64 changes: 64 additions & 0 deletions test/integration/pretty.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { test } from '@oclif/test';
import TestHelper, { createMockServer, stopMockServer } from '../helpers';
import { expect } from '@oclif/test';

const testHelper = new TestHelper();
const badFormatPath = './test/fixtures/asyncapi_v1.yml';
const validFormatPath = './test/fixtures/asyncapiValid_v1.yml';
const badFormatPathJson = './test/fixtures/badFormatAsyncapi.json';

describe('pretty', () => {
describe('with file paths', () => {
beforeEach(() => {
testHelper.createDummyContextFile();
});

afterEach(() => {
testHelper.deleteDummyContextFile();
});

before(() => {
createMockServer();
});

after(() => {
stopMockServer();
});

test
.stderr()
.stdout()
.command(['pretty', badFormatPath])
.it('should log the information file has been beautified', (ctx, done) => {
expect(ctx.stdout).to.contain(
`Asyncapi document ${badFormatPath} has been beautified in-place`,
);
expect(ctx.stderr).to.equal('');
done();
});

test
.stderr()
.stdout()
.command(['pretty', badFormatPath ,'-o', validFormatPath])
.it('should log the information file has been beautified', (ctx, done) => {
expect(ctx.stdout).to.contain(
`Asyncapi document has been beautified ${validFormatPath}`,
);
expect(ctx.stderr).to.equal('');
done();
});

test
.stderr()
.stdout()
.command(['pretty', badFormatPathJson])
.it('should log the information file has been beautified json file', (ctx, done) => {
expect(ctx.stdout).to.contain(
`Asyncapi document ${badFormatPathJson} has been beautified in-place`,
);
expect(ctx.stderr).to.equal('');
done();
});
});
});

0 comments on commit 3682d0f

Please sign in to comment.