@eventcatalog/sdk 2.2.9 → 2.2.10
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/dist/channels.js +12 -1
- package/dist/channels.js.map +1 -1
- package/dist/channels.mjs +13 -2
- package/dist/channels.mjs.map +1 -1
- package/dist/domains.js +12 -1
- package/dist/domains.js.map +1 -1
- package/dist/domains.mjs +12 -1
- package/dist/domains.mjs.map +1 -1
- package/dist/eventcatalog.js +9 -3
- package/dist/eventcatalog.js.map +1 -1
- package/dist/eventcatalog.mjs +11 -5
- package/dist/eventcatalog.mjs.map +1 -1
- package/dist/index.d.mts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +9 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11 -5
- package/dist/index.mjs.map +1 -1
- package/dist/services.js +12 -1
- package/dist/services.js.map +1 -1
- package/dist/services.mjs +13 -2
- package/dist/services.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/eventcatalog.ts","../src/index.ts","../src/events.ts","../src/internal/utils.ts","../src/internal/resources.ts","../src/commands.ts","../src/queries.ts","../src/services.ts","../src/domains.ts","../src/channels.ts","../src/custom-docs.ts","../src/teams.ts","../src/users.ts"],"sourcesContent":["import type { Domain, Service, Event, Query, Command, Team, CustomDoc, User, Channel } from './types';\nimport fs from 'fs';\nimport path, { join } from 'node:path';\nimport utils from './index';\nimport { getResourcePath } from './internal/resources';\ntype ExportedResource<T = any> = T & {\n directory: string;\n};\n\nexport type EventCatalogObject = {\n version: string;\n catalogVersion: string;\n createdAt: string;\n resources: {\n domains?: ExportedResource<Domain>[];\n services?: ExportedResource<Service>[];\n messages?: {\n events?: ExportedResource<Event>[];\n queries?: ExportedResource<Query>[];\n commands?: ExportedResource<Command>[];\n };\n teams?: ExportedResource<Team>[];\n users?: ExportedResource<User>[];\n channels?: ExportedResource<Channel>[];\n customDocs?: ExportedResource<CustomDoc>[];\n };\n};\n\nconst DUMP_VERSION = '0.0.1';\n\nconst getEventCatalogVersion = async (catalogDir: string) => {\n // Read package.json in the catalogDir\n try {\n const packageJson = fs.readFileSync(join(catalogDir, 'package.json'), 'utf8');\n const packageJsonObject = JSON.parse(packageJson);\n return packageJsonObject['dependencies']['@eventcatalog/core'];\n } catch (error) {\n return 'unknown';\n }\n};\n\nconst hydrateResource = async (\n catalogDir: string,\n resources: any[],\n { attachSchema = false }: { attachSchema?: boolean } = {}\n) => {\n return await Promise.all(\n resources.map(async (resource) => {\n // Get resource from directory\n // Get resource from directory\n const resourcePath = await getResourcePath(catalogDir, resource.id, resource.version);\n let schema = '';\n\n if (resource.schemaPath && resourcePath?.fullPath) {\n const pathToSchema = path.join(path.dirname(resourcePath?.fullPath), resource.schemaPath);\n if (fs.existsSync(pathToSchema)) {\n schema = fs.readFileSync(pathToSchema, 'utf8');\n }\n }\n\n // const hasSchemaPath = resource.data.schemaPath;\n\n const eventcatalog = schema ? { directory: resourcePath?.directory, schema } : { directory: resourcePath?.directory };\n\n return {\n ...resource,\n _eventcatalog: eventcatalog,\n };\n })\n );\n};\n\nconst filterCollection = (\n collection: any[],\n options?: {\n includeMarkdown?: boolean;\n }\n) => {\n return collection.map((item) => ({\n ...item,\n markdown: options?.includeMarkdown ? item.markdown : undefined,\n }));\n};\n/**\n * Dumps the catalog to a JSON file.\n *\n * @param directory - The directory of the catalog.\n * @returns A JSON file with the catalog.\n */\nexport const dumpCatalog =\n (directory: string) =>\n async (options?: { includeMarkdown?: boolean }): Promise<EventCatalogObject> => {\n const { getDomains, getServices, getEvents, getQueries, getCommands, getChannels, getTeams, getUsers } = utils(directory);\n\n const { includeMarkdown = true } = options || {};\n\n const domains = await getDomains();\n const services = await getServices();\n\n const events = await getEvents();\n const commands = await getCommands();\n const queries = await getQueries();\n const teams = await getTeams();\n const users = await getUsers();\n const channels = await getChannels();\n\n const [\n hydratedDomains,\n hydratedServices,\n hydratedEvents,\n hydratedQueries,\n hydratedCommands,\n hydratedTeams,\n hydratedUsers,\n hydratedChannels,\n ] = await Promise.all([\n hydrateResource(directory, domains),\n hydrateResource(directory, services),\n hydrateResource(directory, events),\n hydrateResource(directory, queries),\n hydrateResource(directory, commands),\n hydrateResource(directory, teams),\n hydrateResource(directory, users),\n hydrateResource(directory, channels),\n ]);\n\n return {\n version: DUMP_VERSION,\n catalogVersion: await getEventCatalogVersion(directory),\n createdAt: new Date().toISOString(),\n resources: {\n domains: filterCollection(hydratedDomains, { includeMarkdown }),\n services: filterCollection(hydratedServices, { includeMarkdown }),\n messages: {\n events: filterCollection(hydratedEvents, { includeMarkdown }),\n queries: filterCollection(hydratedQueries, { includeMarkdown }),\n commands: filterCollection(hydratedCommands, { includeMarkdown }),\n },\n teams: filterCollection(hydratedTeams, { includeMarkdown }),\n users: filterCollection(hydratedUsers, { includeMarkdown }),\n channels: filterCollection(hydratedChannels, { includeMarkdown }),\n },\n };\n };\n","import { join } from 'node:path';\nimport {\n rmEvent,\n rmEventById,\n writeEvent,\n writeEventToService,\n versionEvent,\n getEvent,\n addFileToEvent,\n addSchemaToEvent,\n eventHasVersion,\n getEvents,\n} from './events';\nimport {\n rmCommand,\n rmCommandById,\n writeCommand,\n writeCommandToService,\n versionCommand,\n getCommand,\n getCommands,\n addFileToCommand,\n addSchemaToCommand,\n commandHasVersion,\n} from './commands';\nimport {\n rmQuery,\n rmQueryById,\n writeQuery,\n writeQueryToService,\n versionQuery,\n getQuery,\n getQueries,\n addFileToQuery,\n addSchemaToQuery,\n queryHasVersion,\n} from './queries';\nimport {\n writeService,\n writeServiceToDomain,\n getService,\n versionService,\n rmService,\n rmServiceById,\n addFileToService,\n addMessageToService,\n serviceHasVersion,\n getSpecificationFilesForService,\n writeVersionedService,\n getServices,\n} from './services';\nimport {\n writeDomain,\n getDomain,\n getDomains,\n versionDomain,\n rmDomain,\n rmDomainById,\n addFileToDomain,\n addUbiquitousLanguageToDomain,\n domainHasVersion,\n addServiceToDomain,\n getUbiquitousLanguageFromDomain,\n} from './domains';\n\nimport {\n rmChannel,\n rmChannelById,\n writeChannel,\n versionChannel,\n getChannel,\n getChannels,\n channelHasVersion,\n addMessageToChannel,\n} from './channels';\n\nimport { dumpCatalog } from './eventcatalog';\n\nimport { writeCustomDoc, getCustomDoc, getCustomDocs, rmCustomDoc } from './custom-docs';\n\nimport { writeTeam, getTeam, getTeams, rmTeamById } from './teams';\n\nimport { writeUser, getUser, getUsers, rmUserById } from './users';\n\n/**\n * Init the SDK for EventCatalog\n *\n * @param path - The path to the EventCatalog directory\n *\n */\nexport default (path: string) => {\n return {\n /**\n * Returns an events from EventCatalog\n * @param id - The id of the event to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Event|Undefined\n */\n getEvent: getEvent(join(path)),\n /**\n * Returns all events from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Event[]|Undefined\n */\n getEvents: getEvents(join(path)),\n /**\n * Adds an event to EventCatalog\n *\n * @param event - The event to write\n * @param options - Optional options to write the event\n *\n */\n writeEvent: writeEvent(join(path, 'events')),\n /**\n * Adds an event to a service in EventCatalog\n *\n * @param event - The event to write to the service\n * @param service - The service and it's id to write to the event to\n * @param options - Optional options to write the event\n *\n */\n writeEventToService: writeEventToService(join(path)),\n /**\n * Remove an event to EventCatalog (modeled on the standard POSIX rm utility)\n *\n * @param path - The path to your event, e.g. `/Inventory/InventoryAdjusted`\n *\n */\n rmEvent: rmEvent(join(path, 'events')),\n /**\n * Remove an event by an Event id\n *\n * @param id - The id of the event you want to remove\n *\n */\n rmEventById: rmEventById(join(path)),\n /**\n * Moves a given event id to the version directory\n * @param directory\n */\n versionEvent: versionEvent(join(path)),\n /**\n * Adds a file to the given event\n * @param id - The id of the event to add the file to\n * @param file - File contents to add including the content and the file name\n * @param version - Optional version of the event to add the file to\n * @returns\n */\n addFileToEvent: addFileToEvent(join(path)),\n /**\n * Adds a schema to the given event\n * @param id - The id of the event to add the schema to\n * @param schema - Schema contents to add including the content and the file name\n * @param version - Optional version of the event to add the schema to\n * @returns\n */\n addSchemaToEvent: addSchemaToEvent(join(path)),\n /**\n * Check to see if an event version exists\n * @param id - The id of the event\n * @param version - The version of the event (supports semver)\n * @returns\n */\n eventHasVersion: eventHasVersion(join(path)),\n\n /**\n * ================================\n * Commands\n * ================================\n */\n\n /**\n * Returns a command from EventCatalog\n * @param id - The id of the command to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Command|Undefined\n */\n getCommand: getCommand(join(path)),\n /**\n * Returns all commands from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Command[]|Undefined\n */\n getCommands: getCommands(join(path)),\n /**\n * Adds an command to EventCatalog\n *\n * @param command - The command to write\n * @param options - Optional options to write the command\n *\n */\n writeCommand: writeCommand(join(path, 'commands')),\n\n /**\n * Adds a command to a service in EventCatalog\n *\n * @param command - The command to write to the service\n * @param service - The service and it's id to write to the command to\n * @param options - Optional options to write the command\n *\n */\n writeCommandToService: writeCommandToService(join(path)),\n\n /**\n * Remove an command to EventCatalog (modeled on the standard POSIX rm utility)\n *\n * @param path - The path to your command, e.g. `/Inventory/InventoryAdjusted`\n *\n */\n rmCommand: rmCommand(join(path, 'commands')),\n /**\n * Remove an command by an Event id\n *\n * @param id - The id of the command you want to remove\n *\n */\n rmCommandById: rmCommandById(join(path)),\n /**\n * Moves a given command id to the version directory\n * @param directory\n */\n versionCommand: versionCommand(join(path)),\n /**\n * Adds a file to the given command\n * @param id - The id of the command to add the file to\n * @param file - File contents to add including the content and the file name\n * @param version - Optional version of the command to add the file to\n * @returns\n */\n addFileToCommand: addFileToCommand(join(path)),\n /**\n * Adds a schema to the given command\n * @param id - The id of the command to add the schema to\n * @param schema - Schema contents to add including the content and the file name\n * @param version - Optional version of the command to add the schema to\n * @returns\n */\n addSchemaToCommand: addSchemaToCommand(join(path)),\n\n /**\n * Check to see if a command version exists\n * @param id - The id of the command\n * @param version - The version of the command (supports semver)\n * @returns\n */\n commandHasVersion: commandHasVersion(join(path)),\n\n /**\n * ================================\n * Queries\n * ================================\n */\n\n /**\n * Returns a query from EventCatalog\n * @param id - The id of the query to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Query|Undefined\n */\n getQuery: getQuery(join(path)),\n /**\n * Returns all queries from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Query[]|Undefined\n */\n getQueries: getQueries(join(path)),\n /**\n * Adds a query to EventCatalog\n *\n * @param query - The query to write\n * @param options - Optional options to write the event\n *\n */\n writeQuery: writeQuery(join(path, 'queries')),\n /**\n * Adds a query to a service in EventCatalog\n *\n * @param query - The query to write to the service\n * @param service - The service and it's id to write to the query to\n * @param options - Optional options to write the query\n *\n */\n writeQueryToService: writeQueryToService(join(path)),\n /**\n * Remove an query to EventCatalog (modeled on the standard POSIX rm utility)\n *\n * @param path - The path to your query, e.g. `/Orders/GetOrder`\n *\n */\n rmQuery: rmQuery(join(path, 'queries')),\n /**\n * Remove a query by a Query id\n *\n * @param id - The id of the query you want to remove\n *\n */\n rmQueryById: rmQueryById(join(path)),\n /**\n * Moves a given query id to the version directory\n * @param directory\n */\n versionQuery: versionQuery(join(path)),\n /**\n * Adds a file to the given query\n * @param id - The id of the query to add the file to\n * @param file - File contents to add including the content and the file name\n * @param version - Optional version of the query to add the file to\n * @returns\n */\n addFileToQuery: addFileToQuery(join(path)),\n /**\n * Adds a schema to the given query\n * @param id - The id of the query to add the schema to\n * @param schema - Schema contents to add including the content and the file name\n * @param version - Optional version of the query to add the schema to\n * @returns\n */\n addSchemaToQuery: addSchemaToQuery(join(path)),\n /**\n * Check to see if an query version exists\n * @param id - The id of the query\n * @param version - The version of the query (supports semver)\n * @returns\n */\n queryHasVersion: queryHasVersion(join(path)),\n\n /**\n * ================================\n * Channels\n * ================================\n */\n\n /**\n * Returns a channel from EventCatalog\n * @param id - The id of the channel to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Channel|Undefined\n */\n getChannel: getChannel(join(path)),\n /**\n * Returns all channels from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Channel[]|Undefined\n */\n getChannels: getChannels(join(path)),\n /**\n * Adds an channel to EventCatalog\n *\n * @param command - The channel to write\n * @param options - Optional options to write the channel\n *\n */\n writeChannel: writeChannel(join(path, 'channels')),\n\n /**\n * Remove an channel to EventCatalog (modeled on the standard POSIX rm utility)\n *\n * @param path - The path to your channel, e.g. `/Inventory/InventoryAdjusted`\n *\n */\n rmChannel: rmChannel(join(path, 'channels')),\n /**\n * Remove an channel by an Event id\n *\n * @param id - The id of the channel you want to remove\n *\n */\n rmChannelById: rmChannelById(join(path)),\n /**\n * Moves a given channel id to the version directory\n * @param directory\n */\n versionChannel: versionChannel(join(path)),\n\n /**\n * Check to see if a channel version exists\n * @param id - The id of the channel\n * @param version - The version of the channel (supports semver)\n * @returns\n */\n channelHasVersion: channelHasVersion(join(path)),\n\n /**\n * Add a channel to an event\n *\n * Optionally specify a version to add the channel to a specific version of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addEventToChannel } = utils('/path/to/eventcatalog');\n *\n * // adds a new event (InventoryUpdatedEvent) to the inventory.{env}.events channel\n * await addEventToChannel('inventory.{env}.events channel', { id: 'InventoryUpdatedEvent', version: '2.0.0', parameters: { env: 'dev' } });\n *\n * ```\n */\n addEventToChannel: addMessageToChannel(join(path), 'events'),\n /**\n * Add a channel to an command\n *\n * Optionally specify a version to add the channel to a specific version of the command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addCommandToChannel } = utils('/path/to/eventcatalog');\n *\n * // adds a new command (UpdateInventory) to the inventory.{env}.events channel\n * await addCommandToChannel('inventory.{env}.events channel', { id: 'UpdateInventory', version: '2.0.0', parameters: { env: 'dev' } });\n *\n * ```\n */\n addCommandToChannel: addMessageToChannel(join(path), 'commands'),\n\n /**\n * Add a channel to an query\n *\n * Optionally specify a version to add the channel to a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addQueryToChannel } = utils('/path/to/eventcatalog');\n *\n * // adds a new query (GetInventory) to the inventory.{env}.events channel\n * await addQueryToChannel('inventory.{env}.events channel', { id: 'GetInventory', version: '2.0.0', parameters: { env: 'dev' } });\n *\n * ```\n */\n addQueryToChannel: addMessageToChannel(join(path), 'queries'),\n\n /**\n * ================================\n * SERVICES\n * ================================\n */\n\n /**\n * Adds a service to EventCatalog\n *\n * @param service - The service to write\n * @param options - Optional options to write the event\n *\n */\n writeService: writeService(join(path, 'services')),\n\n /**\n * Adds a versioned service to EventCatalog\n *\n * @param service - The service to write\n *\n */\n writeVersionedService: writeVersionedService(join(path, 'services')),\n\n /**\n * Adds a service to a domain in EventCatalog\n *\n * @param service - The service to write\n * @param domain - The domain to add the service to\n * @param options - Optional options to write the event\n *\n */\n writeServiceToDomain: writeServiceToDomain(join(path, 'domains')),\n /**\n * Returns a service from EventCatalog\n * @param id - The id of the service to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Service|Undefined\n */\n getService: getService(join(path)),\n /**\n * Returns all services from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Service[]|Undefined\n */\n getServices: getServices(join(path)),\n /**\n * Moves a given service id to the version directory\n * @param directory\n */\n versionService: versionService(join(path)),\n /**\n * Remove a service from EventCatalog (modeled on the standard POSIX rm utility)\n *\n * @param path - The path to your service, e.g. `/InventoryService`\n *\n */\n rmService: rmService(join(path, 'services')),\n /**\n * Remove an service by an service id\n *\n * @param id - The id of the service you want to remove\n *\n */\n rmServiceById: rmServiceById(join(path)),\n /**\n * Adds a file to the given service\n * @param id - The id of the service to add the file to\n * @param file - File contents to add including the content and the file name\n * @param version - Optional version of the service to add the file to\n * @returns\n */\n addFileToService: addFileToService(join(path)),\n\n /**\n * Returns the specifications for a given service\n * @param id - The id of the service to retrieve the specifications for\n * @param version - Optional version of the service\n * @returns\n */\n getSpecificationFilesForService: getSpecificationFilesForService(join(path)),\n\n /**\n * Check to see if a service version exists\n * @param id - The id of the service\n * @param version - The version of the service (supports semver)\n * @returns\n */\n serviceHasVersion: serviceHasVersion(join(path)),\n\n /**\n * Add an event to a service by it's id.\n *\n * Optionally specify a version to add the event to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addEventToService } = utils('/path/to/eventcatalog');\n *\n * // adds a new event (InventoryUpdatedEvent) that the InventoryService will send\n * await addEventToService('InventoryService', 'sends', { event: 'InventoryUpdatedEvent', version: '2.0.0' });\n *\n * // adds a new event (OrderComplete) that the InventoryService will receive\n * await addEventToService('InventoryService', 'receives', { event: 'OrderComplete', version: '2.0.0' });\n *\n * ```\n */\n addEventToService: addMessageToService(join(path)),\n /**\n * Add a command to a service by it's id.\n *\n * Optionally specify a version to add the event to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addCommandToService } = utils('/path/to/eventcatalog');\n *\n * // adds a new command (UpdateInventoryCommand) that the InventoryService will send\n * await addCommandToService('InventoryService', 'sends', { command: 'UpdateInventoryCommand', version: '2.0.0' });\n *\n * // adds a new command (VerifyInventory) that the InventoryService will receive\n * await addCommandToService('InventoryService', 'receives', { command: 'VerifyInventory', version: '2.0.0' });\n *\n * ```\n */\n addCommandToService: addMessageToService(join(path)),\n /**\n * Add a query to a service by it's id.\n *\n * Optionally specify a version to add the event to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addQueryToService } = utils('/path/to/eventcatalog');\n *\n * // adds a new query (UpdateInventory) that the InventoryService will send\n * await addQueryToService('InventoryService', 'sends', { command: 'UpdateInventory', version: '2.0.0' });\n *\n * // adds a new command (VerifyInventory) that the InventoryService will receive\n * await addQueryToService('InventoryService', 'receives', { command: 'VerifyInventory', version: '2.0.0' });\n *\n * ```\n */\n addQueryToService: addMessageToService(join(path)),\n\n /**\n * ================================\n * Domains\n * ================================\n */\n\n /**\n * Adds a domain to EventCatalog\n *\n * @param domain - The domain to write\n * @param options - Optional options to write the event\n *\n */\n writeDomain: writeDomain(join(path, 'domains')),\n\n /**\n * Returns a domain from EventCatalog\n * @param id - The id of the domain to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Domain|Undefined\n */\n getDomain: getDomain(join(path, 'domains')),\n /**\n * Returns all domains from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Domain[]|Undefined\n */\n getDomains: getDomains(join(path)),\n /**\n * Moves a given domain id to the version directory\n * @param directory\n */\n versionDomain: versionDomain(join(path, 'domains')),\n /**\n * Remove a domain from EventCatalog (modeled on the standard POSIX rm utility)\n *\n * @param path - The path to your domain, e.g. `/Payment`\n *\n */\n rmDomain: rmDomain(join(path, 'domains')),\n /**\n * Remove an service by an domain id\n *\n * @param id - The id of the domain you want to remove\n *\n */\n rmDomainById: rmDomainById(join(path, 'domains')),\n /**\n * Adds a file to the given domain\n * @param id - The id of the domain to add the file to\n * @param file - File contents to add including the content and the file name\n * @param version - Optional version of the domain to add the file to\n * @returns\n */\n addFileToDomain: addFileToDomain(join(path, 'domains')),\n\n /**\n * Adds an ubiquitous language dictionary to a domain\n * @param id - The id of the domain to add the ubiquitous language to\n * @param ubiquitousLanguageDictionary - The ubiquitous language dictionary to add\n * @param version - Optional version of the domain to add the ubiquitous language to\n */\n addUbiquitousLanguageToDomain: addUbiquitousLanguageToDomain(join(path, 'domains')),\n\n /**\n * Get the ubiquitous language dictionary from a domain\n * @param id - The id of the domain to get the ubiquitous language from\n * @param version - Optional version of the domain to get the ubiquitous language from\n * @returns\n */\n getUbiquitousLanguageFromDomain: getUbiquitousLanguageFromDomain(join(path, 'domains')),\n\n /**\n * Check to see if a domain version exists\n * @param id - The id of the domain\n * @param version - The version of the domain (supports semver)\n * @returns\n */\n domainHasVersion: domainHasVersion(join(path)),\n\n /**\n * Adds a given service to a domain\n * @param id - The id of the domain\n * @param service - The id and version of the service to add\n * @param version - (Optional) The version of the domain to add the service to\n * @returns\n */\n addServiceToDomain: addServiceToDomain(join(path, 'domains')),\n\n /**\n * ================================\n * Teams\n * ================================\n */\n /**\n * Adds a team to EventCatalog\n *\n * @param team - The team to write\n * @param options - Optional options to write the team\n *\n */\n writeTeam: writeTeam(join(path, 'teams')),\n /**\n * Returns a team from EventCatalog\n * @param id - The id of the team to retrieve\n * @returns Team|Undefined\n */\n getTeam: getTeam(join(path, 'teams')),\n /**\n * Returns all teams from EventCatalog\n * @returns Team[]|Undefined\n */\n getTeams: getTeams(join(path)),\n /**\n * Remove a team by the team id\n *\n * @param id - The id of the team you want to remove\n *\n */\n rmTeamById: rmTeamById(join(path, 'teams')),\n\n /**\n * ================================\n * Users\n * ================================\n */\n /**\n * Adds a user to EventCatalog\n *\n * @param user - The user to write\n * @param options - Optional options to write the user\n *\n */\n writeUser: writeUser(join(path, 'users')),\n /**\n * Returns a user from EventCatalog\n * @param id - The id of the user to retrieve\n * @returns User|Undefined\n */\n getUser: getUser(join(path, 'users')),\n /**\n * Returns all user from EventCatalog\n * @returns User[]|Undefined\n */\n getUsers: getUsers(join(path)),\n /**\n * Remove a user by the user id\n *\n * @param id - The id of the user you want to remove\n *\n */\n rmUserById: rmUserById(join(path, 'users')),\n\n /**\n * ================================\n * Custom Docs\n * ================================\n */\n\n /**\n * Returns a custom doc from EventCatalog\n * @param path - The path to the custom doc to retrieve\n * @returns CustomDoc|Undefined\n */\n getCustomDoc: getCustomDoc(join(path, 'docs')),\n /**\n * Returns all custom docs from EventCatalog\n * @param options - Optional options to get custom docs from a specific path\n * @returns CustomDoc[]|Undefined\n */\n getCustomDocs: getCustomDocs(join(path, 'docs')),\n /**\n * Writes a custom doc to EventCatalog\n * @param customDoc - The custom doc to write\n * @param options - Optional options to write the custom doc\n *\n */\n writeCustomDoc: writeCustomDoc(join(path, 'docs')),\n\n /**\n * Removes a custom doc from EventCatalog\n * @param path - The path to the custom doc to remove\n *\n */\n rmCustomDoc: rmCustomDoc(join(path, 'docs')),\n\n /**\n * Dumps the catalog to a JSON file.\n * @param directory - The directory to dump the catalog to\n * @returns A JSON file with the catalog\n */\n dumpCatalog: dumpCatalog(join(path)),\n };\n};\n","import fs from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { findFileById } from './internal/utils';\nimport type { Event } from './types';\nimport {\n addFileToResource,\n getResource,\n getResourcePath,\n getResources,\n rmResourceById,\n versionResource,\n writeResource,\n} from './internal/resources';\n\n/**\n * Returns an event from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the event\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getEvent } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the event\n * const event = await getEvent('InventoryAdjusted');\n *\n * // Gets a version of the event\n * const event = await getEvent('InventoryAdjusted', '0.0.1');\n * ```\n */\nexport const getEvent =\n (directory: string) =>\n async (id: string, version?: string): Promise<Event> =>\n getResource(directory, id, version, { type: 'event' }) as Promise<Event>;\n\n/**\n * Returns all events from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the events.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getEvents } = utils('/path/to/eventcatalog');\n *\n * // Gets all events (and versions) from the catalog\n * const events = await getEvents();\n *\n * // Gets all events (only latest version) from the catalog\n * const events = await getEvents({ latestOnly: true });\n * ```\n */\nexport const getEvents =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Event[]> =>\n getResources(directory, { type: 'events', ...options }) as Promise<Event[]>;\n\n/**\n * Write an event to EventCatalog.\n *\n * You can optionally overide the path of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeEvent } = utils('/path/to/eventcatalog');\n *\n * // Write an event to the catalog\n * // Event would be written to events/InventoryAdjusted\n * await writeEvent({\n * id: 'InventoryAdjusted',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * });\n *\n * // Write an event to the catalog but override the path\n * // Event would be written to events/Inventory/InventoryAdjusted\n * await writeEvent({\n * id: 'InventoryAdjusted',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { path: \"/Inventory/InventoryAdjusted\"});\n *\n * // Write a event to the catalog and override the existing content (if there is any)\n * await writeEvent({\n * id: 'InventoryAdjusted',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { override: true });\n *\n * // Write a event to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeEvent({\n * id: 'InventoryAdjusted',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeEvent =\n (directory: string) =>\n async (\n event: Event,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...event }, { ...options, type: 'event' });\n/**\n * Write an event to a service in EventCatalog.\n *\n * You can optionally override the path of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeEventToService } = utils('/path/to/eventcatalog');\n *\n * // Write an event to a given service in the catalog\n * // Event would be written to services/Inventory/events/InventoryAdjusted\n * await writeEventToService({\n * id: 'InventoryAdjusted',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { id: 'Inventory' });\n * ```\n */\nexport const writeEventToService =\n (directory: string) =>\n async (\n event: Event,\n service: { id: string; version?: string },\n options: { path?: string; format?: 'md' | 'mdx' } = { path: '', format: 'mdx' }\n ) => {\n const resourcePath = await getResourcePath(directory, service.id, service.version);\n if (!resourcePath) {\n throw new Error('Service not found');\n }\n\n let pathForEvent =\n service.version && service.version !== 'latest'\n ? `${resourcePath.directory}/versioned/${service.version}/events`\n : `${resourcePath.directory}/events`;\n pathForEvent = join(pathForEvent, event.id);\n await writeResource(directory, { ...event }, { ...options, path: pathForEvent, type: 'event' });\n };\n\n/**\n * Delete an event at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmEvent } = utils('/path/to/eventcatalog');\n *\n * // removes an event at the given path (events dir is appended to the given path)\n * // Removes the event at events/InventoryAdjusted\n * await rmEvent('/InventoryAdjusted');\n * ```\n */\nexport const rmEvent = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete an event by it's id.\n *\n * Optionally specify a version to delete a specific version of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmEventById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryAdjusted event\n * await rmEventById('InventoryAdjusted');\n *\n * // deletes a specific version of the InventoryAdjusted event\n * await rmEventById('InventoryAdjusted', '0.0.1');\n * ```\n */\nexport const rmEventById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) => {\n await rmResourceById(directory, id, version, { type: 'event', persistFiles });\n};\n\n/**\n * Version an event by it's id.\n *\n * Takes the latest event and moves it to a versioned directory.\n * All files with this event are also versioned (e.g /events/InventoryAdjusted/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionEvent } = utils('/path/to/eventcatalog');\n *\n * // moves the latest InventoryAdjusted event to a versioned directory\n * // the version within that event is used as the version number.\n * await versionEvent('InventoryAdjusted');\n *\n * ```\n */\nexport const versionEvent = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Add a file to an event by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToEvent } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest InventoryAdjusted event\n * await addFileToEvent('InventoryAdjusted', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the InventoryAdjusted event\n * await addFileToEvent('InventoryAdjusted', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToEvent =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Add a schema to an event by it's id.\n *\n * Optionally specify a version to add a schema to a specific version of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addSchemaToEvent } = utils('/path/to/eventcatalog');\n *\n * // JSON schema example\n * const schema = {\n * \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n * \"type\": \"object\",\n * \"properties\": {\n * \"name\": {\n * \"type\": \"string\"\n * },\n * \"age\": {\n * \"type\": \"number\"\n * }\n * },\n * \"required\": [\"name\", \"age\"]\n * };\n *\n * // adds a schema to the latest InventoryAdjusted event\n * await addSchemaToEvent('InventoryAdjusted', { schema, fileName: 'schema.json' });\n *\n * // adds a file to a specific version of the InventoryAdjusted event\n * await addSchemaToEvent('InventoryAdjusted', { schema, fileName: 'schema.json' }, '0.0.1');\n *\n * ```\n */\nexport const addSchemaToEvent =\n (directory: string) => async (id: string, schema: { schema: string; fileName: string }, version?: string) => {\n await addFileToEvent(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);\n };\n\n/**\n * Check to see if the catalog has a version for the given event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { eventHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await eventHasVersion('InventoryAdjusted', '0.0.1');\n * await eventHasVersion('InventoryAdjusted', 'latest');\n * await eventHasVersion('InventoryAdjusted', '0.0.x');*\n *\n * ```\n */\nexport const eventHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import { globSync } from 'glob';\nimport fsSync from 'node:fs';\nimport { copy, CopyFilterAsync, CopyFilterSync } from 'fs-extra';\nimport { join, dirname } from 'node:path';\nimport matter from 'gray-matter';\nimport { satisfies, validRange, valid } from 'semver';\n\n/**\n * Returns true if a given version of a resource id exists in the catalog\n */\nexport const versionExists = async (catalogDir: string, id: string, version: string) => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n const matchedFiles = (await searchFilesForId(files, id, version)) || [];\n return matchedFiles.length > 0;\n};\n\nexport const findFileById = async (catalogDir: string, id: string, version?: string): Promise<string | undefined> => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n\n const matchedFiles = (await searchFilesForId(files, id)) || [];\n const latestVersion = matchedFiles.find((path) => !path.includes('versioned'));\n\n // If no version is provided, return the latest version\n if (!version) {\n return latestVersion;\n }\n\n // map files into gray matter to get versions\n const parsedFiles = matchedFiles.map((path) => {\n const { data } = matter.read(path);\n return { ...data, path };\n }) as any[];\n\n const semverRange = validRange(version);\n\n if (semverRange && valid(version)) {\n const match = parsedFiles.filter((c) => satisfies(c.version, semverRange));\n return match.length > 0 ? match[0].path : undefined;\n }\n\n // Order by version\n const sorted = parsedFiles.sort((a, b) => {\n return a.version.localeCompare(b.version);\n });\n\n // latest version\n const match = sorted.length > 0 ? [sorted[sorted.length - 1]] : [];\n\n if (match.length > 0) {\n return match[0].path;\n }\n};\n\nexport const getFiles = async (pattern: string, ignore: string | string[] = '') => {\n try {\n const ignoreList = Array.isArray(ignore) ? ignore : [ignore];\n const baseDir = pattern.includes('**') ? pattern.split('**')[0] : dirname(pattern);\n const files = globSync(pattern, { cwd: baseDir, ignore: ['node_modules/**', ...ignoreList] });\n return files;\n } catch (error) {\n throw new Error(`Error finding files: ${error}`);\n }\n};\n\nexport const readMdxFile = async (path: string) => {\n const { data } = matter.read(path);\n const { markdown, ...frontmatter } = data;\n return { ...frontmatter, markdown };\n};\n\nexport const searchFilesForId = async (files: string[], id: string, version?: string) => {\n const idRegex = new RegExp(`^id:\\\\s*(['\"]|>-)?\\\\s*${id}['\"]?\\\\s*$`, 'm');\n const versionRegex = new RegExp(`^version:\\\\s*['\"]?${version}['\"]?\\\\s*$`, 'm');\n\n const matches = files.map((file) => {\n const content = fsSync.readFileSync(file, 'utf-8');\n const hasIdMatch = content.match(idRegex);\n\n // Check version if provided\n if (version && !content.match(versionRegex)) {\n return undefined;\n }\n\n if (hasIdMatch) {\n return file;\n }\n });\n\n return matches.filter(Boolean).filter((file) => file !== undefined);\n};\n\n/**\n * Function to copy a directory from source to target, uses a tmp directory\n * @param catalogDir\n * @param source\n * @param target\n * @param filter\n */\nexport const copyDir = async (catalogDir: string, source: string, target: string, filter?: CopyFilterAsync | CopyFilterSync) => {\n const tmpDirectory = join(catalogDir, 'tmp');\n fsSync.mkdirSync(tmpDirectory, { recursive: true });\n\n // Copy everything over\n await copy(source, tmpDirectory, {\n overwrite: true,\n filter,\n });\n\n await copy(tmpDirectory, target, {\n overwrite: true,\n filter,\n });\n\n // Remove the tmp directory\n fsSync.rmSync(tmpDirectory, { recursive: true });\n};\n\n// Makes sure values in sends/recieves are unique\nexport const uniqueVersions = (messages: { id: string; version: string }[]): { id: string; version: string }[] => {\n const uniqueSet = new Set();\n\n return messages.filter((message) => {\n const key = `${message.id}-${message.version}`;\n if (!uniqueSet.has(key)) {\n uniqueSet.add(key);\n return true;\n }\n return false;\n });\n};\n","import { dirname, join } from 'path';\nimport { copyDir, findFileById, getFiles, searchFilesForId, versionExists } from './utils';\nimport matter from 'gray-matter';\nimport fs from 'node:fs/promises';\nimport fsSync from 'node:fs';\nimport { Message, Service, CustomDoc } from '../types';\nimport { satisfies } from 'semver';\nimport { lock, unlock } from 'proper-lockfile';\n\ntype Resource = Service | Message | CustomDoc;\n\nexport const versionResource = async (catalogDir: string, id: string) => {\n // Find all the events in the directory\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n const matchedFiles = await searchFilesForId(files, id);\n\n if (matchedFiles.length === 0) {\n throw new Error(`No resource found with id: ${id}`);\n }\n\n // Event that is in the route of the project\n const file = matchedFiles[0];\n const sourceDirectory = dirname(file);\n const { data: { version = '0.0.1' } = {} } = matter.read(file);\n const targetDirectory = getVersionedDirectory(sourceDirectory, version);\n\n fsSync.mkdirSync(targetDirectory, { recursive: true });\n\n // Copy the event to the versioned directory\n await copyDir(catalogDir, sourceDirectory, targetDirectory, (src) => {\n return !src.includes('versioned');\n });\n\n // Remove all the files in the root of the resource as they have now been versioned\n await fs.readdir(sourceDirectory).then(async (resourceFiles) => {\n await Promise.all(\n resourceFiles.map(async (file) => {\n if (file !== 'versioned') {\n fsSync.rmSync(join(sourceDirectory, file), { recursive: true });\n }\n })\n );\n });\n};\n\nexport const writeResource = async (\n catalogDir: string,\n resource: Resource,\n options: { path?: string; type: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n type: '',\n override: false,\n versionExistingContent: false,\n format: 'mdx',\n }\n) => {\n const path = options.path || `/${resource.id}`;\n const fullPath = join(catalogDir, path);\n const format = options.format || 'mdx';\n\n // Create directory if it doesn't exist\n fsSync.mkdirSync(fullPath, { recursive: true });\n\n // Create or get lock file path\n const lockPath = join(fullPath, `index.${format}`);\n\n // Ensure the file exists before attempting to lock it\n if (!fsSync.existsSync(lockPath)) {\n fsSync.writeFileSync(lockPath, '');\n }\n\n try {\n // Acquire lock with retry\n await lock(lockPath, {\n retries: 5,\n stale: 10000, // 10 seconds\n });\n\n const exists = await versionExists(catalogDir, resource.id, resource.version);\n\n if (exists && !options.override) {\n throw new Error(`Failed to write ${resource.id} (${options.type}) as the version ${resource.version} already exists`);\n }\n\n const { markdown, ...frontmatter } = resource;\n\n if (options.versionExistingContent && !exists) {\n const currentResource = await getResource(catalogDir, resource.id);\n\n if (currentResource) {\n if (satisfies(resource.version, `>${currentResource.version}`)) {\n await versionResource(catalogDir, resource.id);\n } else {\n throw new Error(`New version ${resource.version} is not greater than current version ${currentResource.version}`);\n }\n }\n }\n\n const document = matter.stringify(markdown.trim(), frontmatter);\n fsSync.writeFileSync(lockPath, document);\n } finally {\n // Always release the lock\n await unlock(lockPath).catch(() => {});\n }\n};\n\nexport const getResource = async (\n catalogDir: string,\n id: string,\n version?: string,\n options?: { type: string }\n): Promise<Resource | undefined> => {\n const file = await findFileById(catalogDir, id, version);\n if (!file) return;\n\n const { data, content } = matter.read(file);\n\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n};\n\nexport const getResourcePath = async (catalogDir: string, id: string, version?: string) => {\n const file = await findFileById(catalogDir, id, version);\n if (!file) return;\n\n return {\n fullPath: file,\n relativePath: file.replace(catalogDir, ''),\n directory: dirname(file.replace(catalogDir, '')),\n };\n};\n\nexport const getResources = async (\n catalogDir: string,\n {\n type,\n latestOnly = false,\n ignore = [],\n pattern = '',\n }: { type: string; pattern?: string; latestOnly?: boolean; ignore?: string[] }\n): Promise<Resource[] | undefined> => {\n const ignoreList = latestOnly ? `**/versioned/**` : '';\n const filePattern = pattern || `${catalogDir}/**/${type}/**/index.{md,mdx}`;\n const files = await getFiles(filePattern, [ignoreList, ...ignore]);\n\n if (files.length === 0) return;\n\n return files.map((file) => {\n const { data, content } = matter.read(file);\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n });\n};\n\nexport const rmResourceById = async (\n catalogDir: string,\n id: string,\n version?: string,\n options?: { type: string; persistFiles?: boolean }\n) => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n\n const matchedFiles = await searchFilesForId(files, id, version);\n\n if (matchedFiles.length === 0) {\n throw new Error(`No ${options?.type || 'resource'} found with id: ${id}`);\n }\n\n if (options?.persistFiles) {\n await Promise.all(\n matchedFiles.map(async (file) => {\n await fs.rm(file, { recursive: true });\n })\n );\n } else {\n await Promise.all(\n matchedFiles.map(async (file) => {\n const directory = dirname(file);\n await fs.rm(directory, { recursive: true, force: true });\n })\n );\n }\n};\n\nexport const addFileToResource = async (\n catalogDir: string,\n id: string,\n file: { content: string; fileName: string },\n version?: string\n) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory to write file to');\n\n fsSync.writeFileSync(join(dirname(pathToResource), file.fileName), file.content);\n};\n\nexport const getFileFromResource = async (catalogDir: string, id: string, file: { fileName: string }, version?: string) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory of resource');\n\n const exists = await fs\n .access(join(dirname(pathToResource), file.fileName))\n .then(() => true)\n .catch(() => false);\n if (!exists) throw new Error(`File ${file.fileName} does not exist in resource ${id} v(${version})`);\n\n return fsSync.readFileSync(join(dirname(pathToResource), file.fileName), 'utf-8');\n};\nexport const getVersionedDirectory = (sourceDirectory: string, version: any): string => {\n return join(sourceDirectory, 'versioned', version);\n};\n","import fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { Command } from './types';\nimport {\n addFileToResource,\n getResource,\n getResourcePath,\n getResources,\n rmResourceById,\n versionResource,\n writeResource,\n} from './internal/resources';\nimport { findFileById } from './internal/utils';\nimport { addMessageToService } from './services';\n\n/**\n * Returns a command from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the command\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getCommand } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the command\n * const command = await getCommand('UpdateInventory');\n *\n * // Gets a version of the command\n * const command = await getCommand('UpdateInventory', '0.0.1');\n * ```\n */\nexport const getCommand =\n (directory: string) =>\n async (id: string, version?: string): Promise<Command> =>\n getResource(directory, id, version, { type: 'command' }) as Promise<Command>;\n\n/**\n * Returns all commands from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the events.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getCommands } = utils('/path/to/eventcatalog');\n *\n * // Gets all commands (and versions) from the catalog\n * const commands = await getCommands();\n *\n * // Gets all commands (only latest version) from the catalog\n * const commands = await getCommands({ latestOnly: true });\n * ```\n */\nexport const getCommands =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Command[]> =>\n getResources(directory, { type: 'commands', ...options }) as Promise<Command[]>;\n\n/**\n * Write a command to EventCatalog.\n *\n * You can optionally override the path of the command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeCommand } = utils('/path/to/eventcatalog');\n *\n * // Write a command to the catalog\n * // Command would be written to commands/UpdateInventory\n * await writeCommand({\n * id: 'UpdateInventory',\n * name: 'Update Inventory',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * });\n *\n * // Write a command to the catalog but override the path\n * // Command would be written to commands/Inventory/UpdateInventory\n * await writeCommand({\n * id: 'UpdateInventory',\n * name: 'Update Inventory',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { path: \"/Inventory/UpdateInventory\"});\n *\n * // Write a command to the catalog and override the existing content (if there is any)\n * await writeCommand({\n * id: 'UpdateInventory',\n * name: 'Update Inventory',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { override: true });\n *\n * // Write a command to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeCommand({\n * id: 'UpdateInventory',\n * name: 'Update Inventory',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeCommand =\n (directory: string) =>\n async (\n command: Command,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n versionExistingContent: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...command }, { ...options, type: 'command' });\n\n/**\n * Write an command to a service in EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeCommandToService } = utils('/path/to/eventcatalog');\n *\n * // Write an event to a given service in the catalog\n * // Event would be written to services/Inventory/commands/UpdateInventory\n * await writeCommandToService({\n * id: 'UpdateInventory',\n * name: 'Update Inventory',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { id: 'Inventory' });\n * ```\n */\nexport const writeCommandToService =\n (directory: string) =>\n async (\n command: Command,\n service: { id: string; version?: string },\n options: { path?: string; format?: 'md' | 'mdx' } = { path: '', format: 'mdx' }\n ) => {\n const resourcePath = await getResourcePath(directory, service.id, service.version);\n if (!resourcePath) {\n throw new Error('Service not found');\n }\n\n let pathForCommand =\n service.version && service.version !== 'latest'\n ? `${resourcePath.directory}/versioned/${service.version}/commands`\n : `${resourcePath.directory}/commands`;\n pathForCommand = join(pathForCommand, command.id);\n\n await writeResource(directory, { ...command }, { ...options, path: pathForCommand, type: 'command' });\n };\n\n/**\n * Delete a command at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmCommand } = utils('/path/to/eventcatalog');\n *\n * // removes a command at the given path (commands dir is appended to the given path)\n * // Removes the command at commands/UpdateInventory\n * await rmCommand('/UpdateInventory');\n * ```\n */\nexport const rmCommand = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a command by it's id.\n *\n * Optionally specify a version to delete a specific version of the command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmCommandById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest UpdateInventory command\n * await rmCommandById('UpdateInventory');\n *\n * // deletes a specific version of the UpdateInventory command\n * await rmCommandById('UpdateInventory', '0.0.1');\n * ```\n */\nexport const rmCommandById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) =>\n rmResourceById(directory, id, version, { type: 'command', persistFiles });\n\n/**\n * Version a command by it's id.\n *\n * Takes the latest command and moves it to a versioned directory.\n * All files with this command are also versioned (e.g /commands/UpdateInventory/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionCommand } = utils('/path/to/eventcatalog');\n *\n * // moves the latest UpdateInventory command to a versioned directory\n * // the version within that command is used as the version number.\n * await versionCommand('UpdateInventory');\n *\n * ```\n */\nexport const versionCommand = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Add a file to a command by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToCommand } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest UpdateInventory command\n * await addFileToCommand('UpdateInventory', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the UpdateInventory command\n * await addFileToCommand('UpdateInventory', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToCommand =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Add a schema to a command by it's id.\n *\n * Optionally specify a version to add a schema to a specific version of the command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addSchemaToCommand } = utils('/path/to/eventcatalog');\n *\n * // JSON schema example\n * const schema = {\n * \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n * \"type\": \"object\",\n * \"properties\": {\n * \"name\": {\n * \"type\": \"string\"\n * },\n * \"age\": {\n * \"type\": \"number\"\n * }\n * },\n * \"required\": [\"name\", \"age\"]\n * };\n *\n * // adds a schema to the latest UpdateInventory command\n * await addSchemaToCommand('UpdateInventory', { schema, fileName: 'schema.json' });\n *\n * // adds a file to a specific version of the UpdateInventory command\n * await addSchemaToCommand('UpdateInventory', { schema, fileName: 'schema.json' }, '0.0.1');\n *\n * ```\n */\nexport const addSchemaToCommand =\n (directory: string) => async (id: string, schema: { schema: string; fileName: string }, version?: string) => {\n await addFileToCommand(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);\n };\n\n/**\n * Check to see if the catalog has a version for the given command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { commandHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await commandHasVersion('InventoryAdjusted', '0.0.1');\n * await commandHasVersion('InventoryAdjusted', 'latest');\n * await commandHasVersion('InventoryAdjusted', '0.0.x');*\n *\n * ```\n */\nexport const commandHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { findFileById } from './internal/utils';\nimport type { Query } from './types';\nimport {\n addFileToResource,\n getResource,\n getResourcePath,\n getResources,\n rmResourceById,\n versionResource,\n writeResource,\n} from './internal/resources';\n\n/**\n * Returns a query from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the query\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getQuery } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the event\n * const event = await getQuery('GetOrder');\n *\n * // Gets a version of the event\n * const event = await getQuery('GetOrder', '0.0.1');\n * ```\n */\nexport const getQuery =\n (directory: string) =>\n async (id: string, version?: string): Promise<Query> =>\n getResource(directory, id, version, { type: 'query' }) as Promise<Query>;\n\n/**\n * Write a query to EventCatalog.\n *\n * You can optionally override the path of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeQuery } = utils('/path/to/eventcatalog');\n *\n * // Write an event to the catalog\n * // Event would be written to queries/GetOrder\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * });\n *\n * // Write an event to the catalog but override the path\n * // Event would be written to queries/Inventory/GetOrder\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { path: \"/Orders/GetOrder\"});\n *\n * // Write a query to the catalog and override the existing content (if there is any)\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { override: true });\n *\n * // Write a query to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeQuery =\n (directory: string) =>\n async (\n query: Query,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n versionExistingContent: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...query }, { ...options, type: 'query' });\n\n/**\n * Returns all queries from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the queries.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getQueries } = utils('/path/to/eventcatalog');\n *\n * // Gets all queries (and versions) from the catalog\n * const queries = await getQueries();\n *\n * // Gets all queries (only latest version) from the catalog\n * const queries = await getQueries({ latestOnly: true });\n * ```\n */\nexport const getQueries =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Query[]> =>\n getResources(directory, { type: 'queries', ...options }) as Promise<Query[]>;\n\n/**\n * Write a query to a service in EventCatalog.\n *\n * You can optionally override the path of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeQueryToService } = utils('/path/to/eventcatalog');\n *\n * // Write an event to a given service in the catalog\n * // Event would be written to services/Orders/queries/GetOrder\n * await writeQueryToService({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { id: 'Orders' });\n * ```\n */\nexport const writeQueryToService =\n (directory: string) =>\n async (\n query: Query,\n service: { id: string; version?: string },\n options: { path?: string; format?: 'md' | 'mdx' } = { path: '', format: 'mdx' }\n ) => {\n const resourcePath = await getResourcePath(directory, service.id, service.version);\n if (!resourcePath) {\n throw new Error('Service not found');\n }\n let pathForQuery =\n service.version && service.version !== 'latest'\n ? `${resourcePath.directory}/versioned/${service.version}/queries`\n : `${resourcePath.directory}/queries`;\n pathForQuery = join(pathForQuery, query.id);\n await writeResource(directory, { ...query }, { ...options, path: pathForQuery, type: 'query' });\n };\n\n/**\n * Delete a query at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmQuery } = utils('/path/to/eventcatalog');\n *\n * // removes an query at the given path (queries dir is appended to the given path)\n * // Removes the query at queries/GetOrders\n * await rmQuery('/GetOrders');\n * ```\n */\nexport const rmQuery = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a query by it's id.\n *\n * Optionally specify a version to delete a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmQueryById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryAdjusted query\n * await rmQueryById('GetOrder');\n *\n * // deletes a specific version of the GetOrder query\n * await rmQueryById('GetOrder', '0.0.1');\n * ```\n */\nexport const rmQueryById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) => {\n await rmResourceById(directory, id, version, { type: 'query', persistFiles });\n};\n\n/**\n * Version a query by it's id.\n *\n * Takes the latest query and moves it to a versioned directory.\n * All files with this query are also versioned (e.g /queries/GetOrder/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionQuery } = utils('/path/to/eventcatalog');\n *\n * // moves the latest GetOrder query to a versioned directory\n * // the version within that query is used as the version number.\n * await versionQuery('GetOrder');\n *\n * ```\n */\nexport const versionQuery = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Add a file to a query by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToQuery } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest GetOrder query\n * await addFileToQuery('GetOrder', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the GetOrder query\n * await addFileToQuery('GetOrder', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToQuery =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Add a schema to a query by it's id.\n *\n * Optionally specify a version to add a schema to a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addSchemaToQuery } = utils('/path/to/eventcatalog');\n *\n * // JSON schema example\n * const schema = {\n * \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n * \"type\": \"object\",\n * \"properties\": {\n * \"name\": {\n * \"type\": \"string\"\n * },\n * \"age\": {\n * \"type\": \"number\"\n * }\n * },\n * \"required\": [\"name\", \"age\"]\n * };\n *\n * // adds a schema to the latest GetOrder query\n * await addSchemaToQuery('GetOrder', { schema, fileName: 'schema.json' });\n *\n * // adds a file to a specific version of the GetOrder query\n * await addSchemaToQuery('GetOrder', { schema, fileName: 'schema.json' }, '0.0.1');\n *\n * ```\n */\nexport const addSchemaToQuery =\n (directory: string) => async (id: string, schema: { schema: string; fileName: string }, version?: string) => {\n await addFileToQuery(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);\n };\n\n/**\n * Check to see if the catalog has a version for the given query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { queryHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await queryHasVersion('GetOrder', '0.0.1');\n * await queryHasVersion('GetOrder', 'latest');\n * await queryHasVersion('GetOrder', '0.0.x');*\n *\n * ```\n */\nexport const queryHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import type { Service, Specifications } from './types';\nimport fs from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport {\n addFileToResource,\n getFileFromResource,\n getResource,\n rmResourceById,\n versionResource,\n writeResource,\n getVersionedDirectory,\n getResources,\n} from './internal/resources';\nimport { findFileById, uniqueVersions } from './internal/utils';\n\n/**\n * Returns a service from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the service\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getService } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the event\n * const service = await getService('InventoryService');\n *\n * // Gets a version of the event\n * const service = await getService('InventoryService', '0.0.1');\n * ```\n */\nexport const getService =\n (directory: string) =>\n async (id: string, version?: string): Promise<Service> =>\n getResource(directory, id, version, { type: 'service' }) as Promise<Service>;\n\n/**\n * Returns all services from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the services.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getServices } = utils('/path/to/eventcatalog');\n *\n * // Gets all services (and versions) from the catalog\n * const services = await getServices();\n *\n * // Gets all services (only latest version) from the catalog\n * const services = await getServices({ latestOnly: true });\n * ```\n */\nexport const getServices =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Service[]> =>\n getResources(directory, {\n type: 'services',\n ignore: ['**/events/**', '**/commands/**', '**/queries/**'],\n ...options,\n }) as Promise<Service[]>;\n\n/**\n * Write a Service to EventCatalog.\n *\n * You can optionally overide the path of the Service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeService } = utils('/path/to/eventcatalog');\n *\n * // Write a Service\n * // Service would be written to services/InventoryService\n * await writeService({\n * id: 'InventoryService',\n * name: 'Inventory Service',\n * version: '0.0.1',\n * summary: 'Service that handles the inventory',\n * markdown: '# Hello world',\n * });\n *\n * // Write a service to the catalog but override the path\n * // Service would be written to services/Inventory/InventoryService\n * await writeService({\n * id: 'InventoryService',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { path: \"/Inventory/InventoryService\"});\n *\n * // Write a service to the catalog and override the existing content (if there is any)\n * await writeService({\n * id: 'InventoryService',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { override: true });\n *\n * // Write a service to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeService({\n * id: 'InventoryService',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeService =\n (directory: string) =>\n async (\n service: Service,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n format: 'mdx',\n }\n ) => {\n const resource: Service = { ...service };\n\n if (Array.isArray(service.sends)) {\n resource.sends = uniqueVersions(service.sends);\n }\n\n if (Array.isArray(service.receives)) {\n resource.receives = uniqueVersions(service.receives);\n }\n\n return await writeResource(directory, resource, { ...options, type: 'service' });\n };\n\n/**\n * Write a versioned service to EventCatalog.\n *\n * You can optionally overide the path of the Service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeVersionedService } = utils('/path/to/eventcatalog');\n *\n * // Write a service\n * // Service would be written to services/InventoryService/versioned/0.0.1\n * await writeVersionedService({\n * id: 'InventoryService',\n * name: 'Inventory Service',\n * version: '0.0.1',\n * summary: 'Service that handles the inventory',\n * markdown: '# Hello world',\n * });\n *\n * ```\n */\nexport const writeVersionedService = (directory: string) => async (service: Service) => {\n const resource: Service = { ...service };\n const path = getVersionedDirectory(service.id, service.version);\n\n return await writeService(directory)(resource, { path: path });\n};\n\n/**\n * Write a service to a domain in EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeServiceToDomain } = utils('/path/to/eventcatalog');\n *\n * // Write a service to a domain\n * // Service would be written to domains/Shopping/services/InventoryService\n * await writeServiceToDomain({\n * id: 'InventoryService',\n * name: 'Inventory Service',\n * version: '0.0.1',\n * summary: 'Service that handles the inventory',\n * markdown: '# Hello world',\n * }, { id: 'Shopping' });\n * ```\n */\nexport const writeServiceToDomain =\n (directory: string) =>\n async (\n service: Service,\n domain: { id: string; version?: string; direction?: string },\n options: { path?: string; format?: 'md' | 'mdx' } = { path: '', format: 'mdx' }\n ) => {\n let pathForService =\n domain.version && domain.version !== 'latest'\n ? `/${domain.id}/versioned/${domain.version}/services`\n : `/${domain.id}/services`;\n pathForService = join(pathForService, service.id);\n\n //\n await writeResource(directory, { ...service }, { ...options, path: pathForService, type: 'service' });\n };\n\n/**\n * Version a service by it's id.\n *\n * Takes the latest service and moves it to a versioned directory.\n * All files with this service are also versioned. (e.g /services/InventoryService/openapi.yml)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionService } = utils('/path/to/eventcatalog');\n *\n * // moves the latest InventoryService service to a versioned directory\n * // the version within that service is used as the version number.\n * await versionService('InventoryService');\n *\n * ```\n */\nexport const versionService = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Delete a service at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmService } = utils('/path/to/eventcatalog');\n *\n * // Removes the service at services/InventoryService\n * await rmService('/InventoryService');\n * ```\n */\nexport const rmService = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a service by it's id.\n *\n * Optionally specify a version to delete a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmServiceById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryService event\n * await rmServiceById('InventoryService');\n *\n * // deletes a specific version of the InventoryService event\n * await rmServiceById('InventoryService', '0.0.1');\n * ```\n */\nexport const rmServiceById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) =>\n rmResourceById(directory, id, version, { type: 'service', persistFiles });\n\n/**\n * Add a file to a service by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToService } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest InventoryService event\n * await addFileToService('InventoryService', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the InventoryService event\n * await addFileToService('InventoryService', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\n\nexport const addFileToService =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Returns specification files for a service\n *\n * Optionally specify a version to of the service\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getSpecificationFilesForService } = utils('/path/to/eventcatalog');\n *\n * // returns a list of specification files for a service\n * await getSpecificationFilesForService('InventoryService', '0.0.1');\n *\n * ```\n */\n\nexport const getSpecificationFilesForService = (directory: string) => async (id: string, version?: string) => {\n let service: Service = await getService(directory)(id, version);\n const filePathToService = await findFileById(directory, id, version);\n\n if (!filePathToService) throw new Error('Cannot find directory of service');\n\n let specs = [] as any;\n if (service.specifications) {\n const serviceSpecifications = service.specifications;\n const specificationFiles = Object.keys(serviceSpecifications);\n\n const getSpecs = specificationFiles.map(async (specFile) => {\n const fileName = serviceSpecifications[specFile as keyof Specifications];\n\n if (!fileName) {\n throw new Error(`Specification file name for ${specFile} is undefined`);\n }\n const rawFile = await getFileFromResource(directory, id, { fileName }, version);\n\n return { key: specFile, content: rawFile, fileName: fileName, path: join(dirname(filePathToService), fileName) };\n });\n\n specs = await Promise.all(getSpecs);\n }\n return specs;\n};\n\n/**\n * Add an event/command to a service by it's id.\n *\n * Optionally specify a version to add the event to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds an event to the service or command to the service\n * const { addEventToService, addCommandToService } = utils('/path/to/eventcatalog');\n *\n * // Adds a new event (InventoryUpdatedEvent) that the InventoryService will send\n * await addEventToService('InventoryService', 'sends', { event: 'InventoryUpdatedEvent', version: '2.0.0' });\n * * // Adds a new event (OrderComplete) that the InventoryService will receive\n * await addEventToService('InventoryService', 'receives', { event: 'OrderComplete', version: '1.0.0' });\n *\n * // Adds a new command (UpdateInventoryCommand) that the InventoryService will send\n * await addCommandToService('InventoryService', 'sends', { command: 'UpdateInventoryCommand', version: '2.0.0' });\n * // Adds a new command (VerifyInventory) that the InventoryService will receive\n * await addCommandToService('InventoryService', 'receives', { command: 'VerifyInventory', version: '1.0.0' });\n *\n * ```\n */\n\nexport const addMessageToService =\n (directory: string) => async (id: string, direction: string, event: { id: string; version: string }, version?: string) => {\n let service: Service = await getService(directory)(id, version);\n\n if (direction === 'sends') {\n if (service.sends === undefined) {\n service.sends = [];\n }\n // We first check if the event is already in the list\n for (let i = 0; i < service.sends.length; i++) {\n if (service.sends[i].id === event.id && service.sends[i].version === event.version) {\n return;\n }\n }\n service.sends.push({ id: event.id, version: event.version });\n } else if (direction === 'receives') {\n if (service.receives === undefined) {\n service.receives = [];\n }\n // We first check if the event is already in the list\n for (let i = 0; i < service.receives.length; i++) {\n if (service.receives[i].id === event.id && service.receives[i].version === event.version) {\n return;\n }\n }\n service.receives.push({ id: event.id, version: event.version });\n } else {\n throw new Error(`Direction ${direction} is invalid, only 'receives' and 'sends' are supported`);\n }\n\n const existingResource = await findFileById(directory, id, version);\n\n if (!existingResource) {\n throw new Error(`Cannot find service ${id} in the catalog`);\n }\n\n // Get where the service was located, make sure it goes back there.\n const path = existingResource.split('/services')[0];\n const pathToResource = join(path, 'services');\n\n await rmServiceById(directory)(id, version);\n await writeService(pathToResource)(service);\n };\n\n/**\n * Check to see if the catalog has a version for the given service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { serviceHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await serviceHasVersion('InventoryService', '0.0.1');\n * await serviceHasVersion('InventoryService', 'latest');\n * await serviceHasVersion('InventoryService', '0.0.x');*\n *\n * ```\n */\nexport const serviceHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import type { Domain, UbiquitousLanguageDictionary } from './types';\nimport fs from 'node:fs/promises';\nimport path, { join } from 'node:path';\nimport fsSync from 'node:fs';\nimport {\n addFileToResource,\n getResource,\n getResources,\n rmResourceById,\n versionResource,\n writeResource,\n} from './internal/resources';\nimport { findFileById, readMdxFile, uniqueVersions } from './internal/utils';\nimport matter from 'gray-matter';\n\n/**\n * Returns a domain from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the domain\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getDomain } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the domain\n * const domain = await getDomain('Payment');\n *\n * // Gets a version of the domain\n * const domain = await getDomain('Payment', '0.0.1');\n * ```\n */\nexport const getDomain =\n (directory: string) =>\n async (id: string, version?: string): Promise<Domain> =>\n getResource(directory, id, version, { type: 'domain' }) as Promise<Domain>;\n\n/**\n * Returns all domains from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the domains.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getDomains } = utils('/path/to/eventcatalog');\n *\n * // Gets all domains (and versions) from the catalog\n * const domains = await getDomains();\n *\n * // Gets all domains (only latest version) from the catalog\n * const domains = await getDomains({ latestOnly: true });\n * ```\n */\nexport const getDomains =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Domain[]> =>\n getResources(directory, {\n type: 'domains',\n ignore: ['**/services/**', '**/events/**', '**/commands/**', '**/queries/**', '**/flows/**'],\n ...options,\n }) as Promise<Domain[]>;\n\n/**\n * Write a domain to EventCatalog.\n *\n * You can optionally overide the path of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeDomain } = utils('/path/to/eventcatalog');\n *\n * // Write a domain\n * // Domain would be written to domains/Payment\n * await writeDomain({\n * id: 'Payment',\n * name: 'Payment domain',\n * version: '0.0.1',\n * summary: 'Domain for all things to do with payments',\n * markdown: '# Hello world',\n * });\n *\n * // Write a domain to the catalog but override the path\n * // Domain would be written to domains/Inventory/Payment\n * await writeDomain({\n * id: 'Payment',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { path: \"/Inventory/Payment\"});\n *\n * // Write a domain to the catalog and override the existing content (if there is any)\n * await writeDomain({\n * id: 'Payment',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { override: true });\n *\n * // Write a domain to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeDomain({\n * id: 'Payment',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeDomain =\n (directory: string) =>\n async (\n domain: Domain,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n versionExistingContent: false,\n format: 'mdx',\n }\n ) => {\n const resource: Domain = { ...domain };\n\n if (Array.isArray(domain.services)) {\n resource.services = uniqueVersions(domain.services);\n }\n\n return await writeResource(directory, resource, { ...options, type: 'domain' });\n };\n\n/**\n * Version a domain by it's id.\n *\n * Takes the latest domain and moves it to a versioned directory.\n * All files with this domain are also versioned. (e.g /domains/Payment/openapi.yml)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionDomain } = utils('/path/to/eventcatalog');\n *\n * // moves the latest Payment domain to a versioned directory\n * // the version within that domain is used as the version number.\n * await versionDomain('Payment');\n *\n * ```\n */\nexport const versionDomain = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Delete a domain at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDomain } = utils('/path/to/eventcatalog');\n *\n * // Removes the domain at domains/Payment\n * await rmDomain('/Payment');\n * ```\n */\nexport const rmDomain = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a domain by it's id.\n *\n * Optionally specify a version to delete a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDomainById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest Payment event\n * await rmDomainById('Payment');\n *\n * // deletes a specific version of the Payment event\n * await rmDomainById('Payment', '0.0.1');\n * ```\n */\nexport const rmDomainById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) =>\n rmResourceById(directory, id, version, { type: 'domain', persistFiles });\n\n/**\n * Add a file to a domain by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToDomain } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest Payment event\n * await addFileToDomain('Payment', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the Payment event\n * await addFileToDomain('Payment', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\n\nexport const addFileToDomain =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Adds a ubiquitous language dictionary to a domain.\n *\n * Optionally specify a version to add a ubiquitous language dictionary to a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addUbiquitousLanguageToDomain } = utils('/path/to/eventcatalog');\n *\n * // Adds a ubiquitous language dictionary to the latest Payment domain\n * await addUbiquitousLanguageToDomain('Payment', { dictionary: [{ id: 'Order', name: 'Order', summary: 'All things to do with the payment systems', description: 'This is a description', icon: 'KeyIcon' }] });\n *\n * // Adds a ubiquitous language dictionary to a specific version of the domain\n * await addUbiquitousLanguageToDomain('Payment', { dictionary: [{ id: 'Order', name: 'Order', summary: 'All things to do with the payment systems', description: 'This is a description', icon: 'KeyIcon' }] }, '0.0.1');\n * ```\n */\n\nexport const addUbiquitousLanguageToDomain =\n (directory: string) => async (id: string, ubiquitousLanguageDictionary: UbiquitousLanguageDictionary, version?: string) => {\n const content = matter.stringify('', {\n ...ubiquitousLanguageDictionary,\n });\n await addFileToResource(directory, id, { content, fileName: 'ubiquitous-language.mdx' }, version);\n };\n\n/**\n * Returns the ubiquitous language dictionary from a domain.\n *\n * Optionally specify a version to get the ubiquitous language dictionary from a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getUbiquitousLanguageFromDomain } = utils('/path/to/eventcatalog');\n *\n * const ubiquitousLanguage = await getUbiquitousLanguageFromDomain('Payment');\n *\n * // Returns the ubiquitous language dictionary from a specific version of the domain\n * const ubiquitousLanguage = await getUbiquitousLanguageFromDomain('Payment', '0.0.1');\n * ```\n */\nexport const getUbiquitousLanguageFromDomain = (directory: string) => async (id: string, version?: string) => {\n const pathToDomain = (await findFileById(directory, id, version)) || '';\n const pathToUbiquitousLanguage = path.join(path.dirname(pathToDomain), 'ubiquitous-language.mdx');\n\n const fileExists = fsSync.existsSync(pathToUbiquitousLanguage);\n\n if (!fileExists) {\n return undefined;\n }\n\n const content = await readMdxFile(pathToUbiquitousLanguage);\n\n return content;\n};\n\n/**\n * Check to see if the catalog has a version for the given domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { domainHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await domainHasVersion('Orders', '0.0.1');\n * await domainHasVersion('Orders', 'latest');\n * await domainHasVersion('Orders', '0.0.x');*\n *\n * ```\n */\nexport const domainHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n\n/**\n * Add a service to a domain by it's id.\n *\n * Optionally specify a version to add the service to a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds a service to the domain\n * const { addServiceToDomain } = utils('/path/to/eventcatalog');\n *\n * // Adds a service (Orders Service) to the domain (Orders)\n * await addServiceToDomain('Orders', { service: 'Order Service', version: '2.0.0' });\n * // Adds a service (Orders Service) to the domain (Orders) with a specific version\n * await addServiceToDomain('Orders', { service: 'Order Service', version: '2.0.0' }, '1.0.0');\n * ```\n */\n\nexport const addServiceToDomain =\n (directory: string) => async (id: string, service: { id: string; version: string }, version?: string) => {\n let domain: Domain = await getDomain(directory)(id, version);\n\n if (domain.services === undefined) {\n domain.services = [];\n }\n\n const serviceExistsInList = domain.services.some((s) => s.id === service.id && s.version === service.version);\n\n if (serviceExistsInList) {\n return;\n }\n\n // Add service to the list\n domain.services.push(service);\n\n await rmDomainById(directory)(id, version, true);\n await writeDomain(directory)(domain);\n };\n","import fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { Channel } from './types';\nimport { getResource, getResources, rmResourceById, versionResource, writeResource } from './internal/resources';\nimport { findFileById } from './internal/utils';\nimport { getEvent, rmEventById, writeEvent } from './events';\nimport { getCommand, rmCommandById, writeCommand } from './commands';\nimport { getQuery, rmQueryById, writeQuery } from './queries';\n\n/**\n * Returns a channel from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the channel\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getChannel } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the channel\n * const channel = await getChannel('InventoryChannel');\n *\n * // Gets a version of the channel\n * const channel = await getChannel('InventoryChannel', '0.0.1');\n * ```\n */\nexport const getChannel =\n (directory: string) =>\n async (id: string, version?: string): Promise<Channel> =>\n getResource(directory, id, version, { type: 'channel' }) as Promise<Channel>;\n\n/**\n * Returns all channels from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the channels.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getChannels } = utils('/path/to/eventcatalog');\n *\n * // Gets all channels (and versions) from the catalog\n * const channels = await getChannels();\n *\n * // Gets all channels (only latest version) from the catalog\n * const channels = await getChannels({ latestOnly: true });\n * ```\n */\nexport const getChannels =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Channel[]> =>\n getResources(directory, { type: 'channels', ...options }) as Promise<Channel[]>;\n\n/**\n * Write a channel to EventCatalog.\n *\n * You can optionally override the path of the channel.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeChannel } = utils('/path/to/eventcatalog');\n *\n * // Write a channel to the catalog\n * // channel would be written to channels/inventory.{env}.events\n * await writeChannel({\n * id: 'inventory.{env}.events',\n * name: 'Inventory channel',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * address: inventory.{env}.events,\n * protocols: ['http'],\n * });\n *\n * // Write a channel to the catalog but override the path\n * // channel would be written to channels/Inventory/InventoryChannel\n * await writeChannel({\n * id: 'InventoryChannel',\n * name: 'Update Inventory',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * address: inventory.{env}.events,\n * protocols: ['http'],\n * }, { path: \"/channels/Inventory/InventoryChannel\"});\n *\n * // Write a channel to the catalog and override the existing content (if there is any)\n * await writeChannel({\n * id: 'InventoryChannel',\n * name: 'Update Inventory',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * address: inventory.{env}.events,\n * protocols: ['http'],\n * }, { override: true });\n *\n * // Write a channel to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeChannel({\n * id: 'InventoryChannel',\n * name: 'Update Inventory',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * address: inventory.{env}.events,\n * protocols: ['http'],\n * }, { versionExistingContent: true });\n * ```\n */\nexport const writeChannel =\n (directory: string) =>\n async (\n channel: Channel,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = { path: '' }\n ) =>\n writeResource(directory, { ...channel }, { ...options, type: 'channel' });\n\n/**\n * Delete a channel at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmChannel } = utils('/path/to/eventcatalog');\n *\n * // removes a channel at the given path (channels dir is appended to the given path)\n * // Removes the channel at channels/InventoryChannel\n * await rmChannel('/InventoryChannel');\n * ```\n */\nexport const rmChannel = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a channel by it's id.\n *\n * Optionally specify a version to delete a specific version of the channel.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmChannelById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryChannel channel\n * await rmChannelById('inventory.{env}.events');\n *\n * // deletes a specific version of the InventoryChannel channel\n * await rmChannelById('inventory.{env}.events', '0.0.1');\n * ```\n */\nexport const rmChannelById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) =>\n rmResourceById(directory, id, version, { type: 'channel', persistFiles });\n\n/**\n * Version a channel by it's id.\n *\n * Takes the latest channel and moves it to a versioned directory.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionChannel } = utils('/path/to/eventcatalog');\n *\n * // moves the latest inventory.{env}.events channel to a versioned directory\n * // the version within that channel is used as the version number.\n * await versionChannel('inventory.{env}.events');\n *\n * ```\n */\nexport const versionChannel = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Check to see if the catalog has a version for the given channel.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { channelHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await channelHasVersion('inventory.{env}.events', '0.0.1');\n * await channelHasVersion('inventory.{env}.events', 'latest');\n * await channelHasVersion('inventory.{env}.events', '0.0.x');*\n *\n * ```\n */\nexport const channelHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n\n/**\n * Add an event/command/query to a channel by it's id.\n *\n * Optionally specify a version to add the message to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds an event to the service or command to the service\n * const { addEventToChannel, addCommandToChannel, addQueryToChannel } = utils('/path/to/eventcatalog');\n *\n * // Adds a new event (InventoryUpdatedEvent) that the InventoryService will send\n * await addEventToChannel('InventoryService', 'sends', { event: 'InventoryUpdatedEvent', version: '2.0.0' });\n * * // Adds a new event (OrderComplete) that the InventoryService will receive\n * await addEventToChannel('InventoryService', 'receives', { event: 'OrderComplete', version: '1.0.0' });\n *\n * // Adds a new command (UpdateInventoryCommand) that the InventoryService will send\n * await addCommandToChannel('InventoryService', 'sends', { command: 'UpdateInventoryCommand', version: '2.0.0' });\n * // Adds a new command (VerifyInventory) that the InventoryService will receive\n * await addCommandToChannel('InventoryService', 'receives', { command: 'VerifyInventory', version: '1.0.0' });\n *\n * // Adds a new query (GetInventoryQuery) that the InventoryService will send\n * await addQueryToChannel('InventoryService', 'sends', { query: 'GetInventoryQuery', version: '2.0.0' });\n * // Adds a new query (GetOrder) that the InventoryService will receive\n * await addQueryToChannel('InventoryService', 'receives', { query: 'GetOrder', version: '1.0.0' });\n *\n * ```\n */\n\nexport const addMessageToChannel =\n (directory: string, collection: string) =>\n async (id: string, _message: { id: string; version: string; parameters?: { [key: string]: string } }, version?: string) => {\n let channel: Channel = await getChannel(directory)(id, version);\n\n const functions = {\n events: {\n getMessage: getEvent,\n rmMessageById: rmEventById,\n writeMessage: writeEvent,\n },\n commands: {\n getMessage: getCommand,\n rmMessageById: rmCommandById,\n writeMessage: writeCommand,\n },\n queries: {\n getMessage: getQuery,\n rmMessageById: rmQueryById,\n writeMessage: writeQuery,\n },\n };\n\n const { getMessage, rmMessageById, writeMessage } = functions[collection as keyof typeof functions];\n\n const message = await getMessage(directory)(_message.id, _message.version);\n\n if (!message) throw new Error(`Message ${_message.id} with version ${_message.version} not found`);\n\n if (message.channels === undefined) {\n message.channels = [];\n }\n\n const channelInfo = { id, version: channel.version, ...(_message.parameters && { parameters: _message.parameters }) };\n message.channels.push(channelInfo);\n\n // Add the message where it was to start..\n const existingResource = await findFileById(directory, _message.id, _message.version);\n\n if (!existingResource) {\n throw new Error(`Cannot find message ${id} in the catalog`);\n }\n\n const path = existingResource.split(`/${collection}`)[0];\n const pathToResource = join(path, collection);\n\n await rmMessageById(directory)(_message.id, _message.version, true);\n await writeMessage(pathToResource)(message);\n };\n","import path, { join } from 'node:path';\nimport { readMdxFile } from './internal/utils';\nimport type { CustomDoc } from './types';\nimport fsSync from 'node:fs';\nimport fs from 'node:fs/promises';\nimport matter from 'gray-matter';\nimport { getResources } from './internal/resources';\nimport slugify from 'slugify';\n\n/**\n * Returns a custom doc from EventCatalog by the given file path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getCustomDoc } = utils('/path/to/eventcatalog');\n *\n * // Gets the custom doc by the given file path\n * const customDoc = await getCustomDoc('/guides/inventory-management.mdx');\n * ```\n */\nexport const getCustomDoc =\n (directory: string) =>\n async (filePath: string): Promise<CustomDoc | undefined> => {\n const fullPath = path.join(directory, filePath);\n const fullPathWithExtension = fullPath.endsWith('.mdx') ? fullPath : `${fullPath}.mdx`;\n const fileExists = fsSync.existsSync(fullPathWithExtension);\n if (!fileExists) {\n return undefined;\n }\n return readMdxFile(fullPathWithExtension) as Promise<CustomDoc>;\n };\n\n/**\n * Returns all custom docs for the project.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getCustomDocs } = utils('/path/to/eventcatalog');\n *\n * // Gets all custom docs from the catalog\n * const customDocs = await getCustomDocs();\n *\n * // Gets all custom docs from the given path\n * const customDocs = await getCustomDocs({ path: '/guides' });\n * ```\n */\nexport const getCustomDocs =\n (directory: string) =>\n async (options?: { path?: string }): Promise<CustomDoc[]> => {\n if (options?.path) {\n const pattern = `${directory}/${options.path}/**/*.{md,mdx}`;\n return getResources(directory, { type: 'docs', pattern }) as Promise<CustomDoc[]>;\n }\n return getResources(directory, { type: 'docs', pattern: `${directory}/**/*.{md,mdx}` }) as Promise<CustomDoc[]>;\n };\n\n/**\n * Write a custom doc to EventCatalog.\n *\n * You can optionally override the path of the custom doc.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeCustomDoc } = utils('/path/to/eventcatalog');\n *\n * // Write a custom doc to the catalog\n * // Custom doc would be written to docs/inventory-management.mdx\n * await writeCustomDoc({\n * title: 'Inventory Management',\n * summary: 'This is a summary',\n * owners: ['John Doe'],\n * badges: [{ content: 'Badge', backgroundColor: 'red', textColor: 'white' }],\n * markdown: '# Hello world',\n * fileName: 'inventory-management',\n * });\n *\n * // Write a custom doc to the catalog but override the path\n * // Custom doc would be written to docs/guides/inventory-management/introduction.mdx\n * await writeCustomDoc({\n * title: 'Inventory Management',\n * summary: 'This is a summary',\n * owners: ['John Doe'],\n * badges: [{ content: 'Badge', backgroundColor: 'red', textColor: 'white' }],\n * markdown: '# Hello world',\n * fileName: 'introduction',\n * }, { path: \"/guides/inventory-management\"});\n * ```\n */\nexport const writeCustomDoc =\n (directory: string) =>\n async (customDoc: CustomDoc, options: { path?: string } = { path: '' }): Promise<void> => {\n const { fileName, ...rest } = customDoc;\n const name = fileName || slugify(customDoc.title, { lower: true });\n const withExtension = name.endsWith('.mdx') ? name : `${name}.mdx`;\n const fullPath = path.join(directory, options.path || '', withExtension);\n\n fsSync.mkdirSync(path.dirname(fullPath), { recursive: true });\n const document = matter.stringify(customDoc.markdown.trim(), rest);\n fsSync.writeFileSync(fullPath, document);\n };\n\n/**\n * Delete a custom doc by its' path\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmCustomDoc } = utils('/path/to/eventcatalog');\n *\n * // removes a custom doc at the given path\n * // Removes the custom doc at docs/guides/inventory-management/introduction.mdx\n * await rmCustomDoc('/guides/inventory-management/introduction');\n * ```\n */\nexport const rmCustomDoc = (directory: string) => async (filePath: string) => {\n const withExtension = filePath.endsWith('.mdx') ? filePath : `${filePath}.mdx`;\n await fs.rm(join(directory, withExtension), { recursive: true });\n};\n","import fs from 'node:fs/promises';\nimport fsSync from 'node:fs';\nimport { join } from 'node:path';\nimport type { Team } from './types';\nimport matter from 'gray-matter';\nimport { getFiles } from './internal/utils';\n\n/**\n * Returns a team from EventCatalog.\n *\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getTeam } = utils('/path/to/eventcatalog');\n *\n * // Gets the team with the given id\n * const team = await getTeam('eventcatalog-core-team');\n *\n * ```\n */\nexport const getTeam =\n (catalogDir: string) =>\n async (id: string): Promise<Team | undefined> => {\n const files = await getFiles(`${catalogDir}/${id}.{md,mdx}`);\n\n if (files.length == 0) return undefined;\n const file = files[0];\n\n const { data, content } = matter.read(file);\n return {\n ...data,\n id: data.id,\n name: data.name,\n markdown: content.trim(),\n } as Team;\n };\n\n/**\n * Returns all teams from EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getTeams } = utils('/path/to/eventcatalog');\n *\n * // Gets all teams from the catalog\n * const channels = await getTeams();\n *\n * ```\n */\nexport const getTeams =\n (catalogDir: string) =>\n async (options?: {}): Promise<Team[]> => {\n const files = await getFiles(`${catalogDir}/teams/*.{md,mdx}`);\n if (files.length === 0) return [];\n\n return files.map((file) => {\n const { data, content } = matter.read(file);\n return {\n ...data,\n id: data.id,\n name: data.name,\n markdown: content.trim(),\n } as Team;\n });\n };\n\n/**\n * Write a team to EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeTeam } = utils('/path/to/eventcatalog');\n *\n * // Write a team to the catalog\n * // team would be written to teams/EventCatalogCoreTeam\n * await writeTeam({\n * id: 'eventcatalog-core-team',\n * name: 'EventCatalogCoreTeam',\n * members: ['dboyne', 'asmith', 'msmith'],\n * email: 'test@test.com',\n * slackDirectMessageUrl: https://yourteam.slack.com/channels/boyney123\n * });\n *\n * // Write a team to the catalog and override the existing content (if there is any)\n * await writeTeam({\n * id: 'eventcatalog-core-team',\n * name: 'EventCatalogCoreTeam',\n * members: ['dboyne', 'asmith', 'msmith'],\n * email: 'test@test.com',\n * slackDirectMessageUrl: https://yourteam.slack.com/channels/boyney123\n * }, { override: true });\n *\n * ```\n */\nexport const writeTeam =\n (catalogDir: string) =>\n async (team: Team, options: { override?: boolean } = {}) => {\n const resource: Team = { ...team };\n\n // Get the path\n const currentTeam = await getTeam(catalogDir)(resource.id);\n const exists = currentTeam !== undefined;\n\n if (exists && !options.override) {\n throw new Error(`Failed to write ${resource.id} (team) as it already exists`);\n }\n\n const { markdown, ...frontmatter } = resource;\n\n const document = matter.stringify(markdown, frontmatter);\n fsSync.mkdirSync(join(catalogDir, ''), { recursive: true });\n fsSync.writeFileSync(join(catalogDir, '', `${resource.id}.mdx`), document);\n };\n\n/**\n * Delete a team by it's id.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmTeamById } = utils('/path/to/eventcatalog');\n *\n * // deletes the EventCatalogCoreTeam team\n * await rmTeamById('eventcatalog-core-team');\n *\n * ```\n */\nexport const rmTeamById = (catalogDir: string) => async (id: string) => {\n await fs.rm(join(catalogDir, `${id}.mdx`), { recursive: true });\n};\n","import fs from 'node:fs/promises';\nimport fsSync from 'node:fs';\nimport { join } from 'node:path';\nimport type { User } from './types';\nimport matter from 'gray-matter';\nimport { getFiles } from './internal/utils';\n\n/**\n * Returns a user from EventCatalog.\n *\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getUser } = utils('/path/to/eventcatalog');\n *\n * // Gets the user with the given id\n * const user = await getUser('eventcatalog-core-user');\n *\n * ```\n */\nexport const getUser =\n (catalogDir: string) =>\n async (id: string): Promise<User | undefined> => {\n const files = await getFiles(`${catalogDir}/${id}.{md,mdx}`);\n\n if (files.length == 0) return undefined;\n const file = files[0];\n\n const { data, content } = matter.read(file);\n return {\n ...data,\n id: data.id,\n name: data.name,\n avatarUrl: data.avatarUrl,\n markdown: content.trim(),\n } as User;\n };\n\n/**\n * Returns all users from EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getUsers } = utils('/path/to/eventcatalog');\n *\n * // Gets all users from the catalog\n * const channels = await getUsers();\n *\n * ```\n */\nexport const getUsers =\n (catalogDir: string) =>\n async (options?: {}): Promise<User[]> => {\n const files = await getFiles(`${catalogDir}/users/*.{md,mdx}`);\n if (files.length === 0) return [];\n\n return files.map((file) => {\n const { data, content } = matter.read(file);\n return {\n ...data,\n id: data.id,\n name: data.name,\n avatarUrl: data.avatarUrl,\n markdown: content.trim(),\n } as User;\n });\n };\n\n/**\n * Write a user to EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeUser } = utils('/path/to/eventcatalog');\n *\n * // Write a user to the catalog\n * // user would be written to users/eventcatalog-tech-lead\n * await writeUser({\n * id: 'eventcatalog-tech-lead',\n * name: 'EventCatalog Tech Lead',\n * email: 'test@test.com',\n * avatarUrl: 'https://pbs.twimg.com/profile_images/1262283153563140096/DYRDqKg6_400x400.png',\n * slackDirectMessageUrl: https://yourteam.slack.com/channels/boyney123\n * });\n *\n * // Write a team to the catalog and override the existing content (if there is any)\n * await writeUser({\n * id: 'eventcatalog-tech-lead',\n * name: 'EventCatalog Tech Lead',\n * email: 'test@test.com',\n * avatarUrl: 'https://pbs.twimg.com/profile_images/1262283153563140096/DYRDqKg6_400x400.png',\n * slackDirectMessageUrl: https://yourteam.slack.com/channels/boyney123\n * }, { override: true });\n *\n * ```\n */\nexport const writeUser =\n (catalogDir: string) =>\n async (user: User, options: { override?: boolean } = {}) => {\n const resource: User = { ...user };\n\n // Get the path\n const currentUser = await getUser(catalogDir)(resource.id);\n const exists = currentUser !== undefined;\n\n if (exists && !options.override) {\n throw new Error(`Failed to write ${resource.id} (user) as it already exists`);\n }\n\n const { markdown, ...frontmatter } = resource;\n\n const document = matter.stringify(markdown, frontmatter);\n fsSync.mkdirSync(join(catalogDir, ''), { recursive: true });\n fsSync.writeFileSync(join(catalogDir, '', `${resource.id}.mdx`), document);\n };\n\n/**\n * Delete a user by it's id.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmUserById } = utils('/path/to/eventcatalog');\n *\n * // deletes the user with id eventcatalog-core-user\n * await rmUserById('eventcatalog-core-user');\n *\n * ```\n */\nexport const rmUserById = (catalogDir: string) => async (id: string) => {\n fsSync.rmSync(join(catalogDir, `${id}.mdx`), { recursive: true });\n};\n"],"mappings":"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","names":["fs","path","join","join","fs","join","path","match","dirname","join","matter","fsSync","satisfies","dirname","file","join","path","join","path","fs","fs","join","join","path","fs","fs","join","join","path","fs","fs","join","dirname","path","join","fs","dirname","fs","join","fsSync","matter","path","fs","join","fsSync","fs","join","path","fs","join","path","join","fsSync","fs","matter","path","fsSync","matter","fs","join","fs","fsSync","join","matter","matter","fsSync","join","fs","fsSync","join","matter","matter","fsSync","join","path","join","fs","join","path","getDomains","getServices","getEvents","getQueries","getCommands","getChannels","getTeams","getUsers"]}
|
|
1
|
+
{"version":3,"sources":["../src/eventcatalog.ts","../src/index.ts","../src/events.ts","../src/internal/utils.ts","../src/internal/resources.ts","../src/commands.ts","../src/queries.ts","../src/services.ts","../src/domains.ts","../src/channels.ts","../src/custom-docs.ts","../src/teams.ts","../src/users.ts"],"sourcesContent":["import type { Domain, Service, Event, Query, Command, Team, CustomDoc, User, Channel } from './types';\nimport fs from 'fs';\nimport path, { join } from 'node:path';\nimport utils from './index';\nimport { getResourcePath } from './internal/resources';\ntype ExportedResource<T = any> = T & {\n directory: string;\n};\n\nexport type EventCatalogObject = {\n version: string;\n catalogVersion: string;\n createdAt: string;\n resources: {\n domains?: ExportedResource<Domain>[];\n services?: ExportedResource<Service>[];\n messages?: {\n events?: ExportedResource<Event>[];\n queries?: ExportedResource<Query>[];\n commands?: ExportedResource<Command>[];\n };\n teams?: ExportedResource<Team>[];\n users?: ExportedResource<User>[];\n channels?: ExportedResource<Channel>[];\n customDocs?: ExportedResource<CustomDoc>[];\n };\n};\n\nconst DUMP_VERSION = '0.0.1';\n\nconst getEventCatalogVersion = async (catalogDir: string) => {\n // Read package.json in the catalogDir\n try {\n const packageJson = fs.readFileSync(join(catalogDir, 'package.json'), 'utf8');\n const packageJsonObject = JSON.parse(packageJson);\n return packageJsonObject['dependencies']['@eventcatalog/core'];\n } catch (error) {\n return 'unknown';\n }\n};\n\nconst hydrateResource = async (\n catalogDir: string,\n resources: any[],\n { attachSchema = false }: { attachSchema?: boolean } = {}\n) => {\n return await Promise.all(\n resources.map(async (resource) => {\n // Get resource from directory\n // Get resource from directory\n const resourcePath = await getResourcePath(catalogDir, resource.id, resource.version);\n let schema = '';\n\n if (resource.schemaPath && resourcePath?.fullPath) {\n const pathToSchema = path.join(path.dirname(resourcePath?.fullPath), resource.schemaPath);\n if (fs.existsSync(pathToSchema)) {\n schema = fs.readFileSync(pathToSchema, 'utf8');\n }\n }\n\n // const hasSchemaPath = resource.data.schemaPath;\n\n const eventcatalog = schema ? { directory: resourcePath?.directory, schema } : { directory: resourcePath?.directory };\n\n return {\n ...resource,\n _eventcatalog: eventcatalog,\n };\n })\n );\n};\n\nconst filterCollection = (\n collection: any[],\n options?: {\n includeMarkdown?: boolean;\n }\n) => {\n return collection.map((item) => ({\n ...item,\n markdown: options?.includeMarkdown ? item.markdown : undefined,\n }));\n};\n/**\n * Dumps the catalog to a JSON file.\n *\n * @param directory - The directory of the catalog.\n * @returns A JSON file with the catalog.\n */\nexport const dumpCatalog =\n (directory: string) =>\n async (options?: { includeMarkdown?: boolean }): Promise<EventCatalogObject> => {\n const { getDomains, getServices, getEvents, getQueries, getCommands, getChannels, getTeams, getUsers } = utils(directory);\n\n const { includeMarkdown = true } = options || {};\n\n const domains = await getDomains();\n const services = await getServices();\n\n const events = await getEvents();\n const commands = await getCommands();\n const queries = await getQueries();\n const teams = await getTeams();\n const users = await getUsers();\n const channels = await getChannels();\n\n const [\n hydratedDomains,\n hydratedServices,\n hydratedEvents,\n hydratedQueries,\n hydratedCommands,\n hydratedTeams,\n hydratedUsers,\n hydratedChannels,\n ] = await Promise.all([\n hydrateResource(directory, domains),\n hydrateResource(directory, services),\n hydrateResource(directory, events),\n hydrateResource(directory, queries),\n hydrateResource(directory, commands),\n hydrateResource(directory, teams),\n hydrateResource(directory, users),\n hydrateResource(directory, channels),\n ]);\n\n return {\n version: DUMP_VERSION,\n catalogVersion: await getEventCatalogVersion(directory),\n createdAt: new Date().toISOString(),\n resources: {\n domains: filterCollection(hydratedDomains, { includeMarkdown }),\n services: filterCollection(hydratedServices, { includeMarkdown }),\n messages: {\n events: filterCollection(hydratedEvents, { includeMarkdown }),\n queries: filterCollection(hydratedQueries, { includeMarkdown }),\n commands: filterCollection(hydratedCommands, { includeMarkdown }),\n },\n teams: filterCollection(hydratedTeams, { includeMarkdown }),\n users: filterCollection(hydratedUsers, { includeMarkdown }),\n channels: filterCollection(hydratedChannels, { includeMarkdown }),\n },\n };\n };\n","import { join } from 'node:path';\nimport {\n rmEvent,\n rmEventById,\n writeEvent,\n writeEventToService,\n versionEvent,\n getEvent,\n addFileToEvent,\n addSchemaToEvent,\n eventHasVersion,\n getEvents,\n} from './events';\nimport {\n rmCommand,\n rmCommandById,\n writeCommand,\n writeCommandToService,\n versionCommand,\n getCommand,\n getCommands,\n addFileToCommand,\n addSchemaToCommand,\n commandHasVersion,\n} from './commands';\nimport {\n rmQuery,\n rmQueryById,\n writeQuery,\n writeQueryToService,\n versionQuery,\n getQuery,\n getQueries,\n addFileToQuery,\n addSchemaToQuery,\n queryHasVersion,\n} from './queries';\nimport {\n writeService,\n writeServiceToDomain,\n getService,\n versionService,\n rmService,\n rmServiceById,\n addFileToService,\n addMessageToService,\n serviceHasVersion,\n getSpecificationFilesForService,\n writeVersionedService,\n getServices,\n} from './services';\nimport {\n writeDomain,\n getDomain,\n getDomains,\n versionDomain,\n rmDomain,\n rmDomainById,\n addFileToDomain,\n addUbiquitousLanguageToDomain,\n domainHasVersion,\n addServiceToDomain,\n getUbiquitousLanguageFromDomain,\n} from './domains';\n\nimport {\n rmChannel,\n rmChannelById,\n writeChannel,\n versionChannel,\n getChannel,\n getChannels,\n channelHasVersion,\n addMessageToChannel,\n} from './channels';\n\nimport { dumpCatalog } from './eventcatalog';\n\nimport { writeCustomDoc, getCustomDoc, getCustomDocs, rmCustomDoc } from './custom-docs';\n\nimport { writeTeam, getTeam, getTeams, rmTeamById } from './teams';\n\nimport { writeUser, getUser, getUsers, rmUserById } from './users';\n\n/**\n * Init the SDK for EventCatalog\n *\n * @param path - The path to the EventCatalog directory\n *\n */\nexport default (path: string) => {\n return {\n /**\n * Returns an events from EventCatalog\n * @param id - The id of the event to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Event|Undefined\n */\n getEvent: getEvent(join(path)),\n /**\n * Returns all events from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Event[]|Undefined\n */\n getEvents: getEvents(join(path)),\n /**\n * Adds an event to EventCatalog\n *\n * @param event - The event to write\n * @param options - Optional options to write the event\n *\n */\n writeEvent: writeEvent(join(path, 'events')),\n /**\n * Adds an event to a service in EventCatalog\n *\n * @param event - The event to write to the service\n * @param service - The service and it's id to write to the event to\n * @param options - Optional options to write the event\n *\n */\n writeEventToService: writeEventToService(join(path)),\n /**\n * Remove an event to EventCatalog (modeled on the standard POSIX rm utility)\n *\n * @param path - The path to your event, e.g. `/Inventory/InventoryAdjusted`\n *\n */\n rmEvent: rmEvent(join(path, 'events')),\n /**\n * Remove an event by an Event id\n *\n * @param id - The id of the event you want to remove\n *\n */\n rmEventById: rmEventById(join(path)),\n /**\n * Moves a given event id to the version directory\n * @param directory\n */\n versionEvent: versionEvent(join(path)),\n /**\n * Adds a file to the given event\n * @param id - The id of the event to add the file to\n * @param file - File contents to add including the content and the file name\n * @param version - Optional version of the event to add the file to\n * @returns\n */\n addFileToEvent: addFileToEvent(join(path)),\n /**\n * Adds a schema to the given event\n * @param id - The id of the event to add the schema to\n * @param schema - Schema contents to add including the content and the file name\n * @param version - Optional version of the event to add the schema to\n * @returns\n */\n addSchemaToEvent: addSchemaToEvent(join(path)),\n /**\n * Check to see if an event version exists\n * @param id - The id of the event\n * @param version - The version of the event (supports semver)\n * @returns\n */\n eventHasVersion: eventHasVersion(join(path)),\n\n /**\n * ================================\n * Commands\n * ================================\n */\n\n /**\n * Returns a command from EventCatalog\n * @param id - The id of the command to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Command|Undefined\n */\n getCommand: getCommand(join(path)),\n /**\n * Returns all commands from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Command[]|Undefined\n */\n getCommands: getCommands(join(path)),\n /**\n * Adds an command to EventCatalog\n *\n * @param command - The command to write\n * @param options - Optional options to write the command\n *\n */\n writeCommand: writeCommand(join(path, 'commands')),\n\n /**\n * Adds a command to a service in EventCatalog\n *\n * @param command - The command to write to the service\n * @param service - The service and it's id to write to the command to\n * @param options - Optional options to write the command\n *\n */\n writeCommandToService: writeCommandToService(join(path)),\n\n /**\n * Remove an command to EventCatalog (modeled on the standard POSIX rm utility)\n *\n * @param path - The path to your command, e.g. `/Inventory/InventoryAdjusted`\n *\n */\n rmCommand: rmCommand(join(path, 'commands')),\n /**\n * Remove an command by an Event id\n *\n * @param id - The id of the command you want to remove\n *\n */\n rmCommandById: rmCommandById(join(path)),\n /**\n * Moves a given command id to the version directory\n * @param directory\n */\n versionCommand: versionCommand(join(path)),\n /**\n * Adds a file to the given command\n * @param id - The id of the command to add the file to\n * @param file - File contents to add including the content and the file name\n * @param version - Optional version of the command to add the file to\n * @returns\n */\n addFileToCommand: addFileToCommand(join(path)),\n /**\n * Adds a schema to the given command\n * @param id - The id of the command to add the schema to\n * @param schema - Schema contents to add including the content and the file name\n * @param version - Optional version of the command to add the schema to\n * @returns\n */\n addSchemaToCommand: addSchemaToCommand(join(path)),\n\n /**\n * Check to see if a command version exists\n * @param id - The id of the command\n * @param version - The version of the command (supports semver)\n * @returns\n */\n commandHasVersion: commandHasVersion(join(path)),\n\n /**\n * ================================\n * Queries\n * ================================\n */\n\n /**\n * Returns a query from EventCatalog\n * @param id - The id of the query to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Query|Undefined\n */\n getQuery: getQuery(join(path)),\n /**\n * Returns all queries from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Query[]|Undefined\n */\n getQueries: getQueries(join(path)),\n /**\n * Adds a query to EventCatalog\n *\n * @param query - The query to write\n * @param options - Optional options to write the event\n *\n */\n writeQuery: writeQuery(join(path, 'queries')),\n /**\n * Adds a query to a service in EventCatalog\n *\n * @param query - The query to write to the service\n * @param service - The service and it's id to write to the query to\n * @param options - Optional options to write the query\n *\n */\n writeQueryToService: writeQueryToService(join(path)),\n /**\n * Remove an query to EventCatalog (modeled on the standard POSIX rm utility)\n *\n * @param path - The path to your query, e.g. `/Orders/GetOrder`\n *\n */\n rmQuery: rmQuery(join(path, 'queries')),\n /**\n * Remove a query by a Query id\n *\n * @param id - The id of the query you want to remove\n *\n */\n rmQueryById: rmQueryById(join(path)),\n /**\n * Moves a given query id to the version directory\n * @param directory\n */\n versionQuery: versionQuery(join(path)),\n /**\n * Adds a file to the given query\n * @param id - The id of the query to add the file to\n * @param file - File contents to add including the content and the file name\n * @param version - Optional version of the query to add the file to\n * @returns\n */\n addFileToQuery: addFileToQuery(join(path)),\n /**\n * Adds a schema to the given query\n * @param id - The id of the query to add the schema to\n * @param schema - Schema contents to add including the content and the file name\n * @param version - Optional version of the query to add the schema to\n * @returns\n */\n addSchemaToQuery: addSchemaToQuery(join(path)),\n /**\n * Check to see if an query version exists\n * @param id - The id of the query\n * @param version - The version of the query (supports semver)\n * @returns\n */\n queryHasVersion: queryHasVersion(join(path)),\n\n /**\n * ================================\n * Channels\n * ================================\n */\n\n /**\n * Returns a channel from EventCatalog\n * @param id - The id of the channel to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Channel|Undefined\n */\n getChannel: getChannel(join(path)),\n /**\n * Returns all channels from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Channel[]|Undefined\n */\n getChannels: getChannels(join(path)),\n /**\n * Adds an channel to EventCatalog\n *\n * @param command - The channel to write\n * @param options - Optional options to write the channel\n *\n */\n writeChannel: writeChannel(join(path, 'channels')),\n\n /**\n * Remove an channel to EventCatalog (modeled on the standard POSIX rm utility)\n *\n * @param path - The path to your channel, e.g. `/Inventory/InventoryAdjusted`\n *\n */\n rmChannel: rmChannel(join(path, 'channels')),\n /**\n * Remove an channel by an Event id\n *\n * @param id - The id of the channel you want to remove\n *\n */\n rmChannelById: rmChannelById(join(path)),\n /**\n * Moves a given channel id to the version directory\n * @param directory\n */\n versionChannel: versionChannel(join(path)),\n\n /**\n * Check to see if a channel version exists\n * @param id - The id of the channel\n * @param version - The version of the channel (supports semver)\n * @returns\n */\n channelHasVersion: channelHasVersion(join(path)),\n\n /**\n * Add a channel to an event\n *\n * Optionally specify a version to add the channel to a specific version of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addEventToChannel } = utils('/path/to/eventcatalog');\n *\n * // adds a new event (InventoryUpdatedEvent) to the inventory.{env}.events channel\n * await addEventToChannel('inventory.{env}.events channel', { id: 'InventoryUpdatedEvent', version: '2.0.0', parameters: { env: 'dev' } });\n *\n * ```\n */\n addEventToChannel: addMessageToChannel(join(path), 'events'),\n /**\n * Add a channel to an command\n *\n * Optionally specify a version to add the channel to a specific version of the command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addCommandToChannel } = utils('/path/to/eventcatalog');\n *\n * // adds a new command (UpdateInventory) to the inventory.{env}.events channel\n * await addCommandToChannel('inventory.{env}.events channel', { id: 'UpdateInventory', version: '2.0.0', parameters: { env: 'dev' } });\n *\n * ```\n */\n addCommandToChannel: addMessageToChannel(join(path), 'commands'),\n\n /**\n * Add a channel to an query\n *\n * Optionally specify a version to add the channel to a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addQueryToChannel } = utils('/path/to/eventcatalog');\n *\n * // adds a new query (GetInventory) to the inventory.{env}.events channel\n * await addQueryToChannel('inventory.{env}.events channel', { id: 'GetInventory', version: '2.0.0', parameters: { env: 'dev' } });\n *\n * ```\n */\n addQueryToChannel: addMessageToChannel(join(path), 'queries'),\n\n /**\n * ================================\n * SERVICES\n * ================================\n */\n\n /**\n * Adds a service to EventCatalog\n *\n * @param service - The service to write\n * @param options - Optional options to write the event\n *\n */\n writeService: writeService(join(path, 'services')),\n\n /**\n * Adds a versioned service to EventCatalog\n *\n * @param service - The service to write\n *\n */\n writeVersionedService: writeVersionedService(join(path, 'services')),\n\n /**\n * Adds a service to a domain in EventCatalog\n *\n * @param service - The service to write\n * @param domain - The domain to add the service to\n * @param options - Optional options to write the event\n *\n */\n writeServiceToDomain: writeServiceToDomain(join(path, 'domains')),\n /**\n * Returns a service from EventCatalog\n * @param id - The id of the service to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Service|Undefined\n */\n getService: getService(join(path)),\n /**\n * Returns all services from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Service[]|Undefined\n */\n getServices: getServices(join(path)),\n /**\n * Moves a given service id to the version directory\n * @param directory\n */\n versionService: versionService(join(path)),\n /**\n * Remove a service from EventCatalog (modeled on the standard POSIX rm utility)\n *\n * @param path - The path to your service, e.g. `/InventoryService`\n *\n */\n rmService: rmService(join(path, 'services')),\n /**\n * Remove an service by an service id\n *\n * @param id - The id of the service you want to remove\n *\n */\n rmServiceById: rmServiceById(join(path)),\n /**\n * Adds a file to the given service\n * @param id - The id of the service to add the file to\n * @param file - File contents to add including the content and the file name\n * @param version - Optional version of the service to add the file to\n * @returns\n */\n addFileToService: addFileToService(join(path)),\n\n /**\n * Returns the specifications for a given service\n * @param id - The id of the service to retrieve the specifications for\n * @param version - Optional version of the service\n * @returns\n */\n getSpecificationFilesForService: getSpecificationFilesForService(join(path)),\n\n /**\n * Check to see if a service version exists\n * @param id - The id of the service\n * @param version - The version of the service (supports semver)\n * @returns\n */\n serviceHasVersion: serviceHasVersion(join(path)),\n\n /**\n * Add an event to a service by it's id.\n *\n * Optionally specify a version to add the event to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addEventToService } = utils('/path/to/eventcatalog');\n *\n * // adds a new event (InventoryUpdatedEvent) that the InventoryService will send\n * await addEventToService('InventoryService', 'sends', { event: 'InventoryUpdatedEvent', version: '2.0.0' });\n *\n * // adds a new event (OrderComplete) that the InventoryService will receive\n * await addEventToService('InventoryService', 'receives', { event: 'OrderComplete', version: '2.0.0' });\n *\n * ```\n */\n addEventToService: addMessageToService(join(path)),\n /**\n * Add a command to a service by it's id.\n *\n * Optionally specify a version to add the event to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addCommandToService } = utils('/path/to/eventcatalog');\n *\n * // adds a new command (UpdateInventoryCommand) that the InventoryService will send\n * await addCommandToService('InventoryService', 'sends', { command: 'UpdateInventoryCommand', version: '2.0.0' });\n *\n * // adds a new command (VerifyInventory) that the InventoryService will receive\n * await addCommandToService('InventoryService', 'receives', { command: 'VerifyInventory', version: '2.0.0' });\n *\n * ```\n */\n addCommandToService: addMessageToService(join(path)),\n /**\n * Add a query to a service by it's id.\n *\n * Optionally specify a version to add the event to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addQueryToService } = utils('/path/to/eventcatalog');\n *\n * // adds a new query (UpdateInventory) that the InventoryService will send\n * await addQueryToService('InventoryService', 'sends', { command: 'UpdateInventory', version: '2.0.0' });\n *\n * // adds a new command (VerifyInventory) that the InventoryService will receive\n * await addQueryToService('InventoryService', 'receives', { command: 'VerifyInventory', version: '2.0.0' });\n *\n * ```\n */\n addQueryToService: addMessageToService(join(path)),\n\n /**\n * ================================\n * Domains\n * ================================\n */\n\n /**\n * Adds a domain to EventCatalog\n *\n * @param domain - The domain to write\n * @param options - Optional options to write the event\n *\n */\n writeDomain: writeDomain(join(path, 'domains')),\n\n /**\n * Returns a domain from EventCatalog\n * @param id - The id of the domain to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Domain|Undefined\n */\n getDomain: getDomain(join(path, 'domains')),\n /**\n * Returns all domains from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Domain[]|Undefined\n */\n getDomains: getDomains(join(path)),\n /**\n * Moves a given domain id to the version directory\n * @param directory\n */\n versionDomain: versionDomain(join(path, 'domains')),\n /**\n * Remove a domain from EventCatalog (modeled on the standard POSIX rm utility)\n *\n * @param path - The path to your domain, e.g. `/Payment`\n *\n */\n rmDomain: rmDomain(join(path, 'domains')),\n /**\n * Remove an service by an domain id\n *\n * @param id - The id of the domain you want to remove\n *\n */\n rmDomainById: rmDomainById(join(path, 'domains')),\n /**\n * Adds a file to the given domain\n * @param id - The id of the domain to add the file to\n * @param file - File contents to add including the content and the file name\n * @param version - Optional version of the domain to add the file to\n * @returns\n */\n addFileToDomain: addFileToDomain(join(path, 'domains')),\n\n /**\n * Adds an ubiquitous language dictionary to a domain\n * @param id - The id of the domain to add the ubiquitous language to\n * @param ubiquitousLanguageDictionary - The ubiquitous language dictionary to add\n * @param version - Optional version of the domain to add the ubiquitous language to\n */\n addUbiquitousLanguageToDomain: addUbiquitousLanguageToDomain(join(path, 'domains')),\n\n /**\n * Get the ubiquitous language dictionary from a domain\n * @param id - The id of the domain to get the ubiquitous language from\n * @param version - Optional version of the domain to get the ubiquitous language from\n * @returns\n */\n getUbiquitousLanguageFromDomain: getUbiquitousLanguageFromDomain(join(path, 'domains')),\n\n /**\n * Check to see if a domain version exists\n * @param id - The id of the domain\n * @param version - The version of the domain (supports semver)\n * @returns\n */\n domainHasVersion: domainHasVersion(join(path)),\n\n /**\n * Adds a given service to a domain\n * @param id - The id of the domain\n * @param service - The id and version of the service to add\n * @param version - (Optional) The version of the domain to add the service to\n * @returns\n */\n addServiceToDomain: addServiceToDomain(join(path, 'domains')),\n\n /**\n * ================================\n * Teams\n * ================================\n */\n /**\n * Adds a team to EventCatalog\n *\n * @param team - The team to write\n * @param options - Optional options to write the team\n *\n */\n writeTeam: writeTeam(join(path, 'teams')),\n /**\n * Returns a team from EventCatalog\n * @param id - The id of the team to retrieve\n * @returns Team|Undefined\n */\n getTeam: getTeam(join(path, 'teams')),\n /**\n * Returns all teams from EventCatalog\n * @returns Team[]|Undefined\n */\n getTeams: getTeams(join(path)),\n /**\n * Remove a team by the team id\n *\n * @param id - The id of the team you want to remove\n *\n */\n rmTeamById: rmTeamById(join(path, 'teams')),\n\n /**\n * ================================\n * Users\n * ================================\n */\n /**\n * Adds a user to EventCatalog\n *\n * @param user - The user to write\n * @param options - Optional options to write the user\n *\n */\n writeUser: writeUser(join(path, 'users')),\n /**\n * Returns a user from EventCatalog\n * @param id - The id of the user to retrieve\n * @returns User|Undefined\n */\n getUser: getUser(join(path, 'users')),\n /**\n * Returns all user from EventCatalog\n * @returns User[]|Undefined\n */\n getUsers: getUsers(join(path)),\n /**\n * Remove a user by the user id\n *\n * @param id - The id of the user you want to remove\n *\n */\n rmUserById: rmUserById(join(path, 'users')),\n\n /**\n * ================================\n * Custom Docs\n * ================================\n */\n\n /**\n * Returns a custom doc from EventCatalog\n * @param path - The path to the custom doc to retrieve\n * @returns CustomDoc|Undefined\n */\n getCustomDoc: getCustomDoc(join(path, 'docs')),\n /**\n * Returns all custom docs from EventCatalog\n * @param options - Optional options to get custom docs from a specific path\n * @returns CustomDoc[]|Undefined\n */\n getCustomDocs: getCustomDocs(join(path, 'docs')),\n /**\n * Writes a custom doc to EventCatalog\n * @param customDoc - The custom doc to write\n * @param options - Optional options to write the custom doc\n *\n */\n writeCustomDoc: writeCustomDoc(join(path, 'docs')),\n\n /**\n * Removes a custom doc from EventCatalog\n * @param path - The path to the custom doc to remove\n *\n */\n rmCustomDoc: rmCustomDoc(join(path, 'docs')),\n\n /**\n * Dumps the catalog to a JSON file.\n * @param directory - The directory to dump the catalog to\n * @returns A JSON file with the catalog\n */\n dumpCatalog: dumpCatalog(join(path)),\n };\n};\n","import fs from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { findFileById } from './internal/utils';\nimport type { Event } from './types';\nimport {\n addFileToResource,\n getResource,\n getResourcePath,\n getResources,\n rmResourceById,\n versionResource,\n writeResource,\n} from './internal/resources';\n\n/**\n * Returns an event from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the event\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getEvent } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the event\n * const event = await getEvent('InventoryAdjusted');\n *\n * // Gets a version of the event\n * const event = await getEvent('InventoryAdjusted', '0.0.1');\n * ```\n */\nexport const getEvent =\n (directory: string) =>\n async (id: string, version?: string): Promise<Event> =>\n getResource(directory, id, version, { type: 'event' }) as Promise<Event>;\n\n/**\n * Returns all events from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the events.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getEvents } = utils('/path/to/eventcatalog');\n *\n * // Gets all events (and versions) from the catalog\n * const events = await getEvents();\n *\n * // Gets all events (only latest version) from the catalog\n * const events = await getEvents({ latestOnly: true });\n * ```\n */\nexport const getEvents =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Event[]> =>\n getResources(directory, { type: 'events', ...options }) as Promise<Event[]>;\n\n/**\n * Write an event to EventCatalog.\n *\n * You can optionally overide the path of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeEvent } = utils('/path/to/eventcatalog');\n *\n * // Write an event to the catalog\n * // Event would be written to events/InventoryAdjusted\n * await writeEvent({\n * id: 'InventoryAdjusted',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * });\n *\n * // Write an event to the catalog but override the path\n * // Event would be written to events/Inventory/InventoryAdjusted\n * await writeEvent({\n * id: 'InventoryAdjusted',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { path: \"/Inventory/InventoryAdjusted\"});\n *\n * // Write a event to the catalog and override the existing content (if there is any)\n * await writeEvent({\n * id: 'InventoryAdjusted',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { override: true });\n *\n * // Write a event to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeEvent({\n * id: 'InventoryAdjusted',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeEvent =\n (directory: string) =>\n async (\n event: Event,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...event }, { ...options, type: 'event' });\n/**\n * Write an event to a service in EventCatalog.\n *\n * You can optionally override the path of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeEventToService } = utils('/path/to/eventcatalog');\n *\n * // Write an event to a given service in the catalog\n * // Event would be written to services/Inventory/events/InventoryAdjusted\n * await writeEventToService({\n * id: 'InventoryAdjusted',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { id: 'Inventory' });\n * ```\n */\nexport const writeEventToService =\n (directory: string) =>\n async (\n event: Event,\n service: { id: string; version?: string },\n options: { path?: string; format?: 'md' | 'mdx' } = { path: '', format: 'mdx' }\n ) => {\n const resourcePath = await getResourcePath(directory, service.id, service.version);\n if (!resourcePath) {\n throw new Error('Service not found');\n }\n\n let pathForEvent =\n service.version && service.version !== 'latest'\n ? `${resourcePath.directory}/versioned/${service.version}/events`\n : `${resourcePath.directory}/events`;\n pathForEvent = join(pathForEvent, event.id);\n await writeResource(directory, { ...event }, { ...options, path: pathForEvent, type: 'event' });\n };\n\n/**\n * Delete an event at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmEvent } = utils('/path/to/eventcatalog');\n *\n * // removes an event at the given path (events dir is appended to the given path)\n * // Removes the event at events/InventoryAdjusted\n * await rmEvent('/InventoryAdjusted');\n * ```\n */\nexport const rmEvent = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete an event by it's id.\n *\n * Optionally specify a version to delete a specific version of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmEventById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryAdjusted event\n * await rmEventById('InventoryAdjusted');\n *\n * // deletes a specific version of the InventoryAdjusted event\n * await rmEventById('InventoryAdjusted', '0.0.1');\n * ```\n */\nexport const rmEventById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) => {\n await rmResourceById(directory, id, version, { type: 'event', persistFiles });\n};\n\n/**\n * Version an event by it's id.\n *\n * Takes the latest event and moves it to a versioned directory.\n * All files with this event are also versioned (e.g /events/InventoryAdjusted/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionEvent } = utils('/path/to/eventcatalog');\n *\n * // moves the latest InventoryAdjusted event to a versioned directory\n * // the version within that event is used as the version number.\n * await versionEvent('InventoryAdjusted');\n *\n * ```\n */\nexport const versionEvent = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Add a file to an event by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToEvent } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest InventoryAdjusted event\n * await addFileToEvent('InventoryAdjusted', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the InventoryAdjusted event\n * await addFileToEvent('InventoryAdjusted', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToEvent =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Add a schema to an event by it's id.\n *\n * Optionally specify a version to add a schema to a specific version of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addSchemaToEvent } = utils('/path/to/eventcatalog');\n *\n * // JSON schema example\n * const schema = {\n * \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n * \"type\": \"object\",\n * \"properties\": {\n * \"name\": {\n * \"type\": \"string\"\n * },\n * \"age\": {\n * \"type\": \"number\"\n * }\n * },\n * \"required\": [\"name\", \"age\"]\n * };\n *\n * // adds a schema to the latest InventoryAdjusted event\n * await addSchemaToEvent('InventoryAdjusted', { schema, fileName: 'schema.json' });\n *\n * // adds a file to a specific version of the InventoryAdjusted event\n * await addSchemaToEvent('InventoryAdjusted', { schema, fileName: 'schema.json' }, '0.0.1');\n *\n * ```\n */\nexport const addSchemaToEvent =\n (directory: string) => async (id: string, schema: { schema: string; fileName: string }, version?: string) => {\n await addFileToEvent(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);\n };\n\n/**\n * Check to see if the catalog has a version for the given event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { eventHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await eventHasVersion('InventoryAdjusted', '0.0.1');\n * await eventHasVersion('InventoryAdjusted', 'latest');\n * await eventHasVersion('InventoryAdjusted', '0.0.x');*\n *\n * ```\n */\nexport const eventHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import { globSync } from 'glob';\nimport fsSync from 'node:fs';\nimport { copy, CopyFilterAsync, CopyFilterSync } from 'fs-extra';\nimport { join, dirname } from 'node:path';\nimport matter from 'gray-matter';\nimport { satisfies, validRange, valid } from 'semver';\n\n/**\n * Returns true if a given version of a resource id exists in the catalog\n */\nexport const versionExists = async (catalogDir: string, id: string, version: string) => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n const matchedFiles = (await searchFilesForId(files, id, version)) || [];\n return matchedFiles.length > 0;\n};\n\nexport const findFileById = async (catalogDir: string, id: string, version?: string): Promise<string | undefined> => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n\n const matchedFiles = (await searchFilesForId(files, id)) || [];\n const latestVersion = matchedFiles.find((path) => !path.includes('versioned'));\n\n // If no version is provided, return the latest version\n if (!version) {\n return latestVersion;\n }\n\n // map files into gray matter to get versions\n const parsedFiles = matchedFiles.map((path) => {\n const { data } = matter.read(path);\n return { ...data, path };\n }) as any[];\n\n const semverRange = validRange(version);\n\n if (semverRange && valid(version)) {\n const match = parsedFiles.filter((c) => satisfies(c.version, semverRange));\n return match.length > 0 ? match[0].path : undefined;\n }\n\n // Order by version\n const sorted = parsedFiles.sort((a, b) => {\n return a.version.localeCompare(b.version);\n });\n\n // latest version\n const match = sorted.length > 0 ? [sorted[sorted.length - 1]] : [];\n\n if (match.length > 0) {\n return match[0].path;\n }\n};\n\nexport const getFiles = async (pattern: string, ignore: string | string[] = '') => {\n try {\n const ignoreList = Array.isArray(ignore) ? ignore : [ignore];\n const baseDir = pattern.includes('**') ? pattern.split('**')[0] : dirname(pattern);\n const files = globSync(pattern, { cwd: baseDir, ignore: ['node_modules/**', ...ignoreList] });\n return files;\n } catch (error) {\n throw new Error(`Error finding files: ${error}`);\n }\n};\n\nexport const readMdxFile = async (path: string) => {\n const { data } = matter.read(path);\n const { markdown, ...frontmatter } = data;\n return { ...frontmatter, markdown };\n};\n\nexport const searchFilesForId = async (files: string[], id: string, version?: string) => {\n const idRegex = new RegExp(`^id:\\\\s*(['\"]|>-)?\\\\s*${id}['\"]?\\\\s*$`, 'm');\n const versionRegex = new RegExp(`^version:\\\\s*['\"]?${version}['\"]?\\\\s*$`, 'm');\n\n const matches = files.map((file) => {\n const content = fsSync.readFileSync(file, 'utf-8');\n const hasIdMatch = content.match(idRegex);\n\n // Check version if provided\n if (version && !content.match(versionRegex)) {\n return undefined;\n }\n\n if (hasIdMatch) {\n return file;\n }\n });\n\n return matches.filter(Boolean).filter((file) => file !== undefined);\n};\n\n/**\n * Function to copy a directory from source to target, uses a tmp directory\n * @param catalogDir\n * @param source\n * @param target\n * @param filter\n */\nexport const copyDir = async (catalogDir: string, source: string, target: string, filter?: CopyFilterAsync | CopyFilterSync) => {\n const tmpDirectory = join(catalogDir, 'tmp');\n fsSync.mkdirSync(tmpDirectory, { recursive: true });\n\n // Copy everything over\n await copy(source, tmpDirectory, {\n overwrite: true,\n filter,\n });\n\n await copy(tmpDirectory, target, {\n overwrite: true,\n filter,\n });\n\n // Remove the tmp directory\n fsSync.rmSync(tmpDirectory, { recursive: true });\n};\n\n// Makes sure values in sends/recieves are unique\nexport const uniqueVersions = (messages: { id: string; version: string }[]): { id: string; version: string }[] => {\n const uniqueSet = new Set();\n\n return messages.filter((message) => {\n const key = `${message.id}-${message.version}`;\n if (!uniqueSet.has(key)) {\n uniqueSet.add(key);\n return true;\n }\n return false;\n });\n};\n","import { dirname, join } from 'path';\nimport { copyDir, findFileById, getFiles, searchFilesForId, versionExists } from './utils';\nimport matter from 'gray-matter';\nimport fs from 'node:fs/promises';\nimport fsSync from 'node:fs';\nimport { Message, Service, CustomDoc } from '../types';\nimport { satisfies } from 'semver';\nimport { lock, unlock } from 'proper-lockfile';\n\ntype Resource = Service | Message | CustomDoc;\n\nexport const versionResource = async (catalogDir: string, id: string) => {\n // Find all the events in the directory\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n const matchedFiles = await searchFilesForId(files, id);\n\n if (matchedFiles.length === 0) {\n throw new Error(`No resource found with id: ${id}`);\n }\n\n // Event that is in the route of the project\n const file = matchedFiles[0];\n const sourceDirectory = dirname(file);\n const { data: { version = '0.0.1' } = {} } = matter.read(file);\n const targetDirectory = getVersionedDirectory(sourceDirectory, version);\n\n fsSync.mkdirSync(targetDirectory, { recursive: true });\n\n // Copy the event to the versioned directory\n await copyDir(catalogDir, sourceDirectory, targetDirectory, (src) => {\n return !src.includes('versioned');\n });\n\n // Remove all the files in the root of the resource as they have now been versioned\n await fs.readdir(sourceDirectory).then(async (resourceFiles) => {\n await Promise.all(\n resourceFiles.map(async (file) => {\n if (file !== 'versioned') {\n fsSync.rmSync(join(sourceDirectory, file), { recursive: true });\n }\n })\n );\n });\n};\n\nexport const writeResource = async (\n catalogDir: string,\n resource: Resource,\n options: { path?: string; type: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n type: '',\n override: false,\n versionExistingContent: false,\n format: 'mdx',\n }\n) => {\n const path = options.path || `/${resource.id}`;\n const fullPath = join(catalogDir, path);\n const format = options.format || 'mdx';\n\n // Create directory if it doesn't exist\n fsSync.mkdirSync(fullPath, { recursive: true });\n\n // Create or get lock file path\n const lockPath = join(fullPath, `index.${format}`);\n\n // Ensure the file exists before attempting to lock it\n if (!fsSync.existsSync(lockPath)) {\n fsSync.writeFileSync(lockPath, '');\n }\n\n try {\n // Acquire lock with retry\n await lock(lockPath, {\n retries: 5,\n stale: 10000, // 10 seconds\n });\n\n const exists = await versionExists(catalogDir, resource.id, resource.version);\n\n if (exists && !options.override) {\n throw new Error(`Failed to write ${resource.id} (${options.type}) as the version ${resource.version} already exists`);\n }\n\n const { markdown, ...frontmatter } = resource;\n\n if (options.versionExistingContent && !exists) {\n const currentResource = await getResource(catalogDir, resource.id);\n\n if (currentResource) {\n if (satisfies(resource.version, `>${currentResource.version}`)) {\n await versionResource(catalogDir, resource.id);\n } else {\n throw new Error(`New version ${resource.version} is not greater than current version ${currentResource.version}`);\n }\n }\n }\n\n const document = matter.stringify(markdown.trim(), frontmatter);\n fsSync.writeFileSync(lockPath, document);\n } finally {\n // Always release the lock\n await unlock(lockPath).catch(() => {});\n }\n};\n\nexport const getResource = async (\n catalogDir: string,\n id: string,\n version?: string,\n options?: { type: string }\n): Promise<Resource | undefined> => {\n const file = await findFileById(catalogDir, id, version);\n if (!file) return;\n\n const { data, content } = matter.read(file);\n\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n};\n\nexport const getResourcePath = async (catalogDir: string, id: string, version?: string) => {\n const file = await findFileById(catalogDir, id, version);\n if (!file) return;\n\n return {\n fullPath: file,\n relativePath: file.replace(catalogDir, ''),\n directory: dirname(file.replace(catalogDir, '')),\n };\n};\n\nexport const getResources = async (\n catalogDir: string,\n {\n type,\n latestOnly = false,\n ignore = [],\n pattern = '',\n }: { type: string; pattern?: string; latestOnly?: boolean; ignore?: string[] }\n): Promise<Resource[] | undefined> => {\n const ignoreList = latestOnly ? `**/versioned/**` : '';\n const filePattern = pattern || `${catalogDir}/**/${type}/**/index.{md,mdx}`;\n const files = await getFiles(filePattern, [ignoreList, ...ignore]);\n\n if (files.length === 0) return;\n\n return files.map((file) => {\n const { data, content } = matter.read(file);\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n });\n};\n\nexport const rmResourceById = async (\n catalogDir: string,\n id: string,\n version?: string,\n options?: { type: string; persistFiles?: boolean }\n) => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n\n const matchedFiles = await searchFilesForId(files, id, version);\n\n if (matchedFiles.length === 0) {\n throw new Error(`No ${options?.type || 'resource'} found with id: ${id}`);\n }\n\n if (options?.persistFiles) {\n await Promise.all(\n matchedFiles.map(async (file) => {\n await fs.rm(file, { recursive: true });\n })\n );\n } else {\n await Promise.all(\n matchedFiles.map(async (file) => {\n const directory = dirname(file);\n await fs.rm(directory, { recursive: true, force: true });\n })\n );\n }\n};\n\nexport const addFileToResource = async (\n catalogDir: string,\n id: string,\n file: { content: string; fileName: string },\n version?: string\n) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory to write file to');\n\n fsSync.writeFileSync(join(dirname(pathToResource), file.fileName), file.content);\n};\n\nexport const getFileFromResource = async (catalogDir: string, id: string, file: { fileName: string }, version?: string) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory of resource');\n\n const exists = await fs\n .access(join(dirname(pathToResource), file.fileName))\n .then(() => true)\n .catch(() => false);\n if (!exists) throw new Error(`File ${file.fileName} does not exist in resource ${id} v(${version})`);\n\n return fsSync.readFileSync(join(dirname(pathToResource), file.fileName), 'utf-8');\n};\nexport const getVersionedDirectory = (sourceDirectory: string, version: any): string => {\n return join(sourceDirectory, 'versioned', version);\n};\n","import fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { Command } from './types';\nimport {\n addFileToResource,\n getResource,\n getResourcePath,\n getResources,\n rmResourceById,\n versionResource,\n writeResource,\n} from './internal/resources';\nimport { findFileById } from './internal/utils';\nimport { addMessageToService } from './services';\n\n/**\n * Returns a command from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the command\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getCommand } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the command\n * const command = await getCommand('UpdateInventory');\n *\n * // Gets a version of the command\n * const command = await getCommand('UpdateInventory', '0.0.1');\n * ```\n */\nexport const getCommand =\n (directory: string) =>\n async (id: string, version?: string): Promise<Command> =>\n getResource(directory, id, version, { type: 'command' }) as Promise<Command>;\n\n/**\n * Returns all commands from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the events.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getCommands } = utils('/path/to/eventcatalog');\n *\n * // Gets all commands (and versions) from the catalog\n * const commands = await getCommands();\n *\n * // Gets all commands (only latest version) from the catalog\n * const commands = await getCommands({ latestOnly: true });\n * ```\n */\nexport const getCommands =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Command[]> =>\n getResources(directory, { type: 'commands', ...options }) as Promise<Command[]>;\n\n/**\n * Write a command to EventCatalog.\n *\n * You can optionally override the path of the command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeCommand } = utils('/path/to/eventcatalog');\n *\n * // Write a command to the catalog\n * // Command would be written to commands/UpdateInventory\n * await writeCommand({\n * id: 'UpdateInventory',\n * name: 'Update Inventory',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * });\n *\n * // Write a command to the catalog but override the path\n * // Command would be written to commands/Inventory/UpdateInventory\n * await writeCommand({\n * id: 'UpdateInventory',\n * name: 'Update Inventory',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { path: \"/Inventory/UpdateInventory\"});\n *\n * // Write a command to the catalog and override the existing content (if there is any)\n * await writeCommand({\n * id: 'UpdateInventory',\n * name: 'Update Inventory',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { override: true });\n *\n * // Write a command to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeCommand({\n * id: 'UpdateInventory',\n * name: 'Update Inventory',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeCommand =\n (directory: string) =>\n async (\n command: Command,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n versionExistingContent: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...command }, { ...options, type: 'command' });\n\n/**\n * Write an command to a service in EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeCommandToService } = utils('/path/to/eventcatalog');\n *\n * // Write an event to a given service in the catalog\n * // Event would be written to services/Inventory/commands/UpdateInventory\n * await writeCommandToService({\n * id: 'UpdateInventory',\n * name: 'Update Inventory',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { id: 'Inventory' });\n * ```\n */\nexport const writeCommandToService =\n (directory: string) =>\n async (\n command: Command,\n service: { id: string; version?: string },\n options: { path?: string; format?: 'md' | 'mdx' } = { path: '', format: 'mdx' }\n ) => {\n const resourcePath = await getResourcePath(directory, service.id, service.version);\n if (!resourcePath) {\n throw new Error('Service not found');\n }\n\n let pathForCommand =\n service.version && service.version !== 'latest'\n ? `${resourcePath.directory}/versioned/${service.version}/commands`\n : `${resourcePath.directory}/commands`;\n pathForCommand = join(pathForCommand, command.id);\n\n await writeResource(directory, { ...command }, { ...options, path: pathForCommand, type: 'command' });\n };\n\n/**\n * Delete a command at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmCommand } = utils('/path/to/eventcatalog');\n *\n * // removes a command at the given path (commands dir is appended to the given path)\n * // Removes the command at commands/UpdateInventory\n * await rmCommand('/UpdateInventory');\n * ```\n */\nexport const rmCommand = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a command by it's id.\n *\n * Optionally specify a version to delete a specific version of the command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmCommandById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest UpdateInventory command\n * await rmCommandById('UpdateInventory');\n *\n * // deletes a specific version of the UpdateInventory command\n * await rmCommandById('UpdateInventory', '0.0.1');\n * ```\n */\nexport const rmCommandById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) =>\n rmResourceById(directory, id, version, { type: 'command', persistFiles });\n\n/**\n * Version a command by it's id.\n *\n * Takes the latest command and moves it to a versioned directory.\n * All files with this command are also versioned (e.g /commands/UpdateInventory/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionCommand } = utils('/path/to/eventcatalog');\n *\n * // moves the latest UpdateInventory command to a versioned directory\n * // the version within that command is used as the version number.\n * await versionCommand('UpdateInventory');\n *\n * ```\n */\nexport const versionCommand = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Add a file to a command by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToCommand } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest UpdateInventory command\n * await addFileToCommand('UpdateInventory', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the UpdateInventory command\n * await addFileToCommand('UpdateInventory', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToCommand =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Add a schema to a command by it's id.\n *\n * Optionally specify a version to add a schema to a specific version of the command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addSchemaToCommand } = utils('/path/to/eventcatalog');\n *\n * // JSON schema example\n * const schema = {\n * \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n * \"type\": \"object\",\n * \"properties\": {\n * \"name\": {\n * \"type\": \"string\"\n * },\n * \"age\": {\n * \"type\": \"number\"\n * }\n * },\n * \"required\": [\"name\", \"age\"]\n * };\n *\n * // adds a schema to the latest UpdateInventory command\n * await addSchemaToCommand('UpdateInventory', { schema, fileName: 'schema.json' });\n *\n * // adds a file to a specific version of the UpdateInventory command\n * await addSchemaToCommand('UpdateInventory', { schema, fileName: 'schema.json' }, '0.0.1');\n *\n * ```\n */\nexport const addSchemaToCommand =\n (directory: string) => async (id: string, schema: { schema: string; fileName: string }, version?: string) => {\n await addFileToCommand(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);\n };\n\n/**\n * Check to see if the catalog has a version for the given command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { commandHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await commandHasVersion('InventoryAdjusted', '0.0.1');\n * await commandHasVersion('InventoryAdjusted', 'latest');\n * await commandHasVersion('InventoryAdjusted', '0.0.x');*\n *\n * ```\n */\nexport const commandHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { findFileById } from './internal/utils';\nimport type { Query } from './types';\nimport {\n addFileToResource,\n getResource,\n getResourcePath,\n getResources,\n rmResourceById,\n versionResource,\n writeResource,\n} from './internal/resources';\n\n/**\n * Returns a query from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the query\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getQuery } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the event\n * const event = await getQuery('GetOrder');\n *\n * // Gets a version of the event\n * const event = await getQuery('GetOrder', '0.0.1');\n * ```\n */\nexport const getQuery =\n (directory: string) =>\n async (id: string, version?: string): Promise<Query> =>\n getResource(directory, id, version, { type: 'query' }) as Promise<Query>;\n\n/**\n * Write a query to EventCatalog.\n *\n * You can optionally override the path of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeQuery } = utils('/path/to/eventcatalog');\n *\n * // Write an event to the catalog\n * // Event would be written to queries/GetOrder\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * });\n *\n * // Write an event to the catalog but override the path\n * // Event would be written to queries/Inventory/GetOrder\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { path: \"/Orders/GetOrder\"});\n *\n * // Write a query to the catalog and override the existing content (if there is any)\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { override: true });\n *\n * // Write a query to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeQuery =\n (directory: string) =>\n async (\n query: Query,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n versionExistingContent: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...query }, { ...options, type: 'query' });\n\n/**\n * Returns all queries from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the queries.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getQueries } = utils('/path/to/eventcatalog');\n *\n * // Gets all queries (and versions) from the catalog\n * const queries = await getQueries();\n *\n * // Gets all queries (only latest version) from the catalog\n * const queries = await getQueries({ latestOnly: true });\n * ```\n */\nexport const getQueries =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Query[]> =>\n getResources(directory, { type: 'queries', ...options }) as Promise<Query[]>;\n\n/**\n * Write a query to a service in EventCatalog.\n *\n * You can optionally override the path of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeQueryToService } = utils('/path/to/eventcatalog');\n *\n * // Write an event to a given service in the catalog\n * // Event would be written to services/Orders/queries/GetOrder\n * await writeQueryToService({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { id: 'Orders' });\n * ```\n */\nexport const writeQueryToService =\n (directory: string) =>\n async (\n query: Query,\n service: { id: string; version?: string },\n options: { path?: string; format?: 'md' | 'mdx' } = { path: '', format: 'mdx' }\n ) => {\n const resourcePath = await getResourcePath(directory, service.id, service.version);\n if (!resourcePath) {\n throw new Error('Service not found');\n }\n let pathForQuery =\n service.version && service.version !== 'latest'\n ? `${resourcePath.directory}/versioned/${service.version}/queries`\n : `${resourcePath.directory}/queries`;\n pathForQuery = join(pathForQuery, query.id);\n await writeResource(directory, { ...query }, { ...options, path: pathForQuery, type: 'query' });\n };\n\n/**\n * Delete a query at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmQuery } = utils('/path/to/eventcatalog');\n *\n * // removes an query at the given path (queries dir is appended to the given path)\n * // Removes the query at queries/GetOrders\n * await rmQuery('/GetOrders');\n * ```\n */\nexport const rmQuery = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a query by it's id.\n *\n * Optionally specify a version to delete a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmQueryById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryAdjusted query\n * await rmQueryById('GetOrder');\n *\n * // deletes a specific version of the GetOrder query\n * await rmQueryById('GetOrder', '0.0.1');\n * ```\n */\nexport const rmQueryById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) => {\n await rmResourceById(directory, id, version, { type: 'query', persistFiles });\n};\n\n/**\n * Version a query by it's id.\n *\n * Takes the latest query and moves it to a versioned directory.\n * All files with this query are also versioned (e.g /queries/GetOrder/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionQuery } = utils('/path/to/eventcatalog');\n *\n * // moves the latest GetOrder query to a versioned directory\n * // the version within that query is used as the version number.\n * await versionQuery('GetOrder');\n *\n * ```\n */\nexport const versionQuery = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Add a file to a query by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToQuery } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest GetOrder query\n * await addFileToQuery('GetOrder', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the GetOrder query\n * await addFileToQuery('GetOrder', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToQuery =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Add a schema to a query by it's id.\n *\n * Optionally specify a version to add a schema to a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addSchemaToQuery } = utils('/path/to/eventcatalog');\n *\n * // JSON schema example\n * const schema = {\n * \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n * \"type\": \"object\",\n * \"properties\": {\n * \"name\": {\n * \"type\": \"string\"\n * },\n * \"age\": {\n * \"type\": \"number\"\n * }\n * },\n * \"required\": [\"name\", \"age\"]\n * };\n *\n * // adds a schema to the latest GetOrder query\n * await addSchemaToQuery('GetOrder', { schema, fileName: 'schema.json' });\n *\n * // adds a file to a specific version of the GetOrder query\n * await addSchemaToQuery('GetOrder', { schema, fileName: 'schema.json' }, '0.0.1');\n *\n * ```\n */\nexport const addSchemaToQuery =\n (directory: string) => async (id: string, schema: { schema: string; fileName: string }, version?: string) => {\n await addFileToQuery(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);\n };\n\n/**\n * Check to see if the catalog has a version for the given query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { queryHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await queryHasVersion('GetOrder', '0.0.1');\n * await queryHasVersion('GetOrder', 'latest');\n * await queryHasVersion('GetOrder', '0.0.x');*\n *\n * ```\n */\nexport const queryHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import type { Service, Specifications } from './types';\nimport fs from 'node:fs/promises';\nimport { join, dirname, extname } from 'node:path';\nimport {\n addFileToResource,\n getFileFromResource,\n getResource,\n rmResourceById,\n versionResource,\n writeResource,\n getVersionedDirectory,\n getResources,\n getResourcePath,\n} from './internal/resources';\nimport { findFileById, uniqueVersions } from './internal/utils';\n\n/**\n * Returns a service from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the service\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getService } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the event\n * const service = await getService('InventoryService');\n *\n * // Gets a version of the event\n * const service = await getService('InventoryService', '0.0.1');\n * ```\n */\nexport const getService =\n (directory: string) =>\n async (id: string, version?: string): Promise<Service> =>\n getResource(directory, id, version, { type: 'service' }) as Promise<Service>;\n\n/**\n * Returns all services from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the services.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getServices } = utils('/path/to/eventcatalog');\n *\n * // Gets all services (and versions) from the catalog\n * const services = await getServices();\n *\n * // Gets all services (only latest version) from the catalog\n * const services = await getServices({ latestOnly: true });\n * ```\n */\nexport const getServices =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Service[]> =>\n getResources(directory, {\n type: 'services',\n ignore: ['**/events/**', '**/commands/**', '**/queries/**'],\n ...options,\n }) as Promise<Service[]>;\n\n/**\n * Write a Service to EventCatalog.\n *\n * You can optionally overide the path of the Service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeService } = utils('/path/to/eventcatalog');\n *\n * // Write a Service\n * // Service would be written to services/InventoryService\n * await writeService({\n * id: 'InventoryService',\n * name: 'Inventory Service',\n * version: '0.0.1',\n * summary: 'Service that handles the inventory',\n * markdown: '# Hello world',\n * });\n *\n * // Write a service to the catalog but override the path\n * // Service would be written to services/Inventory/InventoryService\n * await writeService({\n * id: 'InventoryService',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { path: \"/Inventory/InventoryService\"});\n *\n * // Write a service to the catalog and override the existing content (if there is any)\n * await writeService({\n * id: 'InventoryService',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { override: true });\n *\n * // Write a service to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeService({\n * id: 'InventoryService',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeService =\n (directory: string) =>\n async (\n service: Service,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n format: 'mdx',\n }\n ) => {\n const resource: Service = { ...service };\n\n if (Array.isArray(service.sends)) {\n resource.sends = uniqueVersions(service.sends);\n }\n\n if (Array.isArray(service.receives)) {\n resource.receives = uniqueVersions(service.receives);\n }\n\n return await writeResource(directory, resource, { ...options, type: 'service' });\n };\n\n/**\n * Write a versioned service to EventCatalog.\n *\n * You can optionally overide the path of the Service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeVersionedService } = utils('/path/to/eventcatalog');\n *\n * // Write a service\n * // Service would be written to services/InventoryService/versioned/0.0.1\n * await writeVersionedService({\n * id: 'InventoryService',\n * name: 'Inventory Service',\n * version: '0.0.1',\n * summary: 'Service that handles the inventory',\n * markdown: '# Hello world',\n * });\n *\n * ```\n */\nexport const writeVersionedService = (directory: string) => async (service: Service) => {\n const resource: Service = { ...service };\n const path = getVersionedDirectory(service.id, service.version);\n\n return await writeService(directory)(resource, { path: path });\n};\n\n/**\n * Write a service to a domain in EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeServiceToDomain } = utils('/path/to/eventcatalog');\n *\n * // Write a service to a domain\n * // Service would be written to domains/Shopping/services/InventoryService\n * await writeServiceToDomain({\n * id: 'InventoryService',\n * name: 'Inventory Service',\n * version: '0.0.1',\n * summary: 'Service that handles the inventory',\n * markdown: '# Hello world',\n * }, { id: 'Shopping' });\n * ```\n */\nexport const writeServiceToDomain =\n (directory: string) =>\n async (\n service: Service,\n domain: { id: string; version?: string; direction?: string },\n options: { path?: string; format?: 'md' | 'mdx' } = { path: '', format: 'mdx' }\n ) => {\n let pathForService =\n domain.version && domain.version !== 'latest'\n ? `/${domain.id}/versioned/${domain.version}/services`\n : `/${domain.id}/services`;\n pathForService = join(pathForService, service.id);\n\n //\n await writeResource(directory, { ...service }, { ...options, path: pathForService, type: 'service' });\n };\n\n/**\n * Version a service by it's id.\n *\n * Takes the latest service and moves it to a versioned directory.\n * All files with this service are also versioned. (e.g /services/InventoryService/openapi.yml)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionService } = utils('/path/to/eventcatalog');\n *\n * // moves the latest InventoryService service to a versioned directory\n * // the version within that service is used as the version number.\n * await versionService('InventoryService');\n *\n * ```\n */\nexport const versionService = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Delete a service at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmService } = utils('/path/to/eventcatalog');\n *\n * // Removes the service at services/InventoryService\n * await rmService('/InventoryService');\n * ```\n */\nexport const rmService = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a service by it's id.\n *\n * Optionally specify a version to delete a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmServiceById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryService event\n * await rmServiceById('InventoryService');\n *\n * // deletes a specific version of the InventoryService event\n * await rmServiceById('InventoryService', '0.0.1');\n * ```\n */\nexport const rmServiceById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) =>\n rmResourceById(directory, id, version, { type: 'service', persistFiles });\n\n/**\n * Add a file to a service by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToService } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest InventoryService event\n * await addFileToService('InventoryService', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the InventoryService event\n * await addFileToService('InventoryService', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\n\nexport const addFileToService =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Returns specification files for a service\n *\n * Optionally specify a version to of the service\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getSpecificationFilesForService } = utils('/path/to/eventcatalog');\n *\n * // returns a list of specification files for a service\n * await getSpecificationFilesForService('InventoryService', '0.0.1');\n *\n * ```\n */\n\nexport const getSpecificationFilesForService = (directory: string) => async (id: string, version?: string) => {\n let service: Service = await getService(directory)(id, version);\n const filePathToService = await findFileById(directory, id, version);\n\n if (!filePathToService) throw new Error('Cannot find directory of service');\n\n let specs = [] as any;\n if (service.specifications) {\n const serviceSpecifications = service.specifications;\n const specificationFiles = Object.keys(serviceSpecifications);\n\n const getSpecs = specificationFiles.map(async (specFile) => {\n const fileName = serviceSpecifications[specFile as keyof Specifications];\n\n if (!fileName) {\n throw new Error(`Specification file name for ${specFile} is undefined`);\n }\n const rawFile = await getFileFromResource(directory, id, { fileName }, version);\n\n return { key: specFile, content: rawFile, fileName: fileName, path: join(dirname(filePathToService), fileName) };\n });\n\n specs = await Promise.all(getSpecs);\n }\n return specs;\n};\n\n/**\n * Add an event/command to a service by it's id.\n *\n * Optionally specify a version to add the event to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds an event to the service or command to the service\n * const { addEventToService, addCommandToService } = utils('/path/to/eventcatalog');\n *\n * // Adds a new event (InventoryUpdatedEvent) that the InventoryService will send\n * await addEventToService('InventoryService', 'sends', { event: 'InventoryUpdatedEvent', version: '2.0.0' });\n * * // Adds a new event (OrderComplete) that the InventoryService will receive\n * await addEventToService('InventoryService', 'receives', { event: 'OrderComplete', version: '1.0.0' });\n *\n * // Adds a new command (UpdateInventoryCommand) that the InventoryService will send\n * await addCommandToService('InventoryService', 'sends', { command: 'UpdateInventoryCommand', version: '2.0.0' });\n * // Adds a new command (VerifyInventory) that the InventoryService will receive\n * await addCommandToService('InventoryService', 'receives', { command: 'VerifyInventory', version: '1.0.0' });\n *\n * ```\n */\n\nexport const addMessageToService =\n (directory: string) => async (id: string, direction: string, event: { id: string; version: string }, version?: string) => {\n let service: Service = await getService(directory)(id, version);\n const servicePath = await getResourcePath(directory, id, version);\n const extension = extname(servicePath?.fullPath || '');\n\n if (direction === 'sends') {\n if (service.sends === undefined) {\n service.sends = [];\n }\n // We first check if the event is already in the list\n for (let i = 0; i < service.sends.length; i++) {\n if (service.sends[i].id === event.id && service.sends[i].version === event.version) {\n return;\n }\n }\n service.sends.push({ id: event.id, version: event.version });\n } else if (direction === 'receives') {\n if (service.receives === undefined) {\n service.receives = [];\n }\n // We first check if the event is already in the list\n for (let i = 0; i < service.receives.length; i++) {\n if (service.receives[i].id === event.id && service.receives[i].version === event.version) {\n return;\n }\n }\n service.receives.push({ id: event.id, version: event.version });\n } else {\n throw new Error(`Direction ${direction} is invalid, only 'receives' and 'sends' are supported`);\n }\n\n const existingResource = await findFileById(directory, id, version);\n\n if (!existingResource) {\n throw new Error(`Cannot find service ${id} in the catalog`);\n }\n\n // Get where the service was located, make sure it goes back there.\n const path = existingResource.split('/services')[0];\n const pathToResource = join(path, 'services');\n\n await rmServiceById(directory)(id, version);\n await writeService(pathToResource)(service, { format: extension === '.md' ? 'md' : 'mdx' });\n };\n\n/**\n * Check to see if the catalog has a version for the given service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { serviceHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await serviceHasVersion('InventoryService', '0.0.1');\n * await serviceHasVersion('InventoryService', 'latest');\n * await serviceHasVersion('InventoryService', '0.0.x');*\n *\n * ```\n */\nexport const serviceHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import type { Domain, UbiquitousLanguageDictionary } from './types';\nimport fs from 'node:fs/promises';\nimport path, { join } from 'node:path';\nimport fsSync from 'node:fs';\nimport {\n addFileToResource,\n getResource,\n getResourcePath,\n getResources,\n rmResourceById,\n versionResource,\n writeResource,\n} from './internal/resources';\nimport { findFileById, readMdxFile, uniqueVersions } from './internal/utils';\nimport matter from 'gray-matter';\n\n/**\n * Returns a domain from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the domain\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getDomain } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the domain\n * const domain = await getDomain('Payment');\n *\n * // Gets a version of the domain\n * const domain = await getDomain('Payment', '0.0.1');\n * ```\n */\nexport const getDomain =\n (directory: string) =>\n async (id: string, version?: string): Promise<Domain> =>\n getResource(directory, id, version, { type: 'domain' }) as Promise<Domain>;\n\n/**\n * Returns all domains from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the domains.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getDomains } = utils('/path/to/eventcatalog');\n *\n * // Gets all domains (and versions) from the catalog\n * const domains = await getDomains();\n *\n * // Gets all domains (only latest version) from the catalog\n * const domains = await getDomains({ latestOnly: true });\n * ```\n */\nexport const getDomains =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Domain[]> =>\n getResources(directory, {\n type: 'domains',\n ignore: ['**/services/**', '**/events/**', '**/commands/**', '**/queries/**', '**/flows/**'],\n ...options,\n }) as Promise<Domain[]>;\n\n/**\n * Write a domain to EventCatalog.\n *\n * You can optionally overide the path of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeDomain } = utils('/path/to/eventcatalog');\n *\n * // Write a domain\n * // Domain would be written to domains/Payment\n * await writeDomain({\n * id: 'Payment',\n * name: 'Payment domain',\n * version: '0.0.1',\n * summary: 'Domain for all things to do with payments',\n * markdown: '# Hello world',\n * });\n *\n * // Write a domain to the catalog but override the path\n * // Domain would be written to domains/Inventory/Payment\n * await writeDomain({\n * id: 'Payment',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { path: \"/Inventory/Payment\"});\n *\n * // Write a domain to the catalog and override the existing content (if there is any)\n * await writeDomain({\n * id: 'Payment',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { override: true });\n *\n * // Write a domain to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeDomain({\n * id: 'Payment',\n * name: 'Inventory Adjusted',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeDomain =\n (directory: string) =>\n async (\n domain: Domain,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n versionExistingContent: false,\n format: 'mdx',\n }\n ) => {\n const resource: Domain = { ...domain };\n\n if (Array.isArray(domain.services)) {\n resource.services = uniqueVersions(domain.services);\n }\n\n return await writeResource(directory, resource, { ...options, type: 'domain' });\n };\n\n/**\n * Version a domain by it's id.\n *\n * Takes the latest domain and moves it to a versioned directory.\n * All files with this domain are also versioned. (e.g /domains/Payment/openapi.yml)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionDomain } = utils('/path/to/eventcatalog');\n *\n * // moves the latest Payment domain to a versioned directory\n * // the version within that domain is used as the version number.\n * await versionDomain('Payment');\n *\n * ```\n */\nexport const versionDomain = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Delete a domain at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDomain } = utils('/path/to/eventcatalog');\n *\n * // Removes the domain at domains/Payment\n * await rmDomain('/Payment');\n * ```\n */\nexport const rmDomain = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a domain by it's id.\n *\n * Optionally specify a version to delete a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDomainById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest Payment event\n * await rmDomainById('Payment');\n *\n * // deletes a specific version of the Payment event\n * await rmDomainById('Payment', '0.0.1');\n * ```\n */\nexport const rmDomainById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) =>\n rmResourceById(directory, id, version, { type: 'domain', persistFiles });\n\n/**\n * Add a file to a domain by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToDomain } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest Payment event\n * await addFileToDomain('Payment', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the Payment event\n * await addFileToDomain('Payment', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\n\nexport const addFileToDomain =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Adds a ubiquitous language dictionary to a domain.\n *\n * Optionally specify a version to add a ubiquitous language dictionary to a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addUbiquitousLanguageToDomain } = utils('/path/to/eventcatalog');\n *\n * // Adds a ubiquitous language dictionary to the latest Payment domain\n * await addUbiquitousLanguageToDomain('Payment', { dictionary: [{ id: 'Order', name: 'Order', summary: 'All things to do with the payment systems', description: 'This is a description', icon: 'KeyIcon' }] });\n *\n * // Adds a ubiquitous language dictionary to a specific version of the domain\n * await addUbiquitousLanguageToDomain('Payment', { dictionary: [{ id: 'Order', name: 'Order', summary: 'All things to do with the payment systems', description: 'This is a description', icon: 'KeyIcon' }] }, '0.0.1');\n * ```\n */\n\nexport const addUbiquitousLanguageToDomain =\n (directory: string) => async (id: string, ubiquitousLanguageDictionary: UbiquitousLanguageDictionary, version?: string) => {\n const content = matter.stringify('', {\n ...ubiquitousLanguageDictionary,\n });\n await addFileToResource(directory, id, { content, fileName: 'ubiquitous-language.mdx' }, version);\n };\n\n/**\n * Returns the ubiquitous language dictionary from a domain.\n *\n * Optionally specify a version to get the ubiquitous language dictionary from a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getUbiquitousLanguageFromDomain } = utils('/path/to/eventcatalog');\n *\n * const ubiquitousLanguage = await getUbiquitousLanguageFromDomain('Payment');\n *\n * // Returns the ubiquitous language dictionary from a specific version of the domain\n * const ubiquitousLanguage = await getUbiquitousLanguageFromDomain('Payment', '0.0.1');\n * ```\n */\nexport const getUbiquitousLanguageFromDomain = (directory: string) => async (id: string, version?: string) => {\n const pathToDomain = (await findFileById(directory, id, version)) || '';\n const pathToUbiquitousLanguage = path.join(path.dirname(pathToDomain), 'ubiquitous-language.mdx');\n\n const fileExists = fsSync.existsSync(pathToUbiquitousLanguage);\n\n if (!fileExists) {\n return undefined;\n }\n\n const content = await readMdxFile(pathToUbiquitousLanguage);\n\n return content;\n};\n\n/**\n * Check to see if the catalog has a version for the given domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { domainHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await domainHasVersion('Orders', '0.0.1');\n * await domainHasVersion('Orders', 'latest');\n * await domainHasVersion('Orders', '0.0.x');*\n *\n * ```\n */\nexport const domainHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n\n/**\n * Add a service to a domain by it's id.\n *\n * Optionally specify a version to add the service to a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds a service to the domain\n * const { addServiceToDomain } = utils('/path/to/eventcatalog');\n *\n * // Adds a service (Orders Service) to the domain (Orders)\n * await addServiceToDomain('Orders', { service: 'Order Service', version: '2.0.0' });\n * // Adds a service (Orders Service) to the domain (Orders) with a specific version\n * await addServiceToDomain('Orders', { service: 'Order Service', version: '2.0.0' }, '1.0.0');\n * ```\n */\n\nexport const addServiceToDomain =\n (directory: string) => async (id: string, service: { id: string; version: string }, version?: string) => {\n let domain: Domain = await getDomain(directory)(id, version);\n const domainPath = await getResourcePath(directory, id, version);\n\n // Get the extension of the file\n const extension = path.extname(domainPath?.fullPath || '');\n\n if (domain.services === undefined) {\n domain.services = [];\n }\n\n const serviceExistsInList = domain.services.some((s) => s.id === service.id && s.version === service.version);\n\n if (serviceExistsInList) {\n return;\n }\n\n // Add service to the list\n domain.services.push(service);\n\n await rmDomainById(directory)(id, version, true);\n await writeDomain(directory)(domain, { format: extension === '.md' ? 'md' : 'mdx' });\n };\n","import fs from 'node:fs/promises';\nimport { join, extname } from 'node:path';\nimport type { Channel } from './types';\nimport { getResource, getResourcePath, getResources, rmResourceById, versionResource, writeResource } from './internal/resources';\nimport { findFileById } from './internal/utils';\nimport { getEvent, rmEventById, writeEvent } from './events';\nimport { getCommand, rmCommandById, writeCommand } from './commands';\nimport { getQuery, rmQueryById, writeQuery } from './queries';\n\n/**\n * Returns a channel from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the channel\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getChannel } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the channel\n * const channel = await getChannel('InventoryChannel');\n *\n * // Gets a version of the channel\n * const channel = await getChannel('InventoryChannel', '0.0.1');\n * ```\n */\nexport const getChannel =\n (directory: string) =>\n async (id: string, version?: string): Promise<Channel> =>\n getResource(directory, id, version, { type: 'channel' }) as Promise<Channel>;\n\n/**\n * Returns all channels from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the channels.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getChannels } = utils('/path/to/eventcatalog');\n *\n * // Gets all channels (and versions) from the catalog\n * const channels = await getChannels();\n *\n * // Gets all channels (only latest version) from the catalog\n * const channels = await getChannels({ latestOnly: true });\n * ```\n */\nexport const getChannels =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Channel[]> =>\n getResources(directory, { type: 'channels', ...options }) as Promise<Channel[]>;\n\n/**\n * Write a channel to EventCatalog.\n *\n * You can optionally override the path of the channel.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeChannel } = utils('/path/to/eventcatalog');\n *\n * // Write a channel to the catalog\n * // channel would be written to channels/inventory.{env}.events\n * await writeChannel({\n * id: 'inventory.{env}.events',\n * name: 'Inventory channel',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * address: inventory.{env}.events,\n * protocols: ['http'],\n * });\n *\n * // Write a channel to the catalog but override the path\n * // channel would be written to channels/Inventory/InventoryChannel\n * await writeChannel({\n * id: 'InventoryChannel',\n * name: 'Update Inventory',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * address: inventory.{env}.events,\n * protocols: ['http'],\n * }, { path: \"/channels/Inventory/InventoryChannel\"});\n *\n * // Write a channel to the catalog and override the existing content (if there is any)\n * await writeChannel({\n * id: 'InventoryChannel',\n * name: 'Update Inventory',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * address: inventory.{env}.events,\n * protocols: ['http'],\n * }, { override: true });\n *\n * // Write a channel to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeChannel({\n * id: 'InventoryChannel',\n * name: 'Update Inventory',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * address: inventory.{env}.events,\n * protocols: ['http'],\n * }, { versionExistingContent: true });\n * ```\n */\nexport const writeChannel =\n (directory: string) =>\n async (\n channel: Channel,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = { path: '' }\n ) =>\n writeResource(directory, { ...channel }, { ...options, type: 'channel' });\n\n/**\n * Delete a channel at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmChannel } = utils('/path/to/eventcatalog');\n *\n * // removes a channel at the given path (channels dir is appended to the given path)\n * // Removes the channel at channels/InventoryChannel\n * await rmChannel('/InventoryChannel');\n * ```\n */\nexport const rmChannel = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a channel by it's id.\n *\n * Optionally specify a version to delete a specific version of the channel.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmChannelById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryChannel channel\n * await rmChannelById('inventory.{env}.events');\n *\n * // deletes a specific version of the InventoryChannel channel\n * await rmChannelById('inventory.{env}.events', '0.0.1');\n * ```\n */\nexport const rmChannelById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) =>\n rmResourceById(directory, id, version, { type: 'channel', persistFiles });\n\n/**\n * Version a channel by it's id.\n *\n * Takes the latest channel and moves it to a versioned directory.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionChannel } = utils('/path/to/eventcatalog');\n *\n * // moves the latest inventory.{env}.events channel to a versioned directory\n * // the version within that channel is used as the version number.\n * await versionChannel('inventory.{env}.events');\n *\n * ```\n */\nexport const versionChannel = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Check to see if the catalog has a version for the given channel.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { channelHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await channelHasVersion('inventory.{env}.events', '0.0.1');\n * await channelHasVersion('inventory.{env}.events', 'latest');\n * await channelHasVersion('inventory.{env}.events', '0.0.x');*\n *\n * ```\n */\nexport const channelHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n\n/**\n * Add an event/command/query to a channel by it's id.\n *\n * Optionally specify a version to add the message to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds an event to the service or command to the service\n * const { addEventToChannel, addCommandToChannel, addQueryToChannel } = utils('/path/to/eventcatalog');\n *\n * // Adds a new event (InventoryUpdatedEvent) that the InventoryService will send\n * await addEventToChannel('InventoryService', 'sends', { event: 'InventoryUpdatedEvent', version: '2.0.0' });\n * * // Adds a new event (OrderComplete) that the InventoryService will receive\n * await addEventToChannel('InventoryService', 'receives', { event: 'OrderComplete', version: '1.0.0' });\n *\n * // Adds a new command (UpdateInventoryCommand) that the InventoryService will send\n * await addCommandToChannel('InventoryService', 'sends', { command: 'UpdateInventoryCommand', version: '2.0.0' });\n * // Adds a new command (VerifyInventory) that the InventoryService will receive\n * await addCommandToChannel('InventoryService', 'receives', { command: 'VerifyInventory', version: '1.0.0' });\n *\n * // Adds a new query (GetInventoryQuery) that the InventoryService will send\n * await addQueryToChannel('InventoryService', 'sends', { query: 'GetInventoryQuery', version: '2.0.0' });\n * // Adds a new query (GetOrder) that the InventoryService will receive\n * await addQueryToChannel('InventoryService', 'receives', { query: 'GetOrder', version: '1.0.0' });\n *\n * ```\n */\n\nexport const addMessageToChannel =\n (directory: string, collection: string) =>\n async (id: string, _message: { id: string; version: string; parameters?: { [key: string]: string } }, version?: string) => {\n let channel: Channel = await getChannel(directory)(id, version);\n\n const functions = {\n events: {\n getMessage: getEvent,\n rmMessageById: rmEventById,\n writeMessage: writeEvent,\n },\n commands: {\n getMessage: getCommand,\n rmMessageById: rmCommandById,\n writeMessage: writeCommand,\n },\n queries: {\n getMessage: getQuery,\n rmMessageById: rmQueryById,\n writeMessage: writeQuery,\n },\n };\n\n const { getMessage, rmMessageById, writeMessage } = functions[collection as keyof typeof functions];\n\n const message = await getMessage(directory)(_message.id, _message.version);\n const messagePath = await getResourcePath(directory, _message.id, _message.version);\n const extension = extname(messagePath?.fullPath || '');\n\n if (!message) throw new Error(`Message ${_message.id} with version ${_message.version} not found`);\n\n if (message.channels === undefined) {\n message.channels = [];\n }\n\n const channelInfo = { id, version: channel.version, ...(_message.parameters && { parameters: _message.parameters }) };\n message.channels.push(channelInfo);\n\n // Add the message where it was to start..\n const existingResource = await findFileById(directory, _message.id, _message.version);\n\n if (!existingResource) {\n throw new Error(`Cannot find message ${id} in the catalog`);\n }\n\n const path = existingResource.split(`/${collection}`)[0];\n const pathToResource = join(path, collection);\n\n await rmMessageById(directory)(_message.id, _message.version, true);\n await writeMessage(pathToResource)(message, { format: extension === '.md' ? 'md' : 'mdx' });\n };\n","import path, { join } from 'node:path';\nimport { readMdxFile } from './internal/utils';\nimport type { CustomDoc } from './types';\nimport fsSync from 'node:fs';\nimport fs from 'node:fs/promises';\nimport matter from 'gray-matter';\nimport { getResources } from './internal/resources';\nimport slugify from 'slugify';\n\n/**\n * Returns a custom doc from EventCatalog by the given file path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getCustomDoc } = utils('/path/to/eventcatalog');\n *\n * // Gets the custom doc by the given file path\n * const customDoc = await getCustomDoc('/guides/inventory-management.mdx');\n * ```\n */\nexport const getCustomDoc =\n (directory: string) =>\n async (filePath: string): Promise<CustomDoc | undefined> => {\n const fullPath = path.join(directory, filePath);\n const fullPathWithExtension = fullPath.endsWith('.mdx') ? fullPath : `${fullPath}.mdx`;\n const fileExists = fsSync.existsSync(fullPathWithExtension);\n if (!fileExists) {\n return undefined;\n }\n return readMdxFile(fullPathWithExtension) as Promise<CustomDoc>;\n };\n\n/**\n * Returns all custom docs for the project.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getCustomDocs } = utils('/path/to/eventcatalog');\n *\n * // Gets all custom docs from the catalog\n * const customDocs = await getCustomDocs();\n *\n * // Gets all custom docs from the given path\n * const customDocs = await getCustomDocs({ path: '/guides' });\n * ```\n */\nexport const getCustomDocs =\n (directory: string) =>\n async (options?: { path?: string }): Promise<CustomDoc[]> => {\n if (options?.path) {\n const pattern = `${directory}/${options.path}/**/*.{md,mdx}`;\n return getResources(directory, { type: 'docs', pattern }) as Promise<CustomDoc[]>;\n }\n return getResources(directory, { type: 'docs', pattern: `${directory}/**/*.{md,mdx}` }) as Promise<CustomDoc[]>;\n };\n\n/**\n * Write a custom doc to EventCatalog.\n *\n * You can optionally override the path of the custom doc.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeCustomDoc } = utils('/path/to/eventcatalog');\n *\n * // Write a custom doc to the catalog\n * // Custom doc would be written to docs/inventory-management.mdx\n * await writeCustomDoc({\n * title: 'Inventory Management',\n * summary: 'This is a summary',\n * owners: ['John Doe'],\n * badges: [{ content: 'Badge', backgroundColor: 'red', textColor: 'white' }],\n * markdown: '# Hello world',\n * fileName: 'inventory-management',\n * });\n *\n * // Write a custom doc to the catalog but override the path\n * // Custom doc would be written to docs/guides/inventory-management/introduction.mdx\n * await writeCustomDoc({\n * title: 'Inventory Management',\n * summary: 'This is a summary',\n * owners: ['John Doe'],\n * badges: [{ content: 'Badge', backgroundColor: 'red', textColor: 'white' }],\n * markdown: '# Hello world',\n * fileName: 'introduction',\n * }, { path: \"/guides/inventory-management\"});\n * ```\n */\nexport const writeCustomDoc =\n (directory: string) =>\n async (customDoc: CustomDoc, options: { path?: string } = { path: '' }): Promise<void> => {\n const { fileName, ...rest } = customDoc;\n const name = fileName || slugify(customDoc.title, { lower: true });\n const withExtension = name.endsWith('.mdx') ? name : `${name}.mdx`;\n const fullPath = path.join(directory, options.path || '', withExtension);\n\n fsSync.mkdirSync(path.dirname(fullPath), { recursive: true });\n const document = matter.stringify(customDoc.markdown.trim(), rest);\n fsSync.writeFileSync(fullPath, document);\n };\n\n/**\n * Delete a custom doc by its' path\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmCustomDoc } = utils('/path/to/eventcatalog');\n *\n * // removes a custom doc at the given path\n * // Removes the custom doc at docs/guides/inventory-management/introduction.mdx\n * await rmCustomDoc('/guides/inventory-management/introduction');\n * ```\n */\nexport const rmCustomDoc = (directory: string) => async (filePath: string) => {\n const withExtension = filePath.endsWith('.mdx') ? filePath : `${filePath}.mdx`;\n await fs.rm(join(directory, withExtension), { recursive: true });\n};\n","import fs from 'node:fs/promises';\nimport fsSync from 'node:fs';\nimport { join } from 'node:path';\nimport type { Team } from './types';\nimport matter from 'gray-matter';\nimport { getFiles } from './internal/utils';\n\n/**\n * Returns a team from EventCatalog.\n *\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getTeam } = utils('/path/to/eventcatalog');\n *\n * // Gets the team with the given id\n * const team = await getTeam('eventcatalog-core-team');\n *\n * ```\n */\nexport const getTeam =\n (catalogDir: string) =>\n async (id: string): Promise<Team | undefined> => {\n const files = await getFiles(`${catalogDir}/${id}.{md,mdx}`);\n\n if (files.length == 0) return undefined;\n const file = files[0];\n\n const { data, content } = matter.read(file);\n return {\n ...data,\n id: data.id,\n name: data.name,\n markdown: content.trim(),\n } as Team;\n };\n\n/**\n * Returns all teams from EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getTeams } = utils('/path/to/eventcatalog');\n *\n * // Gets all teams from the catalog\n * const channels = await getTeams();\n *\n * ```\n */\nexport const getTeams =\n (catalogDir: string) =>\n async (options?: {}): Promise<Team[]> => {\n const files = await getFiles(`${catalogDir}/teams/*.{md,mdx}`);\n if (files.length === 0) return [];\n\n return files.map((file) => {\n const { data, content } = matter.read(file);\n return {\n ...data,\n id: data.id,\n name: data.name,\n markdown: content.trim(),\n } as Team;\n });\n };\n\n/**\n * Write a team to EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeTeam } = utils('/path/to/eventcatalog');\n *\n * // Write a team to the catalog\n * // team would be written to teams/EventCatalogCoreTeam\n * await writeTeam({\n * id: 'eventcatalog-core-team',\n * name: 'EventCatalogCoreTeam',\n * members: ['dboyne', 'asmith', 'msmith'],\n * email: 'test@test.com',\n * slackDirectMessageUrl: https://yourteam.slack.com/channels/boyney123\n * });\n *\n * // Write a team to the catalog and override the existing content (if there is any)\n * await writeTeam({\n * id: 'eventcatalog-core-team',\n * name: 'EventCatalogCoreTeam',\n * members: ['dboyne', 'asmith', 'msmith'],\n * email: 'test@test.com',\n * slackDirectMessageUrl: https://yourteam.slack.com/channels/boyney123\n * }, { override: true });\n *\n * ```\n */\nexport const writeTeam =\n (catalogDir: string) =>\n async (team: Team, options: { override?: boolean } = {}) => {\n const resource: Team = { ...team };\n\n // Get the path\n const currentTeam = await getTeam(catalogDir)(resource.id);\n const exists = currentTeam !== undefined;\n\n if (exists && !options.override) {\n throw new Error(`Failed to write ${resource.id} (team) as it already exists`);\n }\n\n const { markdown, ...frontmatter } = resource;\n\n const document = matter.stringify(markdown, frontmatter);\n fsSync.mkdirSync(join(catalogDir, ''), { recursive: true });\n fsSync.writeFileSync(join(catalogDir, '', `${resource.id}.mdx`), document);\n };\n\n/**\n * Delete a team by it's id.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmTeamById } = utils('/path/to/eventcatalog');\n *\n * // deletes the EventCatalogCoreTeam team\n * await rmTeamById('eventcatalog-core-team');\n *\n * ```\n */\nexport const rmTeamById = (catalogDir: string) => async (id: string) => {\n await fs.rm(join(catalogDir, `${id}.mdx`), { recursive: true });\n};\n","import fs from 'node:fs/promises';\nimport fsSync from 'node:fs';\nimport { join } from 'node:path';\nimport type { User } from './types';\nimport matter from 'gray-matter';\nimport { getFiles } from './internal/utils';\n\n/**\n * Returns a user from EventCatalog.\n *\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getUser } = utils('/path/to/eventcatalog');\n *\n * // Gets the user with the given id\n * const user = await getUser('eventcatalog-core-user');\n *\n * ```\n */\nexport const getUser =\n (catalogDir: string) =>\n async (id: string): Promise<User | undefined> => {\n const files = await getFiles(`${catalogDir}/${id}.{md,mdx}`);\n\n if (files.length == 0) return undefined;\n const file = files[0];\n\n const { data, content } = matter.read(file);\n return {\n ...data,\n id: data.id,\n name: data.name,\n avatarUrl: data.avatarUrl,\n markdown: content.trim(),\n } as User;\n };\n\n/**\n * Returns all users from EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getUsers } = utils('/path/to/eventcatalog');\n *\n * // Gets all users from the catalog\n * const channels = await getUsers();\n *\n * ```\n */\nexport const getUsers =\n (catalogDir: string) =>\n async (options?: {}): Promise<User[]> => {\n const files = await getFiles(`${catalogDir}/users/*.{md,mdx}`);\n if (files.length === 0) return [];\n\n return files.map((file) => {\n const { data, content } = matter.read(file);\n return {\n ...data,\n id: data.id,\n name: data.name,\n avatarUrl: data.avatarUrl,\n markdown: content.trim(),\n } as User;\n });\n };\n\n/**\n * Write a user to EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeUser } = utils('/path/to/eventcatalog');\n *\n * // Write a user to the catalog\n * // user would be written to users/eventcatalog-tech-lead\n * await writeUser({\n * id: 'eventcatalog-tech-lead',\n * name: 'EventCatalog Tech Lead',\n * email: 'test@test.com',\n * avatarUrl: 'https://pbs.twimg.com/profile_images/1262283153563140096/DYRDqKg6_400x400.png',\n * slackDirectMessageUrl: https://yourteam.slack.com/channels/boyney123\n * });\n *\n * // Write a team to the catalog and override the existing content (if there is any)\n * await writeUser({\n * id: 'eventcatalog-tech-lead',\n * name: 'EventCatalog Tech Lead',\n * email: 'test@test.com',\n * avatarUrl: 'https://pbs.twimg.com/profile_images/1262283153563140096/DYRDqKg6_400x400.png',\n * slackDirectMessageUrl: https://yourteam.slack.com/channels/boyney123\n * }, { override: true });\n *\n * ```\n */\nexport const writeUser =\n (catalogDir: string) =>\n async (user: User, options: { override?: boolean } = {}) => {\n const resource: User = { ...user };\n\n // Get the path\n const currentUser = await getUser(catalogDir)(resource.id);\n const exists = currentUser !== undefined;\n\n if (exists && !options.override) {\n throw new Error(`Failed to write ${resource.id} (user) as it already exists`);\n }\n\n const { markdown, ...frontmatter } = resource;\n\n const document = matter.stringify(markdown, frontmatter);\n fsSync.mkdirSync(join(catalogDir, ''), { recursive: true });\n fsSync.writeFileSync(join(catalogDir, '', `${resource.id}.mdx`), document);\n };\n\n/**\n * Delete a user by it's id.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmUserById } = utils('/path/to/eventcatalog');\n *\n * // deletes the user with id eventcatalog-core-user\n * await rmUserById('eventcatalog-core-user');\n *\n * ```\n */\nexport const rmUserById = (catalogDir: string) => async (id: string) => {\n fsSync.rmSync(join(catalogDir, `${id}.mdx`), { recursive: true });\n};\n"],"mappings":";AACA,OAAOA,UAAQ;AACf,OAAOC,SAAQ,QAAAC,cAAY;;;ACF3B,SAAS,QAAAC,cAAY;;;ACArB,OAAOC,SAAQ;AACf,SAAS,QAAAC,aAAqB;;;ACD9B,SAAS,gBAAgB;AACzB,OAAO,YAAY;AACnB,SAAS,YAA6C;AACtD,SAAS,MAAM,eAAe;AAC9B,OAAO,YAAY;AACnB,SAAS,WAAW,YAAY,aAAa;AAKtC,IAAM,gBAAgB,OAAO,YAAoB,IAAY,YAAoB;AACtF,QAAM,QAAQ,MAAM,SAAS,GAAG,UAAU,oBAAoB;AAC9D,QAAM,eAAgB,MAAM,iBAAiB,OAAO,IAAI,OAAO,KAAM,CAAC;AACtE,SAAO,aAAa,SAAS;AAC/B;AAEO,IAAM,eAAe,OAAO,YAAoB,IAAY,YAAkD;AACnH,QAAM,QAAQ,MAAM,SAAS,GAAG,UAAU,oBAAoB;AAE9D,QAAM,eAAgB,MAAM,iBAAiB,OAAO,EAAE,KAAM,CAAC;AAC7D,QAAM,gBAAgB,aAAa,KAAK,CAACC,UAAS,CAACA,MAAK,SAAS,WAAW,CAAC;AAG7E,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAGA,QAAM,cAAc,aAAa,IAAI,CAACA,UAAS;AAC7C,UAAM,EAAE,KAAK,IAAI,OAAO,KAAKA,KAAI;AACjC,WAAO,EAAE,GAAG,MAAM,MAAAA,MAAK;AAAA,EACzB,CAAC;AAED,QAAM,cAAc,WAAW,OAAO;AAEtC,MAAI,eAAe,MAAM,OAAO,GAAG;AACjC,UAAMC,SAAQ,YAAY,OAAO,CAAC,MAAM,UAAU,EAAE,SAAS,WAAW,CAAC;AACzE,WAAOA,OAAM,SAAS,IAAIA,OAAM,CAAC,EAAE,OAAO;AAAA,EAC5C;AAGA,QAAM,SAAS,YAAY,KAAK,CAAC,GAAG,MAAM;AACxC,WAAO,EAAE,QAAQ,cAAc,EAAE,OAAO;AAAA,EAC1C,CAAC;AAGD,QAAM,QAAQ,OAAO,SAAS,IAAI,CAAC,OAAO,OAAO,SAAS,CAAC,CAAC,IAAI,CAAC;AAEjE,MAAI,MAAM,SAAS,GAAG;AACpB,WAAO,MAAM,CAAC,EAAE;AAAA,EAClB;AACF;AAEO,IAAM,WAAW,OAAO,SAAiB,SAA4B,OAAO;AACjF,MAAI;AACF,UAAM,aAAa,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AAC3D,UAAM,UAAU,QAAQ,SAAS,IAAI,IAAI,QAAQ,MAAM,IAAI,EAAE,CAAC,IAAI,QAAQ,OAAO;AACjF,UAAM,QAAQ,SAAS,SAAS,EAAE,KAAK,SAAS,QAAQ,CAAC,mBAAmB,GAAG,UAAU,EAAE,CAAC;AAC5F,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,wBAAwB,KAAK,EAAE;AAAA,EACjD;AACF;AAEO,IAAM,cAAc,OAAOD,UAAiB;AACjD,QAAM,EAAE,KAAK,IAAI,OAAO,KAAKA,KAAI;AACjC,QAAM,EAAE,UAAU,GAAG,YAAY,IAAI;AACrC,SAAO,EAAE,GAAG,aAAa,SAAS;AACpC;AAEO,IAAM,mBAAmB,OAAO,OAAiB,IAAY,YAAqB;AACvF,QAAM,UAAU,IAAI,OAAO,yBAAyB,EAAE,cAAc,GAAG;AACvE,QAAM,eAAe,IAAI,OAAO,qBAAqB,OAAO,cAAc,GAAG;AAE7E,QAAM,UAAU,MAAM,IAAI,CAAC,SAAS;AAClC,UAAM,UAAU,OAAO,aAAa,MAAM,OAAO;AACjD,UAAM,aAAa,QAAQ,MAAM,OAAO;AAGxC,QAAI,WAAW,CAAC,QAAQ,MAAM,YAAY,GAAG;AAC3C,aAAO;AAAA,IACT;AAEA,QAAI,YAAY;AACd,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,SAAO,QAAQ,OAAO,OAAO,EAAE,OAAO,CAAC,SAAS,SAAS,MAAS;AACpE;AASO,IAAM,UAAU,OAAO,YAAoB,QAAgB,QAAgB,WAA8C;AAC9H,QAAM,eAAe,KAAK,YAAY,KAAK;AAC3C,SAAO,UAAU,cAAc,EAAE,WAAW,KAAK,CAAC;AAGlD,QAAM,KAAK,QAAQ,cAAc;AAAA,IAC/B,WAAW;AAAA,IACX;AAAA,EACF,CAAC;AAED,QAAM,KAAK,cAAc,QAAQ;AAAA,IAC/B,WAAW;AAAA,IACX;AAAA,EACF,CAAC;AAGD,SAAO,OAAO,cAAc,EAAE,WAAW,KAAK,CAAC;AACjD;AAGO,IAAM,iBAAiB,CAAC,aAAmF;AAChH,QAAM,YAAY,oBAAI,IAAI;AAE1B,SAAO,SAAS,OAAO,CAAC,YAAY;AAClC,UAAM,MAAM,GAAG,QAAQ,EAAE,IAAI,QAAQ,OAAO;AAC5C,QAAI,CAAC,UAAU,IAAI,GAAG,GAAG;AACvB,gBAAU,IAAI,GAAG;AACjB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,CAAC;AACH;;;ACjIA,SAAS,WAAAE,UAAS,QAAAC,aAAY;AAE9B,OAAOC,aAAY;AACnB,OAAO,QAAQ;AACf,OAAOC,aAAY;AAEnB,SAAS,aAAAC,kBAAiB;AAC1B,SAAS,MAAM,cAAc;AAItB,IAAM,kBAAkB,OAAO,YAAoB,OAAe;AAEvE,QAAM,QAAQ,MAAM,SAAS,GAAG,UAAU,oBAAoB;AAC9D,QAAM,eAAe,MAAM,iBAAiB,OAAO,EAAE;AAErD,MAAI,aAAa,WAAW,GAAG;AAC7B,UAAM,IAAI,MAAM,8BAA8B,EAAE,EAAE;AAAA,EACpD;AAGA,QAAM,OAAO,aAAa,CAAC;AAC3B,QAAM,kBAAkBC,SAAQ,IAAI;AACpC,QAAM,EAAE,MAAM,EAAE,UAAU,QAAQ,IAAI,CAAC,EAAE,IAAIH,QAAO,KAAK,IAAI;AAC7D,QAAM,kBAAkB,sBAAsB,iBAAiB,OAAO;AAEtE,EAAAC,QAAO,UAAU,iBAAiB,EAAE,WAAW,KAAK,CAAC;AAGrD,QAAM,QAAQ,YAAY,iBAAiB,iBAAiB,CAAC,QAAQ;AACnE,WAAO,CAAC,IAAI,SAAS,WAAW;AAAA,EAClC,CAAC;AAGD,QAAM,GAAG,QAAQ,eAAe,EAAE,KAAK,OAAO,kBAAkB;AAC9D,UAAM,QAAQ;AAAA,MACZ,cAAc,IAAI,OAAOG,UAAS;AAChC,YAAIA,UAAS,aAAa;AACxB,UAAAH,QAAO,OAAOI,MAAK,iBAAiBD,KAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,QAChE;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AACH;AAEO,IAAM,gBAAgB,OAC3B,YACA,UACA,UAAwH;AAAA,EACtH,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,wBAAwB;AAAA,EACxB,QAAQ;AACV,MACG;AACH,QAAME,QAAO,QAAQ,QAAQ,IAAI,SAAS,EAAE;AAC5C,QAAM,WAAWD,MAAK,YAAYC,KAAI;AACtC,QAAM,SAAS,QAAQ,UAAU;AAGjC,EAAAL,QAAO,UAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AAG9C,QAAM,WAAWI,MAAK,UAAU,SAAS,MAAM,EAAE;AAGjD,MAAI,CAACJ,QAAO,WAAW,QAAQ,GAAG;AAChC,IAAAA,QAAO,cAAc,UAAU,EAAE;AAAA,EACnC;AAEA,MAAI;AAEF,UAAM,KAAK,UAAU;AAAA,MACnB,SAAS;AAAA,MACT,OAAO;AAAA;AAAA,IACT,CAAC;AAED,UAAM,SAAS,MAAM,cAAc,YAAY,SAAS,IAAI,SAAS,OAAO;AAE5E,QAAI,UAAU,CAAC,QAAQ,UAAU;AAC/B,YAAM,IAAI,MAAM,mBAAmB,SAAS,EAAE,KAAK,QAAQ,IAAI,oBAAoB,SAAS,OAAO,iBAAiB;AAAA,IACtH;AAEA,UAAM,EAAE,UAAU,GAAG,YAAY,IAAI;AAErC,QAAI,QAAQ,0BAA0B,CAAC,QAAQ;AAC7C,YAAM,kBAAkB,MAAM,YAAY,YAAY,SAAS,EAAE;AAEjE,UAAI,iBAAiB;AACnB,YAAIC,WAAU,SAAS,SAAS,IAAI,gBAAgB,OAAO,EAAE,GAAG;AAC9D,gBAAM,gBAAgB,YAAY,SAAS,EAAE;AAAA,QAC/C,OAAO;AACL,gBAAM,IAAI,MAAM,eAAe,SAAS,OAAO,wCAAwC,gBAAgB,OAAO,EAAE;AAAA,QAClH;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAAWF,QAAO,UAAU,SAAS,KAAK,GAAG,WAAW;AAC9D,IAAAC,QAAO,cAAc,UAAU,QAAQ;AAAA,EACzC,UAAE;AAEA,UAAM,OAAO,QAAQ,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACvC;AACF;AAEO,IAAM,cAAc,OACzB,YACA,IACA,SACA,YACkC;AAClC,QAAM,OAAO,MAAM,aAAa,YAAY,IAAI,OAAO;AACvD,MAAI,CAAC,KAAM;AAEX,QAAM,EAAE,MAAM,QAAQ,IAAID,QAAO,KAAK,IAAI;AAE1C,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU,QAAQ,KAAK;AAAA,EACzB;AACF;AAEO,IAAM,kBAAkB,OAAO,YAAoB,IAAY,YAAqB;AACzF,QAAM,OAAO,MAAM,aAAa,YAAY,IAAI,OAAO;AACvD,MAAI,CAAC,KAAM;AAEX,SAAO;AAAA,IACL,UAAU;AAAA,IACV,cAAc,KAAK,QAAQ,YAAY,EAAE;AAAA,IACzC,WAAWG,SAAQ,KAAK,QAAQ,YAAY,EAAE,CAAC;AAAA,EACjD;AACF;AAEO,IAAM,eAAe,OAC1B,YACA;AAAA,EACE;AAAA,EACA,aAAa;AAAA,EACb,SAAS,CAAC;AAAA,EACV,UAAU;AACZ,MACoC;AACpC,QAAM,aAAa,aAAa,oBAAoB;AACpD,QAAM,cAAc,WAAW,GAAG,UAAU,OAAO,IAAI;AACvD,QAAM,QAAQ,MAAM,SAAS,aAAa,CAAC,YAAY,GAAG,MAAM,CAAC;AAEjE,MAAI,MAAM,WAAW,EAAG;AAExB,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,UAAM,EAAE,MAAM,QAAQ,IAAIH,QAAO,KAAK,IAAI;AAC1C,WAAO;AAAA,MACL,GAAG;AAAA,MACH,UAAU,QAAQ,KAAK;AAAA,IACzB;AAAA,EACF,CAAC;AACH;AAEO,IAAM,iBAAiB,OAC5B,YACA,IACA,SACA,YACG;AACH,QAAM,QAAQ,MAAM,SAAS,GAAG,UAAU,oBAAoB;AAE9D,QAAM,eAAe,MAAM,iBAAiB,OAAO,IAAI,OAAO;AAE9D,MAAI,aAAa,WAAW,GAAG;AAC7B,UAAM,IAAI,MAAM,MAAM,SAAS,QAAQ,UAAU,mBAAmB,EAAE,EAAE;AAAA,EAC1E;AAEA,MAAI,SAAS,cAAc;AACzB,UAAM,QAAQ;AAAA,MACZ,aAAa,IAAI,OAAO,SAAS;AAC/B,cAAM,GAAG,GAAG,MAAM,EAAE,WAAW,KAAK,CAAC;AAAA,MACvC,CAAC;AAAA,IACH;AAAA,EACF,OAAO;AACL,UAAM,QAAQ;AAAA,MACZ,aAAa,IAAI,OAAO,SAAS;AAC/B,cAAM,YAAYG,SAAQ,IAAI;AAC9B,cAAM,GAAG,GAAG,WAAW,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,MACzD,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,IAAM,oBAAoB,OAC/B,YACA,IACA,MACA,YACG;AACH,QAAM,iBAAiB,MAAM,aAAa,YAAY,IAAI,OAAO;AAEjE,MAAI,CAAC,eAAgB,OAAM,IAAI,MAAM,wCAAwC;AAE7E,EAAAF,QAAO,cAAcI,MAAKF,SAAQ,cAAc,GAAG,KAAK,QAAQ,GAAG,KAAK,OAAO;AACjF;AAEO,IAAM,sBAAsB,OAAO,YAAoB,IAAY,MAA4B,YAAqB;AACzH,QAAM,iBAAiB,MAAM,aAAa,YAAY,IAAI,OAAO;AAEjE,MAAI,CAAC,eAAgB,OAAM,IAAI,MAAM,mCAAmC;AAExE,QAAM,SAAS,MAAM,GAClB,OAAOE,MAAKF,SAAQ,cAAc,GAAG,KAAK,QAAQ,CAAC,EACnD,KAAK,MAAM,IAAI,EACf,MAAM,MAAM,KAAK;AACpB,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,QAAQ,KAAK,QAAQ,+BAA+B,EAAE,MAAM,OAAO,GAAG;AAEnG,SAAOF,QAAO,aAAaI,MAAKF,SAAQ,cAAc,GAAG,KAAK,QAAQ,GAAG,OAAO;AAClF;AACO,IAAM,wBAAwB,CAAC,iBAAyB,YAAyB;AACtF,SAAOE,MAAK,iBAAiB,aAAa,OAAO;AACnD;;;AFxLO,IAAM,WACX,CAAC,cACD,OAAO,IAAY,YACjB,YAAY,WAAW,IAAI,SAAS,EAAE,MAAM,QAAQ,CAAC;AAoBlD,IAAM,YACX,CAAC,cACD,OAAO,YACL,aAAa,WAAW,EAAE,MAAM,UAAU,GAAG,QAAQ,CAAC;AAsDnD,IAAM,aACX,CAAC,cACD,OACE,OACA,UAA0G;AAAA,EACxG,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ;AACV,MAEA,cAAc,WAAW,EAAE,GAAG,MAAM,GAAG,EAAE,GAAG,SAAS,MAAM,QAAQ,CAAC;AAuBjE,IAAM,sBACX,CAAC,cACD,OACE,OACA,SACA,UAAoD,EAAE,MAAM,IAAI,QAAQ,MAAM,MAC3E;AACH,QAAM,eAAe,MAAM,gBAAgB,WAAW,QAAQ,IAAI,QAAQ,OAAO;AACjF,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,MAAM,mBAAmB;AAAA,EACrC;AAEA,MAAI,eACF,QAAQ,WAAW,QAAQ,YAAY,WACnC,GAAG,aAAa,SAAS,cAAc,QAAQ,OAAO,YACtD,GAAG,aAAa,SAAS;AAC/B,iBAAeE,MAAK,cAAc,MAAM,EAAE;AAC1C,QAAM,cAAc,WAAW,EAAE,GAAG,MAAM,GAAG,EAAE,GAAG,SAAS,MAAM,cAAc,MAAM,QAAQ,CAAC;AAChG;AAgBK,IAAM,UAAU,CAAC,cAAsB,OAAOC,UAAiB;AACpE,QAAMC,IAAG,GAAGF,MAAK,WAAWC,KAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACxD;AAoBO,IAAM,cAAc,CAAC,cAAsB,OAAO,IAAY,SAAkB,iBAA2B;AAChH,QAAM,eAAe,WAAW,IAAI,SAAS,EAAE,MAAM,SAAS,aAAa,CAAC;AAC9E;AAoBO,IAAM,eAAe,CAAC,cAAsB,OAAO,OAAe,gBAAgB,WAAW,EAAE;AAqB/F,IAAM,iBACX,CAAC,cAAsB,OAAO,IAAY,MAA6C,YACrF,kBAAkB,WAAW,IAAI,MAAM,OAAO;AAoC3C,IAAM,mBACX,CAAC,cAAsB,OAAO,IAAY,QAA8C,YAAqB;AAC3G,QAAM,eAAe,SAAS,EAAE,IAAI,EAAE,SAAS,OAAO,QAAQ,UAAU,OAAO,SAAS,GAAG,OAAO;AACpG;AAkBK,IAAM,kBAAkB,CAAC,cAAsB,OAAO,IAAY,YAAqB;AAC5F,QAAM,OAAO,MAAM,aAAa,WAAW,IAAI,OAAO;AACtD,SAAO,CAAC,CAAC;AACX;;;AGlTA,OAAOE,SAAQ;AACf,SAAS,QAAAC,aAAY;AAgCd,IAAM,aACX,CAAC,cACD,OAAO,IAAY,YACjB,YAAY,WAAW,IAAI,SAAS,EAAE,MAAM,UAAU,CAAC;AAoBpD,IAAM,cACX,CAAC,cACD,OAAO,YACL,aAAa,WAAW,EAAE,MAAM,YAAY,GAAG,QAAQ,CAAC;AAsDrD,IAAM,eACX,CAAC,cACD,OACE,SACA,UAA0G;AAAA,EACxG,MAAM;AAAA,EACN,UAAU;AAAA,EACV,wBAAwB;AAAA,EACxB,QAAQ;AACV,MAEA,cAAc,WAAW,EAAE,GAAG,QAAQ,GAAG,EAAE,GAAG,SAAS,MAAM,UAAU,CAAC;AAsBrE,IAAM,wBACX,CAAC,cACD,OACE,SACA,SACA,UAAoD,EAAE,MAAM,IAAI,QAAQ,MAAM,MAC3E;AACH,QAAM,eAAe,MAAM,gBAAgB,WAAW,QAAQ,IAAI,QAAQ,OAAO;AACjF,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,MAAM,mBAAmB;AAAA,EACrC;AAEA,MAAI,iBACF,QAAQ,WAAW,QAAQ,YAAY,WACnC,GAAG,aAAa,SAAS,cAAc,QAAQ,OAAO,cACtD,GAAG,aAAa,SAAS;AAC/B,mBAAiBC,MAAK,gBAAgB,QAAQ,EAAE;AAEhD,QAAM,cAAc,WAAW,EAAE,GAAG,QAAQ,GAAG,EAAE,GAAG,SAAS,MAAM,gBAAgB,MAAM,UAAU,CAAC;AACtG;AAgBK,IAAM,YAAY,CAAC,cAAsB,OAAOC,UAAiB;AACtE,QAAMC,IAAG,GAAGF,MAAK,WAAWC,KAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACxD;AAoBO,IAAM,gBAAgB,CAAC,cAAsB,OAAO,IAAY,SAAkB,iBACvF,eAAe,WAAW,IAAI,SAAS,EAAE,MAAM,WAAW,aAAa,CAAC;AAoBnE,IAAM,iBAAiB,CAAC,cAAsB,OAAO,OAAe,gBAAgB,WAAW,EAAE;AAqBjG,IAAM,mBACX,CAAC,cAAsB,OAAO,IAAY,MAA6C,YACrF,kBAAkB,WAAW,IAAI,MAAM,OAAO;AAoC3C,IAAM,qBACX,CAAC,cAAsB,OAAO,IAAY,QAA8C,YAAqB;AAC3G,QAAM,iBAAiB,SAAS,EAAE,IAAI,EAAE,SAAS,OAAO,QAAQ,UAAU,OAAO,SAAS,GAAG,OAAO;AACtG;AAkBK,IAAM,oBAAoB,CAAC,cAAsB,OAAO,IAAY,YAAqB;AAC9F,QAAM,OAAO,MAAM,aAAa,WAAW,IAAI,OAAO;AACtD,SAAO,CAAC,CAAC;AACX;;;ACnTA,OAAOE,SAAQ;AACf,SAAS,QAAAC,aAAY;AA+Bd,IAAM,WACX,CAAC,cACD,OAAO,IAAY,YACjB,YAAY,WAAW,IAAI,SAAS,EAAE,MAAM,QAAQ,CAAC;AAsDlD,IAAM,aACX,CAAC,cACD,OACE,OACA,UAA0G;AAAA,EACxG,MAAM;AAAA,EACN,UAAU;AAAA,EACV,wBAAwB;AAAA,EACxB,QAAQ;AACV,MAEA,cAAc,WAAW,EAAE,GAAG,MAAM,GAAG,EAAE,GAAG,SAAS,MAAM,QAAQ,CAAC;AAoBjE,IAAM,aACX,CAAC,cACD,OAAO,YACL,aAAa,WAAW,EAAE,MAAM,WAAW,GAAG,QAAQ,CAAC;AAwBpD,IAAM,sBACX,CAAC,cACD,OACE,OACA,SACA,UAAoD,EAAE,MAAM,IAAI,QAAQ,MAAM,MAC3E;AACH,QAAM,eAAe,MAAM,gBAAgB,WAAW,QAAQ,IAAI,QAAQ,OAAO;AACjF,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,MAAM,mBAAmB;AAAA,EACrC;AACA,MAAI,eACF,QAAQ,WAAW,QAAQ,YAAY,WACnC,GAAG,aAAa,SAAS,cAAc,QAAQ,OAAO,aACtD,GAAG,aAAa,SAAS;AAC/B,iBAAeC,MAAK,cAAc,MAAM,EAAE;AAC1C,QAAM,cAAc,WAAW,EAAE,GAAG,MAAM,GAAG,EAAE,GAAG,SAAS,MAAM,cAAc,MAAM,QAAQ,CAAC;AAChG;AAgBK,IAAM,UAAU,CAAC,cAAsB,OAAOC,UAAiB;AACpE,QAAMC,IAAG,GAAGF,MAAK,WAAWC,KAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACxD;AAoBO,IAAM,cAAc,CAAC,cAAsB,OAAO,IAAY,SAAkB,iBAA2B;AAChH,QAAM,eAAe,WAAW,IAAI,SAAS,EAAE,MAAM,SAAS,aAAa,CAAC;AAC9E;AAoBO,IAAM,eAAe,CAAC,cAAsB,OAAO,OAAe,gBAAgB,WAAW,EAAE;AAqB/F,IAAM,iBACX,CAAC,cAAsB,OAAO,IAAY,MAA6C,YACrF,kBAAkB,WAAW,IAAI,MAAM,OAAO;AAoC3C,IAAM,mBACX,CAAC,cAAsB,OAAO,IAAY,QAA8C,YAAqB;AAC3G,QAAM,eAAe,SAAS,EAAE,IAAI,EAAE,SAAS,OAAO,QAAQ,UAAU,OAAO,SAAS,GAAG,OAAO;AACpG;AAkBK,IAAM,kBAAkB,CAAC,cAAsB,OAAO,IAAY,YAAqB;AAC5F,QAAM,OAAO,MAAM,aAAa,WAAW,IAAI,OAAO;AACtD,SAAO,CAAC,CAAC;AACX;;;AClTA,OAAOE,SAAQ;AACf,SAAS,QAAAC,OAAM,WAAAC,UAAS,eAAe;AAgChC,IAAM,aACX,CAAC,cACD,OAAO,IAAY,YACjB,YAAY,WAAW,IAAI,SAAS,EAAE,MAAM,UAAU,CAAC;AAoBpD,IAAM,cACX,CAAC,cACD,OAAO,YACL,aAAa,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,QAAQ,CAAC,gBAAgB,kBAAkB,eAAe;AAAA,EAC1D,GAAG;AACL,CAAC;AAsDE,IAAM,eACX,CAAC,cACD,OACE,SACA,UAA0G;AAAA,EACxG,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ;AACV,MACG;AACH,QAAM,WAAoB,EAAE,GAAG,QAAQ;AAEvC,MAAI,MAAM,QAAQ,QAAQ,KAAK,GAAG;AAChC,aAAS,QAAQ,eAAe,QAAQ,KAAK;AAAA,EAC/C;AAEA,MAAI,MAAM,QAAQ,QAAQ,QAAQ,GAAG;AACnC,aAAS,WAAW,eAAe,QAAQ,QAAQ;AAAA,EACrD;AAEA,SAAO,MAAM,cAAc,WAAW,UAAU,EAAE,GAAG,SAAS,MAAM,UAAU,CAAC;AACjF;AAyBK,IAAM,wBAAwB,CAAC,cAAsB,OAAO,YAAqB;AACtF,QAAM,WAAoB,EAAE,GAAG,QAAQ;AACvC,QAAMC,QAAO,sBAAsB,QAAQ,IAAI,QAAQ,OAAO;AAE9D,SAAO,MAAM,aAAa,SAAS,EAAE,UAAU,EAAE,MAAMA,MAAK,CAAC;AAC/D;AAsBO,IAAM,uBACX,CAAC,cACD,OACE,SACA,QACA,UAAoD,EAAE,MAAM,IAAI,QAAQ,MAAM,MAC3E;AACH,MAAI,iBACF,OAAO,WAAW,OAAO,YAAY,WACjC,IAAI,OAAO,EAAE,cAAc,OAAO,OAAO,cACzC,IAAI,OAAO,EAAE;AACnB,mBAAiBC,MAAK,gBAAgB,QAAQ,EAAE;AAGhD,QAAM,cAAc,WAAW,EAAE,GAAG,QAAQ,GAAG,EAAE,GAAG,SAAS,MAAM,gBAAgB,MAAM,UAAU,CAAC;AACtG;AAoBK,IAAM,iBAAiB,CAAC,cAAsB,OAAO,OAAe,gBAAgB,WAAW,EAAE;AAejG,IAAM,YAAY,CAAC,cAAsB,OAAOD,UAAiB;AACtE,QAAME,IAAG,GAAGD,MAAK,WAAWD,KAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACxD;AAoBO,IAAM,gBAAgB,CAAC,cAAsB,OAAO,IAAY,SAAkB,iBACvF,eAAe,WAAW,IAAI,SAAS,EAAE,MAAM,WAAW,aAAa,CAAC;AAsBnE,IAAM,mBACX,CAAC,cAAsB,OAAO,IAAY,MAA6C,YACrF,kBAAkB,WAAW,IAAI,MAAM,OAAO;AAmB3C,IAAM,kCAAkC,CAAC,cAAsB,OAAO,IAAY,YAAqB;AAC5G,MAAI,UAAmB,MAAM,WAAW,SAAS,EAAE,IAAI,OAAO;AAC9D,QAAM,oBAAoB,MAAM,aAAa,WAAW,IAAI,OAAO;AAEnE,MAAI,CAAC,kBAAmB,OAAM,IAAI,MAAM,kCAAkC;AAE1E,MAAI,QAAQ,CAAC;AACb,MAAI,QAAQ,gBAAgB;AAC1B,UAAM,wBAAwB,QAAQ;AACtC,UAAM,qBAAqB,OAAO,KAAK,qBAAqB;AAE5D,UAAM,WAAW,mBAAmB,IAAI,OAAO,aAAa;AAC1D,YAAM,WAAW,sBAAsB,QAAgC;AAEvE,UAAI,CAAC,UAAU;AACb,cAAM,IAAI,MAAM,+BAA+B,QAAQ,eAAe;AAAA,MACxE;AACA,YAAM,UAAU,MAAM,oBAAoB,WAAW,IAAI,EAAE,SAAS,GAAG,OAAO;AAE9E,aAAO,EAAE,KAAK,UAAU,SAAS,SAAS,UAAoB,MAAMC,MAAKE,SAAQ,iBAAiB,GAAG,QAAQ,EAAE;AAAA,IACjH,CAAC;AAED,YAAQ,MAAM,QAAQ,IAAI,QAAQ;AAAA,EACpC;AACA,SAAO;AACT;AA2BO,IAAM,sBACX,CAAC,cAAsB,OAAO,IAAY,WAAmB,OAAwC,YAAqB;AACxH,MAAI,UAAmB,MAAM,WAAW,SAAS,EAAE,IAAI,OAAO;AAC9D,QAAM,cAAc,MAAM,gBAAgB,WAAW,IAAI,OAAO;AAChE,QAAM,YAAY,QAAQ,aAAa,YAAY,EAAE;AAErD,MAAI,cAAc,SAAS;AACzB,QAAI,QAAQ,UAAU,QAAW;AAC/B,cAAQ,QAAQ,CAAC;AAAA,IACnB;AAEA,aAAS,IAAI,GAAG,IAAI,QAAQ,MAAM,QAAQ,KAAK;AAC7C,UAAI,QAAQ,MAAM,CAAC,EAAE,OAAO,MAAM,MAAM,QAAQ,MAAM,CAAC,EAAE,YAAY,MAAM,SAAS;AAClF;AAAA,MACF;AAAA,IACF;AACA,YAAQ,MAAM,KAAK,EAAE,IAAI,MAAM,IAAI,SAAS,MAAM,QAAQ,CAAC;AAAA,EAC7D,WAAW,cAAc,YAAY;AACnC,QAAI,QAAQ,aAAa,QAAW;AAClC,cAAQ,WAAW,CAAC;AAAA,IACtB;AAEA,aAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,QAAQ,KAAK;AAChD,UAAI,QAAQ,SAAS,CAAC,EAAE,OAAO,MAAM,MAAM,QAAQ,SAAS,CAAC,EAAE,YAAY,MAAM,SAAS;AACxF;AAAA,MACF;AAAA,IACF;AACA,YAAQ,SAAS,KAAK,EAAE,IAAI,MAAM,IAAI,SAAS,MAAM,QAAQ,CAAC;AAAA,EAChE,OAAO;AACL,UAAM,IAAI,MAAM,aAAa,SAAS,wDAAwD;AAAA,EAChG;AAEA,QAAM,mBAAmB,MAAM,aAAa,WAAW,IAAI,OAAO;AAElE,MAAI,CAAC,kBAAkB;AACrB,UAAM,IAAI,MAAM,uBAAuB,EAAE,iBAAiB;AAAA,EAC5D;AAGA,QAAMH,QAAO,iBAAiB,MAAM,WAAW,EAAE,CAAC;AAClD,QAAM,iBAAiBC,MAAKD,OAAM,UAAU;AAE5C,QAAM,cAAc,SAAS,EAAE,IAAI,OAAO;AAC1C,QAAM,aAAa,cAAc,EAAE,SAAS,EAAE,QAAQ,cAAc,QAAQ,OAAO,MAAM,CAAC;AAC5F;AAkBK,IAAM,oBAAoB,CAAC,cAAsB,OAAO,IAAY,YAAqB;AAC9F,QAAM,OAAO,MAAM,aAAa,WAAW,IAAI,OAAO;AACtD,SAAO,CAAC,CAAC;AACX;;;ACvaA,OAAOI,SAAQ;AACf,OAAO,QAAQ,QAAAC,aAAY;AAC3B,OAAOC,aAAY;AAWnB,OAAOC,aAAY;AAoBZ,IAAM,YACX,CAAC,cACD,OAAO,IAAY,YACjB,YAAY,WAAW,IAAI,SAAS,EAAE,MAAM,SAAS,CAAC;AAoBnD,IAAM,aACX,CAAC,cACD,OAAO,YACL,aAAa,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,QAAQ,CAAC,kBAAkB,gBAAgB,kBAAkB,iBAAiB,aAAa;AAAA,EAC3F,GAAG;AACL,CAAC;AAsDE,IAAM,cACX,CAAC,cACD,OACE,QACA,UAA0G;AAAA,EACxG,MAAM;AAAA,EACN,UAAU;AAAA,EACV,wBAAwB;AAAA,EACxB,QAAQ;AACV,MACG;AACH,QAAM,WAAmB,EAAE,GAAG,OAAO;AAErC,MAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG;AAClC,aAAS,WAAW,eAAe,OAAO,QAAQ;AAAA,EACpD;AAEA,SAAO,MAAM,cAAc,WAAW,UAAU,EAAE,GAAG,SAAS,MAAM,SAAS,CAAC;AAChF;AAoBK,IAAM,gBAAgB,CAAC,cAAsB,OAAO,OAAe,gBAAgB,WAAW,EAAE;AAehG,IAAM,WAAW,CAAC,cAAsB,OAAOC,UAAiB;AACrE,QAAMC,IAAG,GAAGC,MAAK,WAAWF,KAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACxD;AAoBO,IAAM,eAAe,CAAC,cAAsB,OAAO,IAAY,SAAkB,iBACtF,eAAe,WAAW,IAAI,SAAS,EAAE,MAAM,UAAU,aAAa,CAAC;AAsBlE,IAAM,kBACX,CAAC,cAAsB,OAAO,IAAY,MAA6C,YACrF,kBAAkB,WAAW,IAAI,MAAM,OAAO;AAqB3C,IAAM,gCACX,CAAC,cAAsB,OAAO,IAAY,8BAA4D,YAAqB;AACzH,QAAM,UAAUD,QAAO,UAAU,IAAI;AAAA,IACnC,GAAG;AAAA,EACL,CAAC;AACD,QAAM,kBAAkB,WAAW,IAAI,EAAE,SAAS,UAAU,0BAA0B,GAAG,OAAO;AAClG;AAmBK,IAAM,kCAAkC,CAAC,cAAsB,OAAO,IAAY,YAAqB;AAC5G,QAAM,eAAgB,MAAM,aAAa,WAAW,IAAI,OAAO,KAAM;AACrE,QAAM,2BAA2B,KAAK,KAAK,KAAK,QAAQ,YAAY,GAAG,yBAAyB;AAEhG,QAAM,aAAaI,QAAO,WAAW,wBAAwB;AAE7D,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,MAAM,YAAY,wBAAwB;AAE1D,SAAO;AACT;AAkBO,IAAM,mBAAmB,CAAC,cAAsB,OAAO,IAAY,YAAqB;AAC7F,QAAM,OAAO,MAAM,aAAa,WAAW,IAAI,OAAO;AACtD,SAAO,CAAC,CAAC;AACX;AAqBO,IAAM,qBACX,CAAC,cAAsB,OAAO,IAAY,SAA0C,YAAqB;AACvG,MAAI,SAAiB,MAAM,UAAU,SAAS,EAAE,IAAI,OAAO;AAC3D,QAAM,aAAa,MAAM,gBAAgB,WAAW,IAAI,OAAO;AAG/D,QAAM,YAAY,KAAK,QAAQ,YAAY,YAAY,EAAE;AAEzD,MAAI,OAAO,aAAa,QAAW;AACjC,WAAO,WAAW,CAAC;AAAA,EACrB;AAEA,QAAM,sBAAsB,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ,MAAM,EAAE,YAAY,QAAQ,OAAO;AAE5G,MAAI,qBAAqB;AACvB;AAAA,EACF;AAGA,SAAO,SAAS,KAAK,OAAO;AAE5B,QAAM,aAAa,SAAS,EAAE,IAAI,SAAS,IAAI;AAC/C,QAAM,YAAY,SAAS,EAAE,QAAQ,EAAE,QAAQ,cAAc,QAAQ,OAAO,MAAM,CAAC;AACrF;;;ACtVF,OAAOC,SAAQ;AACf,SAAS,QAAAC,OAAM,WAAAC,gBAAe;AA0BvB,IAAM,aACX,CAAC,cACD,OAAO,IAAY,YACjB,YAAY,WAAW,IAAI,SAAS,EAAE,MAAM,UAAU,CAAC;AAoBpD,IAAM,cACX,CAAC,cACD,OAAO,YACL,aAAa,WAAW,EAAE,MAAM,YAAY,GAAG,QAAQ,CAAC;AA6DrD,IAAM,eACX,CAAC,cACD,OACE,SACA,UAA0G,EAAE,MAAM,GAAG,MAErH,cAAc,WAAW,EAAE,GAAG,QAAQ,GAAG,EAAE,GAAG,SAAS,MAAM,UAAU,CAAC;AAgBrE,IAAM,YAAY,CAAC,cAAsB,OAAOC,UAAiB;AACtE,QAAMC,IAAG,GAAGC,MAAK,WAAWF,KAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACxD;AAoBO,IAAM,gBAAgB,CAAC,cAAsB,OAAO,IAAY,SAAkB,iBACvF,eAAe,WAAW,IAAI,SAAS,EAAE,MAAM,WAAW,aAAa,CAAC;AAmBnE,IAAM,iBAAiB,CAAC,cAAsB,OAAO,OAAe,gBAAgB,WAAW,EAAE;AAkBjG,IAAM,oBAAoB,CAAC,cAAsB,OAAO,IAAY,YAAqB;AAC9F,QAAM,OAAO,MAAM,aAAa,WAAW,IAAI,OAAO;AACtD,SAAO,CAAC,CAAC;AACX;AAgCO,IAAM,sBACX,CAAC,WAAmB,eACpB,OAAO,IAAY,UAAmF,YAAqB;AACzH,MAAI,UAAmB,MAAM,WAAW,SAAS,EAAE,IAAI,OAAO;AAE9D,QAAM,YAAY;AAAA,IAChB,QAAQ;AAAA,MACN,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,cAAc;AAAA,IAChB;AAAA,IACA,UAAU;AAAA,MACR,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,cAAc;AAAA,IAChB;AAAA,IACA,SAAS;AAAA,MACP,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,cAAc;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,EAAE,YAAY,eAAe,aAAa,IAAI,UAAU,UAAoC;AAElG,QAAM,UAAU,MAAM,WAAW,SAAS,EAAE,SAAS,IAAI,SAAS,OAAO;AACzE,QAAM,cAAc,MAAM,gBAAgB,WAAW,SAAS,IAAI,SAAS,OAAO;AAClF,QAAM,YAAYG,SAAQ,aAAa,YAAY,EAAE;AAErD,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,WAAW,SAAS,EAAE,iBAAiB,SAAS,OAAO,YAAY;AAEjG,MAAI,QAAQ,aAAa,QAAW;AAClC,YAAQ,WAAW,CAAC;AAAA,EACtB;AAEA,QAAM,cAAc,EAAE,IAAI,SAAS,QAAQ,SAAS,GAAI,SAAS,cAAc,EAAE,YAAY,SAAS,WAAW,EAAG;AACpH,UAAQ,SAAS,KAAK,WAAW;AAGjC,QAAM,mBAAmB,MAAM,aAAa,WAAW,SAAS,IAAI,SAAS,OAAO;AAEpF,MAAI,CAAC,kBAAkB;AACrB,UAAM,IAAI,MAAM,uBAAuB,EAAE,iBAAiB;AAAA,EAC5D;AAEA,QAAMH,QAAO,iBAAiB,MAAM,IAAI,UAAU,EAAE,EAAE,CAAC;AACvD,QAAM,iBAAiBE,MAAKF,OAAM,UAAU;AAE5C,QAAM,cAAc,SAAS,EAAE,SAAS,IAAI,SAAS,SAAS,IAAI;AAClE,QAAM,aAAa,cAAc,EAAE,SAAS,EAAE,QAAQ,cAAc,QAAQ,OAAO,MAAM,CAAC;AAC5F;;;ACzRF,OAAOI,SAAQ,QAAAC,aAAY;AAG3B,OAAOC,aAAY;AACnB,OAAOC,SAAQ;AACf,OAAOC,aAAY;AAEnB,OAAO,aAAa;AAeb,IAAM,eACX,CAAC,cACD,OAAO,aAAqD;AAC1D,QAAM,WAAWC,MAAK,KAAK,WAAW,QAAQ;AAC9C,QAAM,wBAAwB,SAAS,SAAS,MAAM,IAAI,WAAW,GAAG,QAAQ;AAChF,QAAM,aAAaC,QAAO,WAAW,qBAAqB;AAC1D,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AACA,SAAO,YAAY,qBAAqB;AAC1C;AAkBK,IAAM,gBACX,CAAC,cACD,OAAO,YAAsD;AAC3D,MAAI,SAAS,MAAM;AACjB,UAAM,UAAU,GAAG,SAAS,IAAI,QAAQ,IAAI;AAC5C,WAAO,aAAa,WAAW,EAAE,MAAM,QAAQ,QAAQ,CAAC;AAAA,EAC1D;AACA,SAAO,aAAa,WAAW,EAAE,MAAM,QAAQ,SAAS,GAAG,SAAS,iBAAiB,CAAC;AACxF;AAoCK,IAAM,iBACX,CAAC,cACD,OAAO,WAAsB,UAA6B,EAAE,MAAM,GAAG,MAAqB;AACxF,QAAM,EAAE,UAAU,GAAG,KAAK,IAAI;AAC9B,QAAM,OAAO,YAAY,QAAQ,UAAU,OAAO,EAAE,OAAO,KAAK,CAAC;AACjE,QAAM,gBAAgB,KAAK,SAAS,MAAM,IAAI,OAAO,GAAG,IAAI;AAC5D,QAAM,WAAWD,MAAK,KAAK,WAAW,QAAQ,QAAQ,IAAI,aAAa;AAEvE,EAAAC,QAAO,UAAUD,MAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5D,QAAM,WAAWE,QAAO,UAAU,UAAU,SAAS,KAAK,GAAG,IAAI;AACjE,EAAAD,QAAO,cAAc,UAAU,QAAQ;AACzC;AAgBK,IAAM,cAAc,CAAC,cAAsB,OAAO,aAAqB;AAC5E,QAAM,gBAAgB,SAAS,SAAS,MAAM,IAAI,WAAW,GAAG,QAAQ;AACxE,QAAME,IAAG,GAAGC,MAAK,WAAW,aAAa,GAAG,EAAE,WAAW,KAAK,CAAC;AACjE;;;AC5HA,OAAOC,SAAQ;AACf,OAAOC,aAAY;AACnB,SAAS,QAAAC,cAAY;AAErB,OAAOC,aAAY;AAkBZ,IAAM,UACX,CAAC,eACD,OAAO,OAA0C;AAC/C,QAAM,QAAQ,MAAM,SAAS,GAAG,UAAU,IAAI,EAAE,WAAW;AAE3D,MAAI,MAAM,UAAU,EAAG,QAAO;AAC9B,QAAM,OAAO,MAAM,CAAC;AAEpB,QAAM,EAAE,MAAM,QAAQ,IAAIC,QAAO,KAAK,IAAI;AAC1C,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI,KAAK;AAAA,IACT,MAAM,KAAK;AAAA,IACX,UAAU,QAAQ,KAAK;AAAA,EACzB;AACF;AAgBK,IAAM,WACX,CAAC,eACD,OAAO,YAAkC;AACvC,QAAM,QAAQ,MAAM,SAAS,GAAG,UAAU,mBAAmB;AAC7D,MAAI,MAAM,WAAW,EAAG,QAAO,CAAC;AAEhC,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,UAAM,EAAE,MAAM,QAAQ,IAAIA,QAAO,KAAK,IAAI;AAC1C,WAAO;AAAA,MACL,GAAG;AAAA,MACH,IAAI,KAAK;AAAA,MACT,MAAM,KAAK;AAAA,MACX,UAAU,QAAQ,KAAK;AAAA,IACzB;AAAA,EACF,CAAC;AACH;AAgCK,IAAM,YACX,CAAC,eACD,OAAO,MAAY,UAAkC,CAAC,MAAM;AAC1D,QAAM,WAAiB,EAAE,GAAG,KAAK;AAGjC,QAAM,cAAc,MAAM,QAAQ,UAAU,EAAE,SAAS,EAAE;AACzD,QAAM,SAAS,gBAAgB;AAE/B,MAAI,UAAU,CAAC,QAAQ,UAAU;AAC/B,UAAM,IAAI,MAAM,mBAAmB,SAAS,EAAE,8BAA8B;AAAA,EAC9E;AAEA,QAAM,EAAE,UAAU,GAAG,YAAY,IAAI;AAErC,QAAM,WAAWA,QAAO,UAAU,UAAU,WAAW;AACvD,EAAAC,QAAO,UAAUC,OAAK,YAAY,EAAE,GAAG,EAAE,WAAW,KAAK,CAAC;AAC1D,EAAAD,QAAO,cAAcC,OAAK,YAAY,IAAI,GAAG,SAAS,EAAE,MAAM,GAAG,QAAQ;AAC3E;AAgBK,IAAM,aAAa,CAAC,eAAuB,OAAO,OAAe;AACtE,QAAMC,IAAG,GAAGD,OAAK,YAAY,GAAG,EAAE,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;AAChE;;;ACvIA,OAAOE,aAAY;AACnB,SAAS,QAAAC,cAAY;AAErB,OAAOC,aAAY;AAkBZ,IAAM,UACX,CAAC,eACD,OAAO,OAA0C;AAC/C,QAAM,QAAQ,MAAM,SAAS,GAAG,UAAU,IAAI,EAAE,WAAW;AAE3D,MAAI,MAAM,UAAU,EAAG,QAAO;AAC9B,QAAM,OAAO,MAAM,CAAC;AAEpB,QAAM,EAAE,MAAM,QAAQ,IAAIC,QAAO,KAAK,IAAI;AAC1C,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI,KAAK;AAAA,IACT,MAAM,KAAK;AAAA,IACX,WAAW,KAAK;AAAA,IAChB,UAAU,QAAQ,KAAK;AAAA,EACzB;AACF;AAgBK,IAAM,WACX,CAAC,eACD,OAAO,YAAkC;AACvC,QAAM,QAAQ,MAAM,SAAS,GAAG,UAAU,mBAAmB;AAC7D,MAAI,MAAM,WAAW,EAAG,QAAO,CAAC;AAEhC,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,UAAM,EAAE,MAAM,QAAQ,IAAIA,QAAO,KAAK,IAAI;AAC1C,WAAO;AAAA,MACL,GAAG;AAAA,MACH,IAAI,KAAK;AAAA,MACT,MAAM,KAAK;AAAA,MACX,WAAW,KAAK;AAAA,MAChB,UAAU,QAAQ,KAAK;AAAA,IACzB;AAAA,EACF,CAAC;AACH;AAgCK,IAAM,YACX,CAAC,eACD,OAAO,MAAY,UAAkC,CAAC,MAAM;AAC1D,QAAM,WAAiB,EAAE,GAAG,KAAK;AAGjC,QAAM,cAAc,MAAM,QAAQ,UAAU,EAAE,SAAS,EAAE;AACzD,QAAM,SAAS,gBAAgB;AAE/B,MAAI,UAAU,CAAC,QAAQ,UAAU;AAC/B,UAAM,IAAI,MAAM,mBAAmB,SAAS,EAAE,8BAA8B;AAAA,EAC9E;AAEA,QAAM,EAAE,UAAU,GAAG,YAAY,IAAI;AAErC,QAAM,WAAWA,QAAO,UAAU,UAAU,WAAW;AACvD,EAAAC,QAAO,UAAUC,OAAK,YAAY,EAAE,GAAG,EAAE,WAAW,KAAK,CAAC;AAC1D,EAAAD,QAAO,cAAcC,OAAK,YAAY,IAAI,GAAG,SAAS,EAAE,MAAM,GAAG,QAAQ;AAC3E;AAgBK,IAAM,aAAa,CAAC,eAAuB,OAAO,OAAe;AACtE,EAAAD,QAAO,OAAOC,OAAK,YAAY,GAAG,EAAE,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;AAClE;;;AXhDA,IAAO,gBAAQ,CAACC,UAAiB;AAC/B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOL,UAAU,SAASC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAM7B,WAAW,UAAUC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQ/B,YAAY,WAAWC,OAAKD,OAAM,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAS3C,qBAAqB,oBAAoBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOnD,SAAS,QAAQC,OAAKD,OAAM,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOrC,aAAa,YAAYC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAKnC,cAAc,aAAaC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQrC,gBAAgB,eAAeC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQzC,kBAAkB,iBAAiBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO7C,iBAAiB,gBAAgBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAc3C,YAAY,WAAWC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMjC,aAAa,YAAYC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQnC,cAAc,aAAaC,OAAKD,OAAM,UAAU,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUjD,uBAAuB,sBAAsBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQvD,WAAW,UAAUC,OAAKD,OAAM,UAAU,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO3C,eAAe,cAAcC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAKvC,gBAAgB,eAAeC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQzC,kBAAkB,iBAAiBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQ7C,oBAAoB,mBAAmBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQjD,mBAAmB,kBAAkBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAc/C,UAAU,SAASC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAM7B,YAAY,WAAWC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQjC,YAAY,WAAWC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAS5C,qBAAqB,oBAAoBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOnD,SAAS,QAAQC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOtC,aAAa,YAAYC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAKnC,cAAc,aAAaC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQrC,gBAAgB,eAAeC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQzC,kBAAkB,iBAAiBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO7C,iBAAiB,gBAAgBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAc3C,YAAY,WAAWC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMjC,aAAa,YAAYC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQnC,cAAc,aAAaC,OAAKD,OAAM,UAAU,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQjD,WAAW,UAAUC,OAAKD,OAAM,UAAU,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO3C,eAAe,cAAcC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAKvC,gBAAgB,eAAeC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQzC,mBAAmB,kBAAkBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAkB/C,mBAAmB,oBAAoBC,OAAKD,KAAI,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAiB3D,qBAAqB,oBAAoBC,OAAKD,KAAI,GAAG,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAkB/D,mBAAmB,oBAAoBC,OAAKD,KAAI,GAAG,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAe5D,cAAc,aAAaC,OAAKD,OAAM,UAAU,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQjD,uBAAuB,sBAAsBC,OAAKD,OAAM,UAAU,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUnE,sBAAsB,qBAAqBC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOhE,YAAY,WAAWC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMjC,aAAa,YAAYC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAKnC,gBAAgB,eAAeC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOzC,WAAW,UAAUC,OAAKD,OAAM,UAAU,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO3C,eAAe,cAAcC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQvC,kBAAkB,iBAAiBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQ7C,iCAAiC,gCAAgCC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQ3E,mBAAmB,kBAAkBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAqB/C,mBAAmB,oBAAoBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAoBjD,qBAAqB,oBAAoBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAoBnD,mBAAmB,oBAAoBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAejD,aAAa,YAAYC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQ9C,WAAW,UAAUC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAM1C,YAAY,WAAWC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAKjC,eAAe,cAAcC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOlD,UAAU,SAASC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOxC,cAAc,aAAaC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQhD,iBAAiB,gBAAgBC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQtD,+BAA+B,8BAA8BC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQlF,iCAAiC,gCAAgCC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQtF,kBAAkB,iBAAiBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAS7C,oBAAoB,mBAAmBC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAc5D,WAAW,UAAUC,OAAKD,OAAM,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMxC,SAAS,QAAQC,OAAKD,OAAM,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAKpC,UAAU,SAASC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO7B,YAAY,WAAWC,OAAKD,OAAM,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAc1C,WAAW,UAAUC,OAAKD,OAAM,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMxC,SAAS,QAAQC,OAAKD,OAAM,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAKpC,UAAU,SAASC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO7B,YAAY,WAAWC,OAAKD,OAAM,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAa1C,cAAc,aAAaC,OAAKD,OAAM,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAM7C,eAAe,cAAcC,OAAKD,OAAM,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO/C,gBAAgB,eAAeC,OAAKD,OAAM,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOjD,aAAa,YAAYC,OAAKD,OAAM,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO3C,aAAa,YAAYC,OAAKD,KAAI,CAAC;AAAA,EACrC;AACF;;;AD9uBA,IAAM,eAAe;AAErB,IAAM,yBAAyB,OAAO,eAAuB;AAE3D,MAAI;AACF,UAAM,cAAcE,KAAG,aAAaC,OAAK,YAAY,cAAc,GAAG,MAAM;AAC5E,UAAM,oBAAoB,KAAK,MAAM,WAAW;AAChD,WAAO,kBAAkB,cAAc,EAAE,oBAAoB;AAAA,EAC/D,SAAS,OAAO;AACd,WAAO;AAAA,EACT;AACF;AAEA,IAAM,kBAAkB,OACtB,YACA,WACA,EAAE,eAAe,MAAM,IAAgC,CAAC,MACrD;AACH,SAAO,MAAM,QAAQ;AAAA,IACnB,UAAU,IAAI,OAAO,aAAa;AAGhC,YAAM,eAAe,MAAM,gBAAgB,YAAY,SAAS,IAAI,SAAS,OAAO;AACpF,UAAI,SAAS;AAEb,UAAI,SAAS,cAAc,cAAc,UAAU;AACjD,cAAM,eAAeC,MAAK,KAAKA,MAAK,QAAQ,cAAc,QAAQ,GAAG,SAAS,UAAU;AACxF,YAAIF,KAAG,WAAW,YAAY,GAAG;AAC/B,mBAASA,KAAG,aAAa,cAAc,MAAM;AAAA,QAC/C;AAAA,MACF;AAIA,YAAM,eAAe,SAAS,EAAE,WAAW,cAAc,WAAW,OAAO,IAAI,EAAE,WAAW,cAAc,UAAU;AAEpH,aAAO;AAAA,QACL,GAAG;AAAA,QACH,eAAe;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,IAAM,mBAAmB,CACvB,YACA,YAGG;AACH,SAAO,WAAW,IAAI,CAAC,UAAU;AAAA,IAC/B,GAAG;AAAA,IACH,UAAU,SAAS,kBAAkB,KAAK,WAAW;AAAA,EACvD,EAAE;AACJ;AAOO,IAAM,cACX,CAAC,cACD,OAAO,YAAyE;AAC9E,QAAM,EAAE,YAAAG,aAAY,aAAAC,cAAa,WAAAC,YAAW,YAAAC,aAAY,aAAAC,cAAa,aAAAC,cAAa,UAAAC,WAAU,UAAAC,UAAS,IAAI,cAAM,SAAS;AAExH,QAAM,EAAE,kBAAkB,KAAK,IAAI,WAAW,CAAC;AAE/C,QAAM,UAAU,MAAMP,YAAW;AACjC,QAAM,WAAW,MAAMC,aAAY;AAEnC,QAAM,SAAS,MAAMC,WAAU;AAC/B,QAAM,WAAW,MAAME,aAAY;AACnC,QAAM,UAAU,MAAMD,YAAW;AACjC,QAAM,QAAQ,MAAMG,UAAS;AAC7B,QAAM,QAAQ,MAAMC,UAAS;AAC7B,QAAM,WAAW,MAAMF,aAAY;AAEnC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,MAAM,QAAQ,IAAI;AAAA,IACpB,gBAAgB,WAAW,OAAO;AAAA,IAClC,gBAAgB,WAAW,QAAQ;AAAA,IACnC,gBAAgB,WAAW,MAAM;AAAA,IACjC,gBAAgB,WAAW,OAAO;AAAA,IAClC,gBAAgB,WAAW,QAAQ;AAAA,IACnC,gBAAgB,WAAW,KAAK;AAAA,IAChC,gBAAgB,WAAW,KAAK;AAAA,IAChC,gBAAgB,WAAW,QAAQ;AAAA,EACrC,CAAC;AAED,SAAO;AAAA,IACL,SAAS;AAAA,IACT,gBAAgB,MAAM,uBAAuB,SAAS;AAAA,IACtD,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,WAAW;AAAA,MACT,SAAS,iBAAiB,iBAAiB,EAAE,gBAAgB,CAAC;AAAA,MAC9D,UAAU,iBAAiB,kBAAkB,EAAE,gBAAgB,CAAC;AAAA,MAChE,UAAU;AAAA,QACR,QAAQ,iBAAiB,gBAAgB,EAAE,gBAAgB,CAAC;AAAA,QAC5D,SAAS,iBAAiB,iBAAiB,EAAE,gBAAgB,CAAC;AAAA,QAC9D,UAAU,iBAAiB,kBAAkB,EAAE,gBAAgB,CAAC;AAAA,MAClE;AAAA,MACA,OAAO,iBAAiB,eAAe,EAAE,gBAAgB,CAAC;AAAA,MAC1D,OAAO,iBAAiB,eAAe,EAAE,gBAAgB,CAAC;AAAA,MAC1D,UAAU,iBAAiB,kBAAkB,EAAE,gBAAgB,CAAC;AAAA,IAClE;AAAA,EACF;AACF;","names":["fs","path","join","join","fs","join","path","match","dirname","join","matter","fsSync","satisfies","dirname","file","join","path","join","path","fs","fs","join","join","path","fs","fs","join","join","path","fs","fs","join","dirname","path","join","fs","dirname","fs","join","fsSync","matter","path","fs","join","fsSync","fs","join","extname","path","fs","join","extname","path","join","fsSync","fs","matter","path","fsSync","matter","fs","join","fs","fsSync","join","matter","matter","fsSync","join","fs","fsSync","join","matter","matter","fsSync","join","path","join","fs","join","path","getDomains","getServices","getEvents","getQueries","getCommands","getChannels","getTeams","getUsers"]}
|