Skip to content

Commit

Permalink
initial setup
Browse files Browse the repository at this point in the history
  • Loading branch information
jonaslagoni committed Jul 24, 2023
1 parent 5aa4bbe commit 6fb67e1
Show file tree
Hide file tree
Showing 14 changed files with 1,063 additions and 46 deletions.
744 changes: 728 additions & 16 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"fs-extra": "^11.1.0",
"indent-string": "^4.0.0",
"inquirer": "^8.2.0",
"js-yaml": "^4.1.0",
"lodash.template": "^4.4.0",
"node-fetch": "^2.0.0",
"oclif": "^3.7.3",
Expand Down Expand Up @@ -56,6 +57,7 @@
"@types/fs-extra": "^11.0.1",
"@types/inquirer": "^8.1.3",
"@types/jest": "^29.0.3",
"@types/js-yaml": "^4.0.5",
"@types/lodash.template": "^4.4.4",
"@types/node": "^10.17.60",
"@types/node-fetch": "^2.5.12",
Expand Down
16 changes: 12 additions & 4 deletions src/commands/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Command from '../base';
import bundle from '@asyncapi/bundler';
import { promises } from 'fs';
import path from 'path';
import { load } from '../models/SpecificationFile';
import { Specification, load } from '../models/SpecificationFile';

const { writeFile } = promises;

Expand Down Expand Up @@ -32,9 +32,17 @@ export default class Bundle extends Command {
let baseFile;
const outputFormat = path.extname(argv[0]);
const AsyncAPIFiles = await this.loadFiles(argv);
const containsAsyncAPI3 = AsyncAPIFiles.map((file) => {
return file.isAsyncAPI3();
});
if (containsAsyncAPI3) {
return this.error('One of the files you tried to bundle is AsyncAPI v3 format, the bundle command does not support it yet, please checkout https:/asyncapi/bundler/issues/133');
}
if (flags.base) {baseFile = (await load(flags.base)).text();}

const document = await bundle(AsyncAPIFiles,
const fileContents = AsyncAPIFiles.map((file) => file.text());

const document = await bundle(fileContents,
{
referenceIntoComponents: flags['reference-into-components'],
base: baseFile
Expand Down Expand Up @@ -65,11 +73,11 @@ export default class Bundle extends Command {
}
}

async loadFiles(filepaths: string[]): Promise<string[]> {
async loadFiles(filepaths: string[]): Promise<Specification[]> {
const files = [];
for (const filepath of filepaths) {
const file = await load(filepath);
files.push(file.text());
files.push(file);
}
return files;
}
Expand Down
2 changes: 1 addition & 1 deletion src/commands/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default class Convert extends Command {
this.log(`URL ${specFile.getFileURL()} successfully converted!`);
}
}

if (typeof convertedFile === 'object') {
convertedFileFormatted = JSON.stringify(convertedFile, null, 4);
} else {
Expand Down
11 changes: 8 additions & 3 deletions src/commands/diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ export default class Diff extends Command {

try {
firstDocument = await load(firstDocumentPath);

if (firstDocument.isAsyncAPI3()) {
return this.error('Diff command does not support AsyncAPI v3 yet, please checkout https:/asyncapi/diff/issues/154');
}

enableWatch(watchMode, {
spec: firstDocument,
handler: this,
Expand Down Expand Up @@ -155,7 +160,7 @@ export default class Diff extends Command {
} catch (error) {
if (error instanceof DiffBreakingChangeError) {
this.error(error);
}
}
throw new ValidationError({
type: 'parser-error',
err: error,
Expand Down Expand Up @@ -241,9 +246,9 @@ const enableWatch = (status: boolean, watcher: SpecWatcherParams) => {
function throwOnBreakingChange(diffOutput: AsyncAPIDiff, outputFormat: string) {
const breakingChanges = diffOutput.breaking();
if (
(outputFormat === 'json' && breakingChanges.length !== 0) ||
(outputFormat === 'json' && breakingChanges.length !== 0) ||
((outputFormat === 'yaml' || outputFormat === 'yml') && breakingChanges !== '[]\n')
) {
throw new DiffBreakingChangeError();
}
}
}
2 changes: 1 addition & 1 deletion src/commands/generate/fromTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export default class Template extends Command {
genOption.resolve = {resolve: this.getMapBaseUrlToFolderResolver(parsedFlags.mapBaseUrlToFolder)};
}

await this.generate(asyncapi, template, output, options, genOption);
await this.generate(asyncapi, template, output, options, genOption);
if (watchTemplate) {
const watcherHandler = this.watcherHandler(asyncapi, template, output, options, genOption);
await this.runWatchMode(asyncapi, template, output, watcherHandler);
Expand Down
3 changes: 3 additions & 0 deletions src/commands/generate/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ export default class Models extends Command {
const { tsModelType, tsEnumType, tsIncludeComments, tsModuleSystem, tsExportType, tsJsonBinPack, namespace, csharpAutoImplement, csharpArrayType, csharpNewtonsoft, csharpHashcode, csharpEqual, csharpSystemJson, packageName, output } = flags;
const { language, file } = args;
const inputFile = (await load(file)) || (await load());
if (inputFile.isAsyncAPI3()) {
return this.error('Generate Models command does not support AsyncAPI v3 yet, please checkout https:/asyncapi/modelina/issues/1376');
}
const { document, diagnostics ,status } = await parse(this, inputFile, flags);
if (!document || status === 'invalid') {
const severityErrors = diagnostics.filter((obj) => obj.severity === 0);
Expand Down
25 changes: 14 additions & 11 deletions src/commands/optimize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default class Optimize extends Command {
'asyncapi optimize ./asyncapi.yaml --optimization=remove-components,reuse-components,move-to-components --no-tty',
'asyncapi optimize ./asyncapi.yaml --optimization=remove-components,reuse-components,move-to-components --output=terminal --no-tty',
];

static flags = {
help: Flags.help({ char: 'h' }),
optimization: Flags.string({char: 'p', default: Object.values(Optimizations), options: Object.values(Optimizations), multiple: true, description: 'select the type of optimizations that you want to apply.'}),
Expand All @@ -48,24 +48,27 @@ export default class Optimize extends Command {
const { args, flags } = await this.parse(Optimize); //NOSONAR
const filePath = args['spec-file'];
let specFile: Specification;
let optimizer: Optimizer;
let report: Report;
try {
specFile = await load(filePath);
optimizer = new Optimizer(specFile.text());
report = await optimizer.getReport();
} catch (err) {
this.error(
return this.error(
new ValidationError({
type: 'invalid-file',
filepath: filePath,
})
);
}

if (specFile.isAsyncAPI3()) {
return this.error('Optimize command does not support AsyncAPI v3 yet, please checkout https:/asyncapi/optimizer/issues/168');
}

const optimizer: Optimizer = new Optimizer(specFile.text());
const report: Report = await optimizer.getReport();
this.isInteractive = !flags['no-tty'];
this.optimizations = flags.optimization as Optimizations[];
this.outputMethod = flags.output as Outputs;

if (!(report.moveToComponents?.length || report.removeComponents?.length || report.reuseComponents?.length)) {
this.log(`No optimization has been applied since ${specFile.getFilePath() ?? specFile.getFileURL()} looks optimized!`);
return;
Expand All @@ -76,13 +79,13 @@ export default class Optimize extends Command {
await this.interactiveRun(report);
}

try {
try {
const optimizedDocument = optimizer.getOptimizedDocument({rules: {
moveToComponents: this.optimizations.includes(Optimizations.MOVE_TO_COMPONETS),
removeComponents: this.optimizations.includes(Optimizations.REMOVE_COMPONENTS),
reuseComponents: this.optimizations.includes(Optimizations.REUSE_COMPONENTS)
}, output: Output.YAML});

const specPath = specFile.getFilePath();
let newPath = '';
if (specPath) {
Expand Down Expand Up @@ -149,7 +152,7 @@ export default class Optimize extends Command {
this.showOptimizations(report.reuseComponents);
choices.push({name: 'reuse components', value: Optimizations.REUSE_COMPONENTS});
}
const optimizationRes = await inquirer.prompt([{
const optimizationRes = await inquirer.prompt([{
name: 'optimization',
message: 'select the type of optimization that you want to apply:',
type: 'checkbox',
Expand All @@ -158,7 +161,7 @@ export default class Optimize extends Command {
}]);

this.optimizations = optimizationRes.optimization;

const outputRes = await inquirer.prompt([{
name: 'output',
message: 'where do you want to save the result:',
Expand Down
2 changes: 1 addition & 1 deletion src/commands/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default class Validate extends Command {
if (watchMode) {
specWatcher({ spec: specFile, handler: this, handlerName: 'validate' });
}

await validate(this, specFile, flags);
}
}
17 changes: 15 additions & 2 deletions src/models/SpecificationFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { promises as fs } from 'fs';
import path from 'path';
import { URL } from 'url';
import fetch from 'node-fetch';

import yaml from 'js-yaml';
import { loadContext } from './Context';
import { ErrorLoadingSpec } from '../errors/specification-file';
import { MissingContextFileError } from '../errors/context-error';
Expand Down Expand Up @@ -34,6 +34,19 @@ export class Specification {
}
}

isAsyncAPI3() {
const jsObj = this.toJson();
return jsObj.asyncapi === '3.0.0';
}

toJson(): Record<string, any> {
try {
return yaml.load(this.spec, {json: true}) as Record<string, any>;
} catch (e) {
return JSON.parse(this.spec);
}
}

text() {
return this.spec;
}
Expand Down Expand Up @@ -137,7 +150,7 @@ export async function load(filePathOrContextName?: string, loadType?: LoadType):
if (e instanceof MissingContextFileError) {
throw new ErrorLoadingSpec();
}

throw e;
}
}
Expand Down
4 changes: 2 additions & 2 deletions test/commands/convert.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ describe('convert', () => {
}
}
});

test
.stderr()
.stdout()
Expand Down Expand Up @@ -170,4 +170,4 @@ describe('convert', () => {
done();
});
});
});
});
15 changes: 13 additions & 2 deletions test/commands/optimize.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import path from 'path';
import { test } from '@oclif/test';
import { NO_CONTEXTS_SAVED } from '../../src/errors/context-error';
import TestHelper from '../testHelper';
import inquirer from 'inquirer';
import {Optimizations, Outputs} from '../../src/commands/optimize';
Expand All @@ -9,8 +8,20 @@ const testHelper = new TestHelper();
const optimizedFilePath = './test/specification.yml';
const unoptimizedFile = './test/dummyspec/unoprimizedSpec.yml';
const invalidFile = './test/specification-invalid.yml';
const asyncapiv3 = './test/specification-v3.yml';

describe('optimize', () => {
describe('should handle AsyncAPI v3 document correctly', () => {
test
.stderr()
.stdout()
.command(['optimize', asyncapiv3])
.it('give error', (ctx, done) => {
expect(ctx.stderr).toEqual('Error: Optimize command does not support AsyncAPI v3 yet, please checkout https:/asyncapi/optimizer/issues/168');
expect(ctx.stdout).toEqual(' ');
done();
});
});
describe('no optimization needed', () => {
beforeEach(() => {
testHelper.createDummyContextFile();
Expand Down Expand Up @@ -96,7 +107,7 @@ describe('optimize', () => {
}
}
});

test
.stderr()
.stdout()
Expand Down
Loading

0 comments on commit 6fb67e1

Please sign in to comment.