Skip to content

Commit

Permalink
Merge pull request #52 from event-catalog/feat-asyncapi-groups-by-ser…
Browse files Browse the repository at this point in the history
…vice

feat(plugin): asyncapi plugin now groups by service
  • Loading branch information
boyney123 authored Feb 6, 2025
2 parents 64b4def + c9ad7b7 commit 5188485
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/stupid-badgers-check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@eventcatalog/generator-asyncapi": major
---

feat(plugin): asyncapi plugin now groups by service
22 changes: 21 additions & 1 deletion packages/generator-asyncapi/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { defaultMarkdown as generateMarkdownForChannel, getChannelProtocols } fr
import checkLicense from './checkLicense';

import { EventType, MessageOperations } from './types';
import { join } from 'node:path';

const parser = new Parser();

Expand All @@ -33,6 +34,7 @@ const cliArgs = argv(process.argv.slice(2));

const optionsSchema = z.object({
licenseKey: z.string().optional(),
writeFilesToRoot: z.boolean().optional(),
services: z.array(
z.object({
id: z.string({ required_error: 'The service id is required. please provide the service id' }),
Expand Down Expand Up @@ -111,18 +113,21 @@ export default async (config: any, options: Props) => {
version: versionEvent,
get: getEvent,
addSchema: addSchemaToEvent,
collection: 'events',
},
command: {
write: writeCommand,
version: versionCommand,
get: getCommand,
addSchema: addSchemaToCommand,
collection: 'commands',
},
query: {
write: writeQuery,
version: versionQuery,
get: getQuery,
addSchema: addSchemaToQuery,
collection: 'queries',
},
};

Expand Down Expand Up @@ -173,6 +178,14 @@ export default async (config: any, options: Props) => {
let serviceSpecificationsFiles = [];
let serviceMarkdown = generateMarkdownForService(document);

// Have to ../ as the SDK will put the files into hard coded folders
let servicePath = options.domain
? path.join('../', 'domains', options.domain.id, 'services', service.id)
: path.join('../', 'services', service.id);
if (options.writeFilesToRoot) {
servicePath = service.id;
}

// Manage domain
if (options.domain) {
// Try and get the domain
Expand Down Expand Up @@ -283,13 +296,19 @@ export default async (config: any, options: Props) => {
version: versionMessage,
get: getMessage,
addSchema: addSchemaToMessage,
collection: folder,
} = MESSAGE_OPERATIONS[eventType];

let messageMarkdown = generateMarkdownForMessage(document, message);
const badges = message.tags().all() || [];

console.log(chalk.blue(`Processing message: ${getMessageName(message)} (v${messageVersion})`));

let messagePath = join(servicePath, folder, message.id());
if (options.writeFilesToRoot) {
messagePath = message.id();
}

if (serviceOwnsMessageContract) {
// Check if the message already exists in the catalog
const catalogedMessage = await getMessage(message.id().toLowerCase(), 'latest');
Expand Down Expand Up @@ -321,7 +340,7 @@ export default async (config: any, options: Props) => {
},
{
override: true,
path: message.id(),
path: messagePath,
}
);

Expand Down Expand Up @@ -399,6 +418,7 @@ export default async (config: any, options: Props) => {
...(repository && { repository }),
},
{
path: servicePath,
override: true,
}
);
Expand Down
42 changes: 39 additions & 3 deletions packages/generator-asyncapi/src/test/plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,9 @@ describe('AsyncAPI EventCatalog Plugin', () => {
it('when a message has a schema defined in the AsyncAPI file, the schema is documented in EventCatalog', async () => {
await plugin(config, { services: [{ path: join(asyncAPIExamplesDir, 'simple.asyncapi.yml'), id: 'account-service' }] });

const schema = await fs.readFile(join(catalogDir, 'events', 'UserSignedUp', 'schema.json'));
const schema = await fs.readFile(
join(catalogDir, 'services', 'account-service', 'events', 'UserSignedUp', 'schema.json')
);

expect(schema).toBeDefined();
});
Expand Down Expand Up @@ -1089,7 +1091,10 @@ describe('AsyncAPI EventCatalog Plugin', () => {
expect(event).toBeDefined();
expect(event.schemaPath).toEqual('schema.avsc');

const schema = await fs.readFile(join(catalogDir, 'events', 'lightMeasuredMessageAvro', 'schema.avsc'), 'utf-8');
const schema = await fs.readFile(
join(catalogDir, 'services', 'test-service', 'events', 'lightMeasuredMessageAvro', 'schema.avsc'),
'utf-8'
);
const parsedAsyncAPIFile = await fs.readFile(
join(catalogDir, 'services', 'test-service', 'asyncapi-with-avro-expect-not-to-parse-schemas.yml'),
'utf-8'
Expand Down Expand Up @@ -1188,7 +1193,10 @@ describe('AsyncAPI EventCatalog Plugin', () => {
expect(event.schemaPath).toEqual('schema.avsc');

// Check file schema.avsc
const schema = await fs.readFile(join(catalogDir, 'events', 'userSignedUp', 'schema.avsc'), 'utf-8');
const schema = await fs.readFile(
join(catalogDir, 'services', 'user-signup-api', 'events', 'userSignedUp', 'schema.avsc'),
'utf-8'
);
const schemaParsed = JSON.parse(schema);
expect(schemaParsed).toEqual({
type: 'record',
Expand Down Expand Up @@ -1319,5 +1327,33 @@ describe('AsyncAPI EventCatalog Plugin', () => {
expect(schema).toContain('x-parser-schema-id');
});
});

describe('writeFilesToRoot', () => {
it('if `writeFilesToRoot` is true, the files are written to the root of the service', async () => {
const { getService } = utils(catalogDir);

await plugin(config, {
services: [{ path: join(asyncAPIExamplesDir, 'simple.asyncapi.yml'), id: 'account-service' }],
writeFilesToRoot: true,
});

const service = await getService('account-service', '1.0.0');
expect(service.schemaPath).toEqual('simple.asyncapi.yml');

const events = await fs.readdir(join(catalogDir, 'events'));
expect(events).toEqual(['UserSignedOut', 'UserSignedUp']);

const queries = await fs.readdir(join(catalogDir, 'queries'));
expect(queries).toEqual(['CheckEmailAvailability', 'GetUserByEmail']);

const commands = await fs.readdir(join(catalogDir, 'commands'));
expect(commands).toEqual(['SignUpUser']);

const services = await fs.readdir(join(catalogDir, 'services'));
expect(services).toEqual(['account-service']);
const file = await fs.readFile(join(catalogDir, 'services', 'account-service', 'simple.asyncapi.yml'), 'utf-8');
expect(file).toBeDefined();
});
});
});
});
1 change: 1 addition & 0 deletions packages/generator-asyncapi/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export interface MessageOperations {
version: (id: string) => Promise<any>;
get: (id: string, version: string) => Promise<any>;
addSchema: (id: string, schema: any, version: any) => Promise<void>;
collection: string;
}

// Define valid event types
Expand Down

0 comments on commit 5188485

Please sign in to comment.