@eventcatalog/sdk 2.17.1 → 2.17.2
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/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/dsl/utils.ts","../src/dsl/message.ts","../src/dsl/service.ts","../src/dsl/channel.ts","../src/dsl/owner.ts","../src/dsl/domain.ts","../src/dsl/container.ts","../src/dsl/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/messages.ts","../src/custom-docs.ts","../src/teams.ts","../src/users.ts","../src/eventcatalog.ts","../src/snapshots.ts","../src/snapshot-diff.ts","../src/changelogs.ts","../src/entities.ts","../src/containers.ts","../src/data-stores.ts","../src/data-products.ts","../src/diagrams.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { toDSL } from './dsl';\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 addEntityToService,\n serviceHasVersion,\n getSpecificationFilesForService,\n writeVersionedService,\n getServices,\n getServiceByPath,\n isService,\n toService,\n addDataStoreToService,\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 addSubDomainToDomain,\n addEntityToDomain,\n addDataProductToDomain,\n getUbiquitousLanguageFromDomain,\n addMessageToDomain,\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 {\n getConsumersOfSchema,\n getMessageBySchemaPath,\n getProducersAndConsumersForMessage,\n getProducersOfSchema,\n getSchemaForMessage,\n} from './messages';\n\nimport { getResourcePath, getResourceFolderName } from './internal/resources';\n\nimport { writeCustomDoc, getCustomDoc, getCustomDocs, rmCustomDoc } from './custom-docs';\n\nimport { writeTeam, getTeam, getTeams, rmTeamById, getOwnersForResource } from './teams';\n\nimport { writeUser, getUser, getUsers, rmUserById } from './users';\nimport { dumpCatalog, getEventCatalogConfigurationFile } from './eventcatalog';\nimport { createSnapshot, diffSnapshots, listSnapshots } from './snapshots';\nimport { writeChangelog, appendChangelog, getChangelog, rmChangelog } from './changelogs';\nimport { getEntity, getEntities, writeEntity, rmEntity, rmEntityById, versionEntity, entityHasVersion } from './entities';\n\nimport {\n getDataStore,\n getDataStores,\n writeDataStore,\n versionDataStore,\n rmDataStore,\n rmDataStoreById,\n dataStoreHasVersion,\n addFileToDataStore,\n writeDataStoreToService,\n} from './data-stores';\n\nimport {\n getDataProduct,\n getDataProducts,\n writeDataProduct,\n writeDataProductToDomain,\n versionDataProduct,\n rmDataProduct,\n rmDataProductById,\n dataProductHasVersion,\n addFileToDataProduct,\n} from './data-products';\n\nimport {\n getDiagram,\n getDiagrams,\n writeDiagram,\n rmDiagram,\n rmDiagramById,\n versionDiagram,\n diagramHasVersion,\n addFileToDiagram,\n} from './diagrams';\n\n// Export the types\nexport type * from './types';\nexport type * from './snapshot-types';\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 a service from EventCatalog by it's path.\n * @param path - The path to the service to retrieve\n * @returns Service|Undefined\n */\n getServiceByPath: getServiceByPath(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 /**\n * Add a data store to a service by it's id.\n *\n * Optionally specify a version to add the data store to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addDataStoreToService } = utils('/path/to/eventcatalog');\n *\n * // adds a new data store (orders-db) that the InventoryService will write to\n * await addDataStoreToService('InventoryService', 'writesTo', { id: 'orders-db', version: '2.0.0' });\n *\n * ```\n */\n addDataStoreToService: addDataStoreToService(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 * Add an entity to a service by its id.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addEntityToService } = utils('/path/to/eventcatalog');\n *\n * // adds a new entity (User) to the InventoryService\n * await addEntityToService('InventoryService', { id: 'User', version: '1.0.0' });\n *\n * // adds a new entity (Product) to a specific version of the InventoryService\n * await addEntityToService('InventoryService', { id: 'Product', version: '1.0.0' }, '2.0.0');\n *\n * ```\n */\n addEntityToService: addEntityToService(join(path)),\n\n /**\n * Check to see if a service exists by it's path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { isService } = utils('/path/to/eventcatalog');\n *\n * // returns true if the path is a service\n * await isService('/services/InventoryService/index.mdx');\n * ```\n *\n * @param path - The path to the service to check\n * @returns boolean\n */\n isService: isService(join(path)),\n\n /**\n * Converts a file to a service.\n * @param file - The file to convert to a service.\n * @returns The service.\n */\n toService: toService(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 * Adds a given subdomain to a domain\n * @param id - The id of the domain\n * @param subDomain - The id and version of the subdomain to add\n * @param version - (Optional) The version of the domain to add the subdomain to\n * @returns\n */\n addSubDomainToDomain: addSubDomainToDomain(join(path, 'domains')),\n\n /**\n * Adds an entity to a domain\n * @param id - The id of the domain\n * @param entity - The id and version of the entity to add\n * @param version - (Optional) The version of the domain to add the entity to\n * @returns\n */\n addEntityToDomain: addEntityToDomain(join(path, 'domains')),\n\n /**\n * Add an event to a domain by its id.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addEventToDomain } = utils('/path/to/eventcatalog');\n *\n * // adds a new event (OrderCreated) that the Orders domain will send\n * await addEventToDomain('Orders', 'sends', { id: 'OrderCreated', version: '2.0.0' });\n *\n * // adds a new event (PaymentProcessed) that the Orders domain will receive\n * await addEventToDomain('Orders', 'receives', { id: 'PaymentProcessed', version: '2.0.0' });\n *\n * ```\n */\n addEventToDomain: addMessageToDomain(join(path, 'domains')),\n\n /**\n * Add a command to a domain by its id.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addCommandToDomain } = utils('/path/to/eventcatalog');\n *\n * // adds a new command (ProcessOrder) that the Orders domain will send\n * await addCommandToDomain('Orders', 'sends', { id: 'ProcessOrder', version: '2.0.0' });\n *\n * // adds a new command (CancelOrder) that the Orders domain will receive\n * await addCommandToDomain('Orders', 'receives', { id: 'CancelOrder', version: '2.0.0' });\n *\n * ```\n */\n addCommandToDomain: addMessageToDomain(join(path, 'domains')),\n\n /**\n * Add a query to a domain by its id.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addQueryToDomain } = utils('/path/to/eventcatalog');\n *\n * // adds a new query (GetOrderStatus) that the Orders domain will send\n * await addQueryToDomain('Orders', 'sends', { id: 'GetOrderStatus', version: '2.0.0' });\n *\n * // adds a new query (GetInventory) that the Orders domain will receive\n * await addQueryToDomain('Orders', 'receives', { id: 'GetInventory', version: '2.0.0' });\n *\n * ```\n */\n addQueryToDomain: addMessageToDomain(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, 'teams')),\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 * Returns the event catalog configuration file.\n * The event catalog configuration file is the file that contains the configuration for the event catalog.\n *\n * @param directory - The directory of the catalog.\n * @returns A JSON object with the configuration for the event catalog.\n */\n getEventCatalogConfigurationFile: getEventCatalogConfigurationFile(join(path)),\n /**\n * ================================\n * Changelogs\n * ================================\n */\n\n /**\n * Writes a changelog entry to a resource in EventCatalog\n *\n * @param id - The id of the resource to write the changelog to\n * @param changelog - The changelog entry to write\n * @param options - Optional options (version, format)\n *\n */\n writeChangelog: writeChangelog(join(path)),\n /**\n * Appends a changelog entry to an existing changelog for a resource.\n * If no changelog exists, one is created.\n *\n * @param id - The id of the resource to append the changelog to\n * @param changelog - The changelog entry to append\n * @param options - Optional options (version, format)\n *\n */\n appendChangelog: appendChangelog(join(path)),\n /**\n * Returns the changelog for a resource in EventCatalog\n *\n * @param id - The id of the resource to get the changelog for\n * @param options - Optional options (version)\n * @returns Changelog|Undefined\n */\n getChangelog: getChangelog(join(path)),\n /**\n * Removes the changelog for a resource in EventCatalog\n *\n * @param id - The id of the resource to remove the changelog from\n * @param options - Optional options (version)\n *\n */\n rmChangelog: rmChangelog(join(path)),\n\n /**\n * ================================\n * Resources Utils\n * ================================\n */\n\n /**\n * Returns the path to a given resource by id and version\n */\n getResourcePath: getResourcePath,\n\n /**\n * Returns the folder name of a given resource\n */\n getResourceFolderName: getResourceFolderName,\n\n /**\n * ================================\n * General Message Utils\n * ================================\n */\n\n /**\n * Returns a message from EventCatalog by a given schema path.\n *\n * @param path - The path to the message to retrieve\n * @returns Message|Undefined\n */\n getMessageBySchemaPath: getMessageBySchemaPath(join(path)),\n\n /**\n * Returns the producers and consumers (services) for a given message\n * @param id - The id of the message to get the producers and consumers for\n * @param version - Optional version of the message\n * @returns { producers: Service[], consumers: Service[] }\n */\n getProducersAndConsumersForMessage: getProducersAndConsumersForMessage(join(path)),\n\n /**\n * Returns the consumers of a given schema path\n * @param path - The path to the schema to get the consumers for\n * @returns Service[]\n */\n getConsumersOfSchema: getConsumersOfSchema(join(path)),\n\n /**\n * Returns the producers of a given schema path\n * @param path - The path to the schema to get the producers for\n * @returns Service[]\n */\n getProducersOfSchema: getProducersOfSchema(join(path)),\n\n /**\n * Returns the schema for a given message (event, command or query) by its id and version.\n * If no version is given, the latest version is used.\n * @param id - The id of the message to get the schema for\n * @param version - Optional version of the message\n * @returns { schema: string, fileName: string } | undefined\n */\n getSchemaForMessage: getSchemaForMessage(join(path)),\n\n /**\n * Returns the owners for a given resource (e.g domain, service, event, command, query, etc.)\n * @param id - The id of the resource to get the owners for\n * @param version - Optional version of the resource\n * @returns { owners: User[] }\n */\n getOwnersForResource: getOwnersForResource(join(path)),\n\n /**\n * ================================\n * Entities\n * ================================\n */\n\n /**\n * Returns an entity from EventCatalog\n * @param id - The id of the entity to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Entity|Undefined\n */\n getEntity: getEntity(join(path)),\n /**\n * Returns all entities from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Entity[]|Undefined\n */\n getEntities: getEntities(join(path)),\n /**\n * Adds an entity to EventCatalog\n *\n * @param entity - The entity to write\n * @param options - Optional options to write the entity\n *\n */\n writeEntity: writeEntity(join(path, 'entities')),\n /**\n * Remove an entity from EventCatalog (modeled on the standard POSIX rm utility)\n *\n * @param path - The path to your entity, e.g. `/User`\n *\n */\n rmEntity: rmEntity(join(path, 'entities')),\n /**\n * Remove an entity by an entity id\n *\n * @param id - The id of the entity you want to remove\n *\n */\n rmEntityById: rmEntityById(join(path)),\n /**\n * Moves a given entity id to the version directory\n * @param id - The id of the entity to version\n */\n versionEntity: versionEntity(join(path)),\n /**\n * Check to see if an entity version exists\n * @param id - The id of the entity\n * @param version - The version of the entity (supports semver)\n * @returns\n */\n entityHasVersion: entityHasVersion(join(path)),\n\n /**\n * ================================\n * Data Stores\n * ================================\n */\n /**\n * Adds a data store to EventCatalog\n * @param dataStore - The data store to write\n * @param options - Optional options to write the data store\n *\n */\n writeDataStore: writeDataStore(join(path, 'containers')),\n\n /**\n * Returns a data store from EventCatalog\n * @param id - The id of the data store to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Container|Undefined\n */\n getDataStore: getDataStore(join(path)),\n\n /**\n * Returns all data stores from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Container[]|Undefined\n */\n getDataStores: getDataStores(join(path)),\n\n /**\n * Version a data store by its id\n * @param id - The id of the data store to version\n */\n versionDataStore: versionDataStore(join(path, 'containers')),\n\n /**\n * Remove a data store by its path\n * @param path - The path to the data store to remove\n */\n rmDataStore: rmDataStore(join(path, 'containers')),\n\n /**\n * Remove a data store by its id\n * @param id - The id of the data store to remove\n */\n rmDataStoreById: rmDataStoreById(join(path)),\n\n /**\n * Check to see if a data store version exists\n * @param id - The id of the data store\n * @param version - The version of the data store (supports semver)\n * @returns\n */\n dataStoreHasVersion: dataStoreHasVersion(join(path)),\n\n /**\n * Adds a file to a data store by its id\n * @param id - The id of the data store 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 data store to add the file to\n * @returns\n */\n addFileToDataStore: addFileToDataStore(join(path)),\n\n /**\n * Writes a data store to a service by its id\n * @param dataStore - The data store to write\n * @param service - The service to write the data store to\n * @returns\n */\n writeDataStoreToService: writeDataStoreToService(join(path)),\n\n /**\n * ================================\n * Data Products\n * ================================\n */\n /**\n * Adds a data product to EventCatalog\n * @param dataProduct - The data product to write\n * @param options - Optional options to write the data product\n *\n */\n writeDataProduct: writeDataProduct(join(path, 'data-products')),\n\n /**\n * Writes a data product to a domain in EventCatalog\n * @param dataProduct - The data product to write\n * @param domain - The domain to write the data product to\n * @param options - Optional options to write the data product\n *\n */\n writeDataProductToDomain: writeDataProductToDomain(join(path, 'domains')),\n\n /**\n * Returns a data product from EventCatalog\n * @param id - The id of the data product to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns DataProduct|Undefined\n */\n getDataProduct: getDataProduct(join(path)),\n\n /**\n * Returns all data products from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns DataProduct[]|Undefined\n */\n getDataProducts: getDataProducts(join(path)),\n\n /**\n * Version a data product by its id\n * @param id - The id of the data product to version\n */\n versionDataProduct: versionDataProduct(join(path)),\n\n /**\n * Remove a data product by its path\n * @param path - The path to the data product to remove\n */\n rmDataProduct: rmDataProduct(join(path, 'data-products')),\n\n /**\n * Remove a data product by its id\n * @param id - The id of the data product to remove\n * @param version - Optional version of the data product to remove\n */\n rmDataProductById: rmDataProductById(join(path)),\n\n /**\n * Check to see if a data product version exists\n * @param id - The id of the data product\n * @param version - The version of the data product (supports semver)\n * @returns\n */\n dataProductHasVersion: dataProductHasVersion(join(path)),\n\n /**\n * Adds a file to a data product by its id\n * @param id - The id of the data product 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 data product to add the file to\n * @returns\n */\n addFileToDataProduct: addFileToDataProduct(join(path)),\n\n /**\n * Adds a data product to a domain\n * @param id - The id of the domain\n * @param dataProduct - The id and version of the data product to add\n * @param version - (Optional) The version of the domain to add the data product to\n * @returns\n */\n addDataProductToDomain: addDataProductToDomain(join(path, 'domains')),\n\n /**\n * ================================\n * Diagrams\n * ================================\n */\n\n /**\n * Returns a diagram from EventCatalog\n * @param id - The id of the diagram to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Diagram|Undefined\n */\n getDiagram: getDiagram(join(path)),\n /**\n * Returns all diagrams from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Diagram[]|Undefined\n */\n getDiagrams: getDiagrams(join(path)),\n /**\n * Adds a diagram to EventCatalog\n *\n * @param diagram - The diagram to write\n * @param options - Optional options to write the diagram\n *\n */\n writeDiagram: writeDiagram(join(path, 'diagrams')),\n /**\n * Remove a diagram from EventCatalog (modeled on the standard POSIX rm utility)\n *\n * @param path - The path to your diagram, e.g. `/ArchitectureDiagram`\n *\n */\n rmDiagram: rmDiagram(join(path, 'diagrams')),\n /**\n * Remove a diagram by a diagram id\n *\n * @param id - The id of the diagram you want to remove\n *\n */\n rmDiagramById: rmDiagramById(join(path)),\n /**\n * Moves a given diagram id to the version directory\n * @param id - The id of the diagram to version\n */\n versionDiagram: versionDiagram(join(path)),\n /**\n * Check to see if a diagram version exists\n * @param id - The id of the diagram\n * @param version - The version of the diagram (supports semver)\n * @returns\n */\n diagramHasVersion: diagramHasVersion(join(path)),\n /**\n * Adds a file to the given diagram\n * @param id - The id of the diagram 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 diagram to add the file to\n * @returns\n */\n addFileToDiagram: addFileToDiagram(join(path)),\n\n /**\n * ================================\n * DSL\n * ================================\n */\n\n /**\n * Converts catalog resources to EventCatalog DSL (.ec) format strings.\n *\n * @param resource - A resource or array of resources to convert\n * @param options - Options including type ('event'|'command'|'query'|'service'|'domain') and optional hydrate flag\n * @returns A DSL string representation\n *\n * @example\n * ```ts\n * const dsl = await sdk.toDSL(event, { type: 'event' });\n * const dsl = await sdk.toDSL(services, { type: 'service', hydrate: true });\n * ```\n */\n createSnapshot: createSnapshot(join(path)),\n diffSnapshots: diffSnapshots(join(path)),\n listSnapshots: listSnapshots(join(path)),\n\n toDSL: toDSL(join(path), {\n getEvent: getEvent(join(path)),\n getCommand: getCommand(join(path)),\n getQuery: getQuery(join(path)),\n getService: getService(join(path)),\n getServices: getServices(join(path)),\n getDomain: getDomain(join(path, 'domains')),\n getChannel: getChannel(join(path)),\n getChannels: getChannels(join(path)),\n getContainer: getDataStore(join(path)),\n getTeam: getTeam(join(path, 'teams')),\n getUser: getUser(join(path, 'users')),\n }),\n };\n};\n","import { globSync } from 'glob';\nimport { satisfies, validRange } from 'semver';\n\n/**\n * Checks whether a pointer version (which may be a semver range like ^1.0.0, ~1.2.0)\n * matches a concrete message version.\n */\nexport function msgVersionMatches(pointerVersion: string | undefined, messageVersion: string | undefined): boolean {\n if (!pointerVersion) return true;\n if (!messageVersion) return false;\n if (pointerVersion === messageVersion) return true;\n try {\n // Check if pointerVersion is a range that messageVersion satisfies\n if (validRange(pointerVersion)) {\n if (satisfies(messageVersion, pointerVersion)) return true;\n }\n // Check the reverse: messageVersion may be a range that pointerVersion satisfies\n if (validRange(messageVersion)) {\n if (satisfies(pointerVersion, messageVersion)) return true;\n }\n } catch {\n // Invalid semver, fall through\n }\n return false;\n}\n\ninterface BaseResource {\n id: string;\n name: string;\n version: string;\n summary?: string;\n owners?: string[];\n badges?: { content: string; backgroundColor: string; textColor: string }[];\n deprecated?: boolean | { date?: string; message?: string };\n draft?: boolean | { title?: string; message?: string };\n}\n\nexport type MessageTypeIndex = Map<string, MessageType>;\n\ninterface ChannelPointer {\n id: string;\n version?: string;\n parameters?: Record<string, string>;\n}\n\ninterface SendsPointer {\n id: string;\n version?: string;\n to?: ChannelPointer[];\n}\n\ninterface ReceivesPointer {\n id: string;\n version?: string;\n from?: ChannelPointer[];\n}\n\nexport type MessageType = 'event' | 'command' | 'query';\n\nexport function serializeBaseFields(resource: BaseResource, indent: string = ' '): string {\n const lines: string[] = [];\n\n if (resource.version) {\n lines.push(`${indent}version ${resource.version}`);\n }\n\n if (resource.name) {\n lines.push(`${indent}name \"${resource.name}\"`);\n }\n\n if (resource.summary) {\n lines.push(`${indent}summary \"${resource.summary.trim()}\"`);\n }\n\n if (resource.owners && resource.owners.length > 0) {\n for (const owner of resource.owners) {\n lines.push(`${indent}owner ${owner}`);\n }\n }\n\n if (resource.deprecated === true) {\n lines.push(`${indent}deprecated true`);\n }\n\n if (resource.draft === true) {\n lines.push(`${indent}draft true`);\n }\n\n return lines.join('\\n');\n}\n\nexport function buildMessageTypeIndex(catalogDir: string): MessageTypeIndex {\n const index: MessageTypeIndex = new Map();\n const types = ['events', 'commands', 'queries'] as const;\n const typeMap = { events: 'event', commands: 'command', queries: 'query' } as const;\n\n for (const type of types) {\n const matches = globSync(`**/${type}/*/index.{md,mdx}`, { cwd: catalogDir });\n for (const match of matches) {\n const parts = match.replace(/\\\\/g, '/').split('/');\n const typeIdx = parts.lastIndexOf(type);\n if (typeIdx !== -1 && typeIdx + 1 < parts.length) {\n const id = parts[typeIdx + 1];\n if (!index.has(id)) index.set(id, typeMap[type]);\n }\n }\n }\n\n return index;\n}\n\nexport function resolveMessageType(catalogDirOrIndex: string | MessageTypeIndex, id: string): MessageType | undefined {\n if (typeof catalogDirOrIndex !== 'string') {\n return catalogDirOrIndex.get(id);\n }\n // Fallback for backwards compatibility\n if (globSync(`**/events/${id}/index.{md,mdx}`, { cwd: catalogDirOrIndex }).length > 0) return 'event';\n if (globSync(`**/commands/${id}/index.{md,mdx}`, { cwd: catalogDirOrIndex }).length > 0) return 'command';\n if (globSync(`**/queries/${id}/index.{md,mdx}`, { cwd: catalogDirOrIndex }).length > 0) return 'query';\n return undefined;\n}\n\nfunction serializeChannelRef(channel: ChannelPointer): string {\n let ref = channel.id;\n if (channel.version) ref += `@${channel.version}`;\n return ref;\n}\n\nexport function serializeMessagePointers(\n items: (SendsPointer | ReceivesPointer)[],\n direction: 'sends' | 'receives',\n catalogDirOrIndex: string | MessageTypeIndex,\n indent: string = ' '\n): string {\n const lines: string[] = [];\n\n for (const item of items) {\n const msgType = resolveMessageType(catalogDirOrIndex, item.id);\n if (!msgType) continue;\n\n let ref = `${item.id}`;\n if (item.version) ref += `@${item.version}`;\n\n const channels = direction === 'sends' ? (item as SendsPointer).to : (item as ReceivesPointer).from;\n\n const channelKeyword = direction === 'sends' ? 'to' : 'from';\n\n if (channels && channels.length === 1) {\n lines.push(`${indent}${direction} ${msgType} ${ref} ${channelKeyword} ${serializeChannelRef(channels[0])}`);\n } else if (channels && channels.length > 1) {\n const channelRefs = channels.map(serializeChannelRef).join(', ');\n lines.push(`${indent}${direction} ${msgType} ${ref} ${channelKeyword} ${channelRefs}`);\n } else {\n lines.push(`${indent}${direction} ${msgType} ${ref}`);\n }\n }\n\n return lines.join('\\n');\n}\n","import type { Event, Command, Query } from '../types';\nimport { serializeBaseFields, type MessageType } from './utils';\n\nexport function messageToDSL(resource: Event | Command | Query, type: MessageType): string {\n const body = serializeBaseFields(resource);\n\n if (!body) {\n return `${type} ${resource.id}`;\n }\n\n return `${type} ${resource.id} {\\n${body}\\n}`;\n}\n","import type { Service, Event, Command, Query } from '../types';\nimport { serializeBaseFields, serializeMessagePointers, resolveMessageType, buildMessageTypeIndex } from './utils';\nimport type { MessageTypeIndex } from './utils';\nimport { messageToDSL } from './message';\nimport { valid as semverValid } from 'semver';\n\ninterface ServiceToDSLOptions {\n catalogDir: string;\n hydrate?: boolean;\n _seen?: Set<string>;\n _msgIndex?: MessageTypeIndex;\n}\n\nexport async function serviceToDSL(\n resource: Service,\n options: ServiceToDSLOptions,\n getMessageFn?: (id: string, version?: string) => Promise<Event | Command | Query | undefined>\n): Promise<string> {\n const { catalogDir, hydrate = false, _seen = new Set<string>() } = options;\n const msgIndex = options._msgIndex || buildMessageTypeIndex(catalogDir);\n const parts: string[] = [];\n const resolvedVersions = new Map<string, string>();\n\n if (hydrate && getMessageFn) {\n const allMessages = [...(resource.sends || []), ...(resource.receives || [])];\n for (const msg of allMessages) {\n const key = `${msg.id}@${msg.version || 'latest'}`;\n if (_seen.has(key)) continue;\n _seen.add(key);\n\n const msgType = resolveMessageType(msgIndex, msg.id);\n if (!msgType) continue;\n\n const msgResource = await getMessageFn(msg.id, msg.version);\n if (msgResource) {\n parts.push(messageToDSL(msgResource, msgType));\n // Track resolved version so semver ranges can be replaced with concrete versions\n if (msg.version && !semverValid(msg.version) && msgResource.version) {\n resolvedVersions.set(`${msg.id}@${msg.version}`, msgResource.version);\n }\n }\n }\n }\n\n // Replace semver range versions with concrete resolved versions\n const resolvePointers = <T extends { id: string; version?: string }>(pointers: T[]): T[] =>\n pointers.map((p) => {\n if (p.version && !semverValid(p.version)) {\n const resolved = resolvedVersions.get(`${p.id}@${p.version}`);\n if (resolved) return { ...p, version: resolved };\n }\n return p;\n });\n\n const sends = resource.sends ? resolvePointers(resource.sends) : undefined;\n const receives = resource.receives ? resolvePointers(resource.receives) : undefined;\n\n const lines: string[] = [];\n const baseFields = serializeBaseFields(resource);\n if (baseFields) lines.push(baseFields);\n\n if (sends && sends.length > 0) {\n const sendsStr = serializeMessagePointers(sends, 'sends', msgIndex);\n if (sendsStr) lines.push(sendsStr);\n }\n\n if (receives && receives.length > 0) {\n const recvStr = serializeMessagePointers(receives, 'receives', msgIndex);\n if (recvStr) lines.push(recvStr);\n }\n\n if (resource.writesTo && resource.writesTo.length > 0) {\n for (const container of resource.writesTo) {\n let ref = container.id;\n if (container.version) ref += `@${container.version}`;\n lines.push(` writes-to container ${ref}`);\n }\n }\n\n if (resource.readsFrom && resource.readsFrom.length > 0) {\n for (const container of resource.readsFrom) {\n let ref = container.id;\n if (container.version) ref += `@${container.version}`;\n lines.push(` reads-from container ${ref}`);\n }\n }\n\n const body = lines.join('\\n');\n parts.push(`service ${resource.id} {\\n${body}\\n}`);\n\n return parts.join('\\n\\n');\n}\n","import type { Channel } from '../types';\n\nexport function channelToDSL(resource: Channel): string {\n const lines: string[] = [];\n\n if (resource.version) {\n lines.push(` version ${resource.version}`);\n }\n\n if (resource.name) {\n lines.push(` name \"${resource.name}\"`);\n }\n\n if (resource.address) {\n lines.push(` address \"${resource.address}\"`);\n }\n\n if (resource.protocols && resource.protocols.length > 0) {\n for (const protocol of resource.protocols) {\n lines.push(` protocol \"${protocol}\"`);\n }\n }\n\n if (resource.summary) {\n lines.push(` summary \"${resource.summary.trim()}\"`);\n }\n\n if (resource.routes && resource.routes.length > 0) {\n for (const route of resource.routes) {\n let ref = route.id;\n if (route.version) ref += `@${route.version}`;\n lines.push(` route ${ref}`);\n }\n }\n\n if (!lines.length) {\n return `channel ${resource.id}`;\n }\n\n return `channel ${resource.id} {\\n${lines.join('\\n')}\\n}`;\n}\n","import type { Team, User } from '../types';\n\nexport function teamToDSL(team: Team): string {\n const lines: string[] = [];\n\n if (team.name) lines.push(` name \"${team.name}\"`);\n if (team.avatarUrl) lines.push(` avatar \"${team.avatarUrl}\"`);\n if (team.role) lines.push(` role \"${team.role}\"`);\n if (team.summary) lines.push(` summary \"${team.summary}\"`);\n if (team.email) lines.push(` email \"${team.email}\"`);\n if (team.slackDirectMessageUrl) lines.push(` slack \"${team.slackDirectMessageUrl}\"`);\n\n return `team ${team.id} {\\n${lines.join('\\n')}\\n}`;\n}\n\nexport function userToDSL(user: User): string {\n const lines: string[] = [];\n\n if (user.name) lines.push(` name \"${user.name}\"`);\n if (user.avatarUrl) lines.push(` avatar \"${user.avatarUrl}\"`);\n if (user.role) lines.push(` role \"${user.role}\"`);\n if (user.email) lines.push(` email \"${user.email}\"`);\n if (user.slackDirectMessageUrl) lines.push(` slack \"${user.slackDirectMessageUrl}\"`);\n\n return `user ${user.id} {\\n${lines.join('\\n')}\\n}`;\n}\n","import type { Domain, Service, Event, Command, Query, Channel, Team, User } from '../types';\nimport { serializeBaseFields, serializeMessagePointers, resolveMessageType, buildMessageTypeIndex } from './utils';\nimport type { MessageTypeIndex } from './utils';\nimport { serviceToDSL } from './service';\nimport { messageToDSL } from './message';\nimport { channelToDSL } from './channel';\nimport { teamToDSL, userToDSL } from './owner';\n\ninterface DomainToDSLOptions {\n catalogDir: string;\n hydrate?: boolean;\n _seen?: Set<string>;\n _msgIndex?: MessageTypeIndex;\n}\n\nexport interface DomainResolvers {\n getService?: (id: string, version?: string) => Promise<Service | undefined>;\n getDomain?: (id: string, version?: string) => Promise<Domain | undefined>;\n getMessage?: (id: string, version?: string) => Promise<Event | Command | Query | undefined>;\n getChannel?: (id: string, version?: string) => Promise<Channel | undefined>;\n getTeam?: (id: string) => Promise<Team | undefined>;\n getUser?: (id: string) => Promise<User | undefined>;\n}\n\nasync function hydrateOwners(owners: string[] | undefined, resolvers: DomainResolvers, seen: Set<string>, parts: string[]) {\n if (!owners || !resolvers.getTeam || !resolvers.getUser) return;\n for (const ownerId of owners) {\n const key = `owner:${ownerId}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const team = await resolvers.getTeam(ownerId);\n if (team) {\n parts.push(teamToDSL(team));\n continue;\n }\n\n const user = await resolvers.getUser(ownerId);\n if (user) {\n parts.push(userToDSL(user));\n }\n }\n}\n\nasync function hydrateChannelsFromMessages(\n messages: {\n id: string;\n version?: string;\n to?: { id: string; version?: string }[];\n from?: { id: string; version?: string }[];\n }[],\n resolvers: DomainResolvers,\n seen: Set<string>,\n parts: string[]\n) {\n if (!resolvers.getChannel) return;\n for (const msg of messages) {\n const channels = (msg as any).to || (msg as any).from;\n if (!channels) continue;\n for (const ch of channels) {\n const key = `channel:${ch.id}@${ch.version || 'latest'}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const channel = await resolvers.getChannel(ch.id, ch.version);\n if (channel) {\n parts.push(channelToDSL(channel));\n }\n }\n }\n}\n\nasync function buildDomainBody(\n resource: Domain,\n options: DomainToDSLOptions,\n resolvers: DomainResolvers | undefined,\n keyword: 'domain' | 'subdomain'\n): Promise<{ topLevelParts: string[]; block: string }> {\n const { catalogDir, hydrate = false, _seen = new Set<string>() } = options;\n const msgIndex = options._msgIndex || buildMessageTypeIndex(catalogDir);\n const topLevelParts: string[] = [];\n\n if (hydrate && resolvers) {\n // Hydrate services (and their owners, channels, messages)\n if (resource.services && resource.services.length > 0 && resolvers.getService) {\n for (const svcRef of resource.services) {\n const svcKey = `service:${svcRef.id}@${svcRef.version || 'latest'}`;\n if (_seen.has(svcKey)) continue;\n _seen.add(svcKey);\n\n const svc = await resolvers.getService(svcRef.id, svcRef.version);\n if (svc) {\n // Hydrate service owners\n await hydrateOwners(svc.owners, resolvers, _seen, topLevelParts);\n // Hydrate service channels\n const svcMessages = [...(svc.sends || []), ...(svc.receives || [])];\n await hydrateChannelsFromMessages(svcMessages, resolvers, _seen, topLevelParts);\n // Hydrate service (includes message hydration)\n const svcDsl = await serviceToDSL(svc, { catalogDir, hydrate: true, _seen, _msgIndex: msgIndex }, resolvers.getMessage);\n topLevelParts.push(svcDsl);\n }\n }\n }\n\n // Hydrate domain-level channels\n const domainMessages = [...(resource.sends || []), ...(resource.receives || [])];\n await hydrateChannelsFromMessages(domainMessages, resolvers, _seen, topLevelParts);\n\n // Hydrate domain-level messages\n if (resolvers.getMessage) {\n for (const msg of domainMessages) {\n const key = `${msg.id}@${msg.version || 'latest'}`;\n if (_seen.has(key)) continue;\n _seen.add(key);\n\n const msgType = resolveMessageType(msgIndex, msg.id);\n if (!msgType) continue;\n\n const msgResource = await resolvers.getMessage(msg.id, msg.version);\n if (msgResource) {\n topLevelParts.push(messageToDSL(msgResource, msgType));\n }\n }\n }\n }\n\n const lines: string[] = [];\n const baseFields = serializeBaseFields(resource);\n if (baseFields) lines.push(baseFields);\n\n // Service references\n if (resource.services && resource.services.length > 0) {\n for (const svc of resource.services) {\n let ref = svc.id;\n if (svc.version) ref += `@${svc.version}`;\n lines.push(` service ${ref}`);\n }\n }\n\n if (resource.sends && resource.sends.length > 0) {\n const sendsStr = serializeMessagePointers(resource.sends, 'sends', msgIndex);\n if (sendsStr) lines.push(sendsStr);\n }\n\n if (resource.receives && resource.receives.length > 0) {\n const recvStr = serializeMessagePointers(resource.receives, 'receives', msgIndex);\n if (recvStr) lines.push(recvStr);\n }\n\n // Subdomain blocks (inline)\n if (resource.domains && resource.domains.length > 0) {\n if (hydrate && resolvers?.getDomain) {\n for (const subRef of resource.domains) {\n const subKey = `domain:${subRef.id}@${subRef.version || 'latest'}`;\n if (_seen.has(subKey)) continue;\n _seen.add(subKey);\n\n const subDomain = await resolvers.getDomain(subRef.id, subRef.version);\n if (subDomain) {\n // Hydrate subdomain owners at top level\n await hydrateOwners(subDomain.owners, resolvers, _seen, topLevelParts);\n // Recursively build subdomain\n const sub = await buildDomainBody(\n subDomain,\n { catalogDir, hydrate, _seen, _msgIndex: msgIndex },\n resolvers,\n 'subdomain'\n );\n topLevelParts.push(...sub.topLevelParts);\n // Indent the subdomain block to nest inside the parent\n const indented = sub.block\n .split('\\n')\n .map((line) => ` ${line}`)\n .join('\\n');\n lines.push(indented);\n }\n }\n } else {\n // Non-hydrated: just output references\n for (const sub of resource.domains) {\n let ref = sub.id;\n if (sub.version) ref += `@${sub.version}`;\n lines.push(` subdomain ${ref}`);\n }\n }\n }\n\n const body = lines.join('\\n');\n const block = `${keyword} ${resource.id} {\\n${body}\\n}`;\n\n return { topLevelParts, block };\n}\n\nexport async function domainToDSL(resource: Domain, options: DomainToDSLOptions, resolvers?: DomainResolvers): Promise<string> {\n const { catalogDir, hydrate = false, _seen = new Set<string>() } = options;\n const msgIndex = options._msgIndex || buildMessageTypeIndex(catalogDir);\n\n const result = await buildDomainBody(resource, { catalogDir, hydrate, _seen, _msgIndex: msgIndex }, resolvers, 'domain');\n const parts = [...result.topLevelParts, result.block];\n\n return parts.join('\\n\\n');\n}\n","import type { Container } from '../types';\nimport { serializeBaseFields } from './utils';\n\nexport function containerToDSL(resource: Container): string {\n const lines: string[] = [];\n const baseFields = serializeBaseFields(resource);\n if (baseFields) lines.push(baseFields);\n\n if (resource.container_type) {\n lines.push(` container-type ${resource.container_type}`);\n }\n\n if (resource.technology) {\n lines.push(` technology \"${resource.technology}\"`);\n }\n\n if (resource.authoritative === true) {\n lines.push(` authoritative true`);\n }\n\n if (resource.access_mode) {\n lines.push(` access-mode ${resource.access_mode}`);\n }\n\n if (resource.classification) {\n lines.push(` classification ${resource.classification}`);\n }\n\n if (resource.residency) {\n lines.push(` residency \"${resource.residency}\"`);\n }\n\n if (resource.retention) {\n lines.push(` retention \"${resource.retention}\"`);\n }\n\n const body = lines.join('\\n');\n return `container ${resource.id} {\\n${body}\\n}`;\n}\n","import type { Event, Command, Query, Service, Domain, Team, User, Channel, Container } from '../types';\nimport { messageToDSL } from './message';\nimport { serviceToDSL } from './service';\nimport { domainToDSL } from './domain';\nimport { teamToDSL, userToDSL } from './owner';\nimport { channelToDSL } from './channel';\nimport { containerToDSL } from './container';\nimport { buildMessageTypeIndex, resolveMessageType, msgVersionMatches } from './utils';\nimport type { MessageType, MessageTypeIndex } from './utils';\n\ntype ResourceType = 'event' | 'command' | 'query' | 'service' | 'domain';\n\nexport interface ToDSLOptions {\n type: ResourceType;\n hydrate?: boolean;\n}\n\ntype AnyResource = Event | Command | Query | Service | Domain;\n\nexport interface ResourceResolvers {\n getEvent: (id: string, version?: string) => Promise<Event | undefined>;\n getCommand: (id: string, version?: string) => Promise<Command | undefined>;\n getQuery: (id: string, version?: string) => Promise<Query | undefined>;\n getService: (id: string, version?: string) => Promise<Service | undefined>;\n getServices: (options?: { latestOnly?: boolean }) => Promise<Service[]>;\n getDomain: (id: string, version?: string) => Promise<Domain | undefined>;\n getChannel: (id: string, version?: string) => Promise<Channel | undefined>;\n getChannels: (options?: { latestOnly?: boolean }) => Promise<Channel[]>;\n getContainer: (id: string, version?: string) => Promise<Container | undefined>;\n getTeam: (id: string) => Promise<Team | undefined>;\n getUser: (id: string) => Promise<User | undefined>;\n}\n\nfunction getMessage(resolvers: ResourceResolvers, msgIndex: MessageTypeIndex) {\n return async (id: string, version?: string) => {\n const msgType = resolveMessageType(msgIndex, id);\n if (!msgType) return undefined;\n switch (msgType) {\n case 'event':\n return resolvers.getEvent(id, version);\n case 'command':\n return resolvers.getCommand(id, version);\n case 'query':\n return resolvers.getQuery(id, version);\n }\n };\n}\n\nasync function hydrateChannel(\n channelId: string,\n channelVersion: string | undefined,\n resolvers: ResourceResolvers,\n seen: Set<string>,\n parts: string[]\n) {\n const key = `channel:${channelId}@${channelVersion || 'latest'}`;\n if (seen.has(key)) return;\n seen.add(key);\n\n const channel = await resolvers.getChannel(channelId, channelVersion);\n if (!channel) return;\n\n // Hydrate any channels this channel routes to (downstream)\n if (channel.routes && channel.routes.length > 0) {\n for (const route of channel.routes) {\n await hydrateChannel(route.id, route.version, resolvers, seen, parts);\n }\n }\n\n // Hydrate any channels that route TO this channel (upstream)\n const allChannels = (await resolvers.getChannels({ latestOnly: false })) || [];\n const targetVersion = channelVersion || channel.version;\n for (const upstream of allChannels) {\n if (!upstream.routes) continue;\n const routesToThis = upstream.routes.some((route) => {\n if (route.id !== channelId) return false;\n if (!route.version) {\n // Unversioned routes point to latest, so only match when hydrating latest.\n return !channelVersion;\n }\n return msgVersionMatches(route.version, targetVersion);\n });\n if (routesToThis) {\n await hydrateChannel(upstream.id, upstream.version, resolvers, seen, parts);\n }\n }\n\n parts.push(channelToDSL(channel));\n}\n\nasync function hydrateChannels(resource: Service | Domain, resolvers: ResourceResolvers, seen: Set<string>, parts: string[]) {\n const allMessages = [...((resource as Service).sends || []), ...((resource as Service).receives || [])];\n for (const msg of allMessages) {\n const channels = 'to' in msg ? (msg as any).to : 'from' in msg ? (msg as any).from : undefined;\n if (!channels) continue;\n for (const ch of channels) {\n await hydrateChannel(ch.id, ch.version, resolvers, seen, parts);\n }\n }\n}\n\nasync function hydrateContainers(resource: Service, resolvers: ResourceResolvers, seen: Set<string>, parts: string[]) {\n const allContainers = [...(resource.writesTo || []), ...(resource.readsFrom || [])];\n for (const ref of allContainers) {\n const key = `container:${ref.id}@${ref.version || 'latest'}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const container = await resolvers.getContainer(ref.id, ref.version);\n if (!container) continue;\n\n parts.push(containerToDSL(container));\n }\n}\n\nasync function hydrateOwners(owners: string[] | undefined, resolvers: ResourceResolvers, seen: Set<string>, parts: string[]) {\n if (!owners) return;\n for (const ownerId of owners) {\n const key = `owner:${ownerId}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const team = await resolvers.getTeam(ownerId);\n if (team) {\n parts.push(teamToDSL(team));\n continue;\n }\n\n const user = await resolvers.getUser(ownerId);\n if (user) {\n parts.push(userToDSL(user));\n }\n }\n}\n\nasync function hydrateMessageServices(\n messageId: string,\n messageVersion: string | undefined,\n resolvers: ResourceResolvers,\n seen: Set<string>,\n parts: string[],\n catalogDir: string,\n msgIndex: MessageTypeIndex\n) {\n const services = (await resolvers.getServices({ latestOnly: false })) || [];\n for (const service of services) {\n const key = `service:${service.id}@${service.version || 'latest'}`;\n if (seen.has(key)) continue;\n\n const referencesMessage = [...(service.sends || []), ...(service.receives || [])].some(\n (msg) => msg.id === messageId && msgVersionMatches(msg.version, messageVersion)\n );\n\n if (referencesMessage) {\n seen.add(key);\n const matchMsg = (msg: { id: string; version?: string }) =>\n msg.id === messageId && msgVersionMatches(msg.version, messageVersion);\n const resolvePointerVersion = <T extends { id: string; version?: string }>(msg: T): T => {\n if (msg.id === messageId && msg.version && msg.version !== messageVersion && messageVersion) {\n return { ...msg, version: messageVersion };\n }\n return msg;\n };\n const filtered: Service = {\n ...service,\n sends: service.sends?.filter(matchMsg).map(resolvePointerVersion),\n receives: service.receives?.filter(matchMsg).map(resolvePointerVersion),\n };\n await hydrateChannels(filtered, resolvers, seen, parts);\n parts.push(await serviceToDSL(filtered, { catalogDir, hydrate: false, _seen: new Set(seen), _msgIndex: msgIndex }));\n }\n }\n}\n\nasync function hydrateRelatedServices(\n messages: { id: string; version?: string }[],\n direction: 'sends' | 'receives',\n resolvers: ResourceResolvers,\n seen: Set<string>,\n parts: string[],\n catalogDir: string,\n msgIndex: MessageTypeIndex\n) {\n if (!messages.length) return;\n\n const referencesHydratedMessage = (msg: { id: string; version?: string }) =>\n messages.some((input) => msg.id === input.id && msgVersionMatches(msg.version, input.version));\n\n const services = (await resolvers.getServices({ latestOnly: false })) || [];\n for (const service of services) {\n const key = `service:${service.id}@${service.version || 'latest'}`;\n if (seen.has(key)) continue;\n\n if (direction === 'sends') {\n const matchedPointers = (service.sends || []).filter(referencesHydratedMessage);\n if (matchedPointers.length > 0) {\n seen.add(key);\n const filtered: Service = {\n ...service,\n sends: matchedPointers,\n receives: undefined,\n };\n await hydrateChannels(filtered, resolvers, seen, parts);\n parts.push(await serviceToDSL(filtered, { catalogDir, hydrate: false, _seen: new Set(seen), _msgIndex: msgIndex }));\n }\n } else {\n const matchedPointers = (service.receives || []).filter(referencesHydratedMessage);\n if (matchedPointers.length > 0) {\n seen.add(key);\n const filtered: Service = {\n ...service,\n sends: undefined,\n receives: matchedPointers,\n };\n await hydrateChannels(filtered, resolvers, seen, parts);\n parts.push(await serviceToDSL(filtered, { catalogDir, hydrate: false, _seen: new Set(seen), _msgIndex: msgIndex }));\n }\n }\n }\n}\n\nexport const toDSL =\n (catalogDir: string, resolvers: ResourceResolvers) =>\n async (resource: AnyResource | AnyResource[], options: ToDSLOptions): Promise<string> => {\n const resources = Array.isArray(resource) ? resource : [resource];\n const seen = new Set<string>();\n const parts: string[] = [];\n const msgIndex = buildMessageTypeIndex(catalogDir);\n\n for (const res of resources) {\n const key = `${options.type}:${res.id}@${res.version || 'latest'}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n switch (options.type) {\n case 'event':\n case 'command':\n case 'query':\n if (options.hydrate) {\n await hydrateOwners(res.owners, resolvers, seen, parts);\n await hydrateMessageServices(res.id, res.version, resolvers, seen, parts, catalogDir, msgIndex);\n }\n parts.push(messageToDSL(res as Event | Command | Query, options.type as MessageType));\n break;\n case 'service':\n if (options.hydrate) {\n await hydrateOwners(res.owners, resolvers, seen, parts);\n await hydrateChannels(res as Service, resolvers, seen, parts);\n await hydrateContainers(res as Service, resolvers, seen, parts);\n }\n parts.push(\n await serviceToDSL(\n res as Service,\n { catalogDir, hydrate: options.hydrate, _seen: seen, _msgIndex: msgIndex },\n getMessage(resolvers, msgIndex)\n )\n );\n if (options.hydrate) {\n const svc = res as Service;\n // For messages this service sends: find services that receive them (downstream consumers)\n await hydrateRelatedServices(svc.sends || [], 'receives', resolvers, seen, parts, catalogDir, msgIndex);\n // For messages this service receives: find services that send them (upstream producers)\n await hydrateRelatedServices(svc.receives || [], 'sends', resolvers, seen, parts, catalogDir, msgIndex);\n }\n break;\n case 'domain':\n if (options.hydrate) {\n await hydrateOwners(res.owners, resolvers, seen, parts);\n }\n parts.push(\n await domainToDSL(\n res as Domain,\n { catalogDir, hydrate: options.hydrate, _seen: seen, _msgIndex: msgIndex },\n {\n getService: resolvers.getService,\n getDomain: resolvers.getDomain,\n getMessage: getMessage(resolvers, msgIndex),\n getChannel: resolvers.getChannel,\n getTeam: resolvers.getTeam,\n getUser: resolvers.getUser,\n }\n )\n );\n if (options.hydrate) {\n const domain = res as Domain;\n const allSends: { id: string; version?: string }[] = [];\n const allReceives: { id: string; version?: string }[] = [];\n\n if (domain.services?.length) {\n for (const svcRef of domain.services) {\n const svc = await resolvers.getService(svcRef.id, svcRef.version);\n if (svc) {\n allSends.push(...(svc.sends || []));\n allReceives.push(...(svc.receives || []));\n }\n }\n }\n\n // Downstream: services that receive what domain services send\n await hydrateRelatedServices(allSends, 'receives', resolvers, seen, parts, catalogDir, msgIndex);\n // Upstream: services that send what domain services receive\n await hydrateRelatedServices(allReceives, 'sends', resolvers, seen, parts, catalogDir, msgIndex);\n }\n break;\n }\n }\n\n return parts.join('\\n\\n');\n };\n","import fs from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { findFileById, invalidateFileCache } 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 * // Get the event with the schema attached\n * const event = await getEvent('InventoryAdjusted', '0.0.1', { attachSchema: true });\n * ```\n */\nexport const getEvent =\n (directory: string) =>\n async (id: string, version?: string, options?: { attachSchema?: boolean }): Promise<Event> =>\n getResource(directory, id, version, { type: 'event', ...options }) 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 * // Get all events with the schema attached\n * const events = await getEvents({ attachSchema: true });\n * ```\n */\nexport const getEvents =\n (directory: string) =>\n async (options?: { latestOnly?: boolean; attachSchema?: 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'; override?: boolean } = { path: '', format: 'mdx', override: false }\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 invalidateFileCache();\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) =>\n async (id: string, file: { content: string; fileName: string }, version?: string, options?: { path?: string }) =>\n addFileToResource(directory, id, file, version, options);\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 { addFileToEvent } = 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 file to the latest InventoryAdjusted event\n * await addFileToEvent('InventoryAdjusted', { schema, fileName: 'schema.json' });\n *\n * // adds a file to a specific version of the InventoryAdjusted event\n * await addFileToEvent('InventoryAdjusted', { schema, fileName: 'schema.json' }, '0.0.1');\n *\n * ```\n */\nexport const addSchemaToEvent =\n (directory: string) =>\n async (id: string, schema: { schema: string; fileName: string }, version?: string, options?: { path?: string }) => {\n await addFileToEvent(directory)(id, { content: schema.schema, fileName: schema.fileName }, version, options);\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, normalize, sep as pathSeparator, resolve, basename, relative } from 'node:path';\nimport matter from 'gray-matter';\nimport { satisfies, validRange, valid } from 'semver';\n\n// In-memory file index cache. Auto-built on first read, invalidated on writes.\ninterface FileIndexEntry {\n path: string;\n id: string;\n version: string;\n isVersioned: boolean;\n}\n\nlet _fileIndexCache: Map<string, FileIndexEntry[]> | null = null;\nlet _fileIndexCatalogDir: string | null = null;\nlet _matterCache: Map<string, matter.GrayMatterFile<string>> | null = null;\nlet _filePathToIdCache: Map<string, string> | null = null;\nlet _fileIndexMtimeMs: number = 0;\n\nfunction toCanonicalPath(inputPath: string): string {\n return normalize(resolve(inputPath));\n}\n\nfunction buildFileCache(catalogDir: string): void {\n const canonicalCatalogDir = toCanonicalPath(catalogDir);\n const files = globSync('**/index.{md,mdx}', {\n cwd: canonicalCatalogDir,\n ignore: ['node_modules/**'],\n absolute: true,\n nodir: true,\n }).map(normalize);\n\n const index = new Map<string, FileIndexEntry[]>();\n const matterResults = new Map<string, matter.GrayMatterFile<string>>();\n const pathToId = new Map<string, string>();\n\n for (const file of files) {\n const content = fsSync.readFileSync(file, 'utf-8');\n const parsed = matter(content);\n matterResults.set(file, parsed);\n\n const id = parsed.data.id;\n if (!id) continue;\n\n const resourceId = String(id);\n const version = parsed.data.version || '';\n const isVersioned = file.includes('versioned');\n const entry: FileIndexEntry = { path: file, id: resourceId, version: String(version), isVersioned };\n pathToId.set(file, resourceId);\n\n const existing = index.get(resourceId);\n if (existing) {\n existing.push(entry);\n } else {\n index.set(resourceId, [entry]);\n }\n }\n\n _fileIndexCache = index;\n _fileIndexCatalogDir = canonicalCatalogDir;\n _matterCache = matterResults;\n _filePathToIdCache = pathToId;\n try {\n _fileIndexMtimeMs = fsSync.statSync(canonicalCatalogDir).mtimeMs;\n } catch {\n _fileIndexMtimeMs = 0;\n }\n}\n\nfunction ensureFileCache(catalogDir: string): void {\n const canonicalCatalogDir = toCanonicalPath(catalogDir);\n if (!_fileIndexCache || _fileIndexCatalogDir !== canonicalCatalogDir) {\n buildFileCache(catalogDir);\n return;\n }\n // Check if catalog dir was recreated (e.g. tests wiping and recreating)\n try {\n const currentMtime = fsSync.statSync(canonicalCatalogDir).mtimeMs;\n if (currentMtime !== _fileIndexMtimeMs) {\n buildFileCache(catalogDir);\n }\n } catch {\n buildFileCache(catalogDir);\n }\n}\n\n/** Invalidate the file cache. Call after any write/rm/version operation. */\nexport function invalidateFileCache(): void {\n _fileIndexCache = null;\n _fileIndexCatalogDir = null;\n _matterCache = null;\n _filePathToIdCache = null;\n}\n\n/**\n * Incrementally updates the in-memory file index for a single file write.\n * No-ops when cache is disabled or points at a different catalog.\n */\nexport function upsertFileCacheEntry(catalogDir: string, filePath: string, rawContent: string): void {\n const canonicalCatalogDir = toCanonicalPath(catalogDir);\n if (!_fileIndexCache || !_matterCache || !_filePathToIdCache || _fileIndexCatalogDir !== canonicalCatalogDir) {\n return;\n }\n\n const normalizedPath = toCanonicalPath(filePath);\n const parsed = matter(rawContent);\n\n // Remove stale entry for this file path (if it existed under another id/version).\n const previousId = _filePathToIdCache.get(normalizedPath);\n if (previousId) {\n const previousEntries = _fileIndexCache.get(previousId) || [];\n const nextEntries = previousEntries.filter((entry) => entry.path !== normalizedPath);\n if (nextEntries.length === 0) {\n _fileIndexCache.delete(previousId);\n } else {\n _fileIndexCache.set(previousId, nextEntries);\n }\n _filePathToIdCache.delete(normalizedPath);\n }\n\n _matterCache.set(normalizedPath, parsed);\n\n const id = parsed.data.id;\n if (!id) {\n _filePathToIdCache.delete(normalizedPath);\n return;\n }\n\n const resourceId = String(id);\n const entry: FileIndexEntry = {\n path: normalizedPath,\n id: resourceId,\n version: String(parsed.data.version || ''),\n isVersioned: normalizedPath.includes(`${pathSeparator}versioned${pathSeparator}`),\n };\n\n const entries = _fileIndexCache.get(resourceId) || [];\n entries.push(entry);\n _fileIndexCache.set(resourceId, entries);\n _filePathToIdCache.set(normalizedPath, resourceId);\n\n try {\n _fileIndexMtimeMs = fsSync.statSync(canonicalCatalogDir).mtimeMs;\n } catch {\n // Ignore mtime refresh failures; cache will self-heal on next ensureFileCache call.\n }\n}\n\n// Keep these as aliases for backwards compat with CLI export code\nexport const enableFileCache = buildFileCache;\nexport const disableFileCache = invalidateFileCache;\n\n/**\n * Returns cached matter.read result if available, otherwise reads from disk.\n */\nexport function cachedMatterRead(filePath: string): matter.GrayMatterFile<string> {\n if (_matterCache) {\n const cached = _matterCache.get(filePath);\n if (cached) return cached;\n }\n return matter.read(filePath);\n}\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 ensureFileCache(catalogDir);\n const entries = _fileIndexCache!.get(id);\n if (!entries) return false;\n return entries.some((e) => e.version === version);\n};\n\nexport const findFileById = async (catalogDir: string, id: string, version?: string): Promise<string | undefined> => {\n ensureFileCache(catalogDir);\n\n const entries = _fileIndexCache!.get(id);\n if (!entries || entries.length === 0) return undefined;\n\n const latestEntry = entries.find((e) => !e.isVersioned);\n\n if (!version || version === 'latest') {\n return latestEntry?.path;\n }\n\n // Exact version match\n const exactMatch = entries.find((e) => e.version === version);\n if (exactMatch) return exactMatch.path;\n\n // Semver range match\n const semverRange = validRange(version);\n if (semverRange) {\n const match = entries.find((e) => {\n try {\n return satisfies(e.version, semverRange);\n } catch {\n return false;\n }\n });\n return match?.path;\n }\n\n return undefined;\n};\n\nexport const getFiles = async (pattern: string, ignore: string | string[] = '') => {\n try {\n // 1. Normalize the input pattern to handle mixed separators potentially\n const normalizedInputPattern = normalize(pattern);\n\n // 2. Determine the absolute base directory (cwd for glob)\n // Resolve ensures it's absolute. Handles cases with/without globstar.\n const absoluteBaseDir = resolve(\n normalizedInputPattern.includes('**') ? normalizedInputPattern.split('**')[0] : dirname(normalizedInputPattern)\n );\n\n // 3. Determine the pattern part relative to the absolute base directory\n // We extract the part of the normalized pattern that comes *after* the absoluteBaseDir\n let relativePattern = relative(absoluteBaseDir, normalizedInputPattern);\n\n // On Windows, relative() might return empty string if paths are identical,\n // or might need normalization if the original pattern didn't have `**`\n // Example: pattern = 'dir/file.md', absoluteBaseDir='.../dir', normalized='...\\dir\\file.md'\n // relative() -> 'file.md'\n // Example: pattern = 'dir/**/file.md', absoluteBaseDir='.../dir', normalized='...\\dir\\**\\file.md'\n // relative() -> '**\\file.md'\n // Convert separators in the relative pattern to forward slashes for glob\n relativePattern = relativePattern.replace(/\\\\/g, '/');\n\n const ignoreList = Array.isArray(ignore) ? ignore : [ignore];\n\n const files = globSync(relativePattern, {\n cwd: absoluteBaseDir,\n ignore: ['node_modules/**', ...ignoreList],\n absolute: true,\n nodir: true,\n });\n\n // 5. Normalize results for consistency before returning\n return files.map(normalize);\n } catch (error: any) {\n // Add more diagnostic info to the error\n const absoluteBaseDirForError = resolve(\n normalize(pattern).includes('**') ? normalize(pattern).split('**')[0] : dirname(normalize(pattern))\n );\n const relativePatternForError = relative(absoluteBaseDirForError, normalize(pattern)).replace(/\\\\/g, '/');\n throw new Error(\n `Error finding files for pattern \"${pattern}\" (using cwd: \"${absoluteBaseDirForError}\", globPattern: \"${relativePatternForError}\"): ${error.message}`\n );\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 // Escape the id to avoid regex issues\n const escapedId = id.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const idRegex = new RegExp(`^id:\\\\s*(['\"]|>-)?\\\\s*${escapedId}['\"]?\\\\s*$`, 'm');\n\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 {\n copyDir,\n findFileById,\n getFiles,\n searchFilesForId,\n versionExists,\n cachedMatterRead,\n invalidateFileCache,\n upsertFileCacheEntry,\n} 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';\nimport { basename } from 'node:path';\nimport path from 'node:path';\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 // Handle both forward and back slashes for cross-platform compatibility (Windows uses \\, Unix uses /)\n const sourceDirectory = dirname(file).replace(/[/\\\\]versioned[/\\\\][^/\\\\]+[/\\\\]/, path.sep);\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 const ignoreListToCopy = ['events', 'commands', 'queries', 'versioned'];\n\n // Copy the event to the versioned directory\n await copyDir(catalogDir, sourceDirectory, targetDirectory, (src) => {\n // get the folder name\n const folderName = basename(src);\n\n if (ignoreListToCopy.includes(folderName)) {\n return false;\n }\n return true;\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 // Dont remove anything in the ignore list\n if (ignoreListToCopy.includes(file)) {\n return;\n }\n if (file !== 'versioned') {\n fsSync.rmSync(join(sourceDirectory, file), { recursive: true });\n }\n })\n );\n });\n\n invalidateFileCache();\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 upsertFileCacheEntry(catalogDir, 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; attachSchema?: boolean },\n filePath?: string\n): Promise<Resource | undefined> => {\n const attachSchema = options?.attachSchema || false;\n const file = filePath || (id ? await findFileById(catalogDir, id, version) : undefined);\n if (!file || !fsSync.existsSync(file)) return;\n\n const { data, content } = cachedMatterRead(file);\n\n if (attachSchema && data?.schemaPath) {\n const resourceDirectory = dirname(file);\n const pathToSchema = join(resourceDirectory, data.schemaPath);\n if (fsSync.existsSync(pathToSchema)) {\n const schema = fsSync.readFileSync(pathToSchema, 'utf8');\n // Try to parse the schema\n try {\n data.schema = JSON.parse(schema);\n } catch (error) {\n data.schema = schema;\n }\n }\n }\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 getResourceFolderName = async (catalogDir: string, id: string, version?: string) => {\n const paths = await getResourcePath(catalogDir, id, version);\n if (!paths) return;\n return paths?.directory.split(path.sep).filter(Boolean).pop();\n};\n\nexport const toResource = async (catalogDir: string, rawContents: string) => {\n const { data, content } = matter(rawContents);\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n};\n\nexport const getResources = async (\n catalogDir: string,\n {\n type,\n latestOnly = false,\n ignore = [],\n pattern = '',\n attachSchema = false,\n }: { type: string; pattern?: string; latestOnly?: boolean; ignore?: string[]; attachSchema?: boolean }\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 } = cachedMatterRead(file);\n\n // Attach the schema if the attachSchema option is set to true\n if (attachSchema && data?.schemaPath) {\n const resourceDirectory = dirname(file);\n const pathToSchema = join(resourceDirectory, data.schemaPath);\n if (fsSync.existsSync(pathToSchema)) {\n const schema = fsSync.readFileSync(pathToSchema, 'utf8');\n // Try to parse the schema\n try {\n data.schema = JSON.parse(schema);\n } catch (error) {\n data.schema = schema;\n }\n }\n }\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 // Verify file is actually removed\n await waitForFileRemoval(file);\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 // Verify directory is actually removed\n await waitForFileRemoval(directory);\n })\n );\n }\n\n invalidateFileCache();\n};\n\n// Helper function to ensure file/directory is completely removed\nconst waitForFileRemoval = async (path: string, maxRetries: number = 50, delay: number = 10): Promise<void> => {\n for (let i = 0; i < maxRetries; i++) {\n try {\n await fs.access(path);\n // If access succeeds, file still exists, wait and retry\n await new Promise((resolve) => setTimeout(resolve, delay));\n } catch (error) {\n // If access fails, file is removed\n return;\n }\n }\n // If we reach here, file still exists after all retries\n throw new Error(`File/directory ${path} was not removed after ${maxRetries} attempts`);\n};\n\nexport const addFileToResource = async (\n catalogDir: string,\n id: string,\n file: { content: string; fileName: string },\n version?: string,\n options?: { path?: string }\n) => {\n let pathToResource: string | undefined;\n\n if (options?.path) {\n pathToResource = join(catalogDir, options.path, 'index.mdx');\n } else {\n // Fall back to global lookup (existing behavior)\n pathToResource = await findFileById(catalogDir, id, version);\n }\n\n if (!pathToResource) throw new Error('Cannot find directory to write file to');\n\n // Create the directory if it doesn't exist\n fsSync.mkdirSync(path.dirname(pathToResource), { recursive: true });\n\n let fileContent = file.content.trim();\n\n try {\n const json = JSON.parse(fileContent);\n fileContent = JSON.stringify(json, null, 2);\n } catch (error) {\n // Just silently fail if the file is not valid JSON\n // Write it as it is\n }\n\n fsSync.writeFileSync(join(dirname(pathToResource), file.fileName), fileContent);\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\nexport const isLatestVersion = async (catalogDir: string, id: string, version?: string) => {\n const resource = await getResource(catalogDir, id, version);\n if (!resource) return false;\n\n const pathToResource = await getResourcePath(catalogDir, id, version);\n\n return !pathToResource?.relativePath.replace(/\\\\/g, '/').includes('/versioned/');\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, invalidateFileCache } 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 * // Gets the command with the schema attached\n * const command = await getCommand('UpdateInventory', '0.0.1', { attachSchema: true });\n * ```\n */\nexport const getCommand =\n (directory: string) =>\n async (id: string, version?: string, options?: { attachSchema?: boolean }): Promise<Command> =>\n getResource(directory, id, version, { type: 'command', ...options }) 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 * // Gets all commands with the schema attached\n * const commands = await getCommands({ attachSchema: true });\n * ```\n */\nexport const getCommands =\n (directory: string) =>\n async (options?: { latestOnly?: boolean; attachSchema?: 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'; override?: boolean } = { path: '', format: 'mdx', override: false }\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 invalidateFileCache();\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) =>\n async (id: string, file: { content: string; fileName: string }, version?: string, options?: { path?: string }) =>\n addFileToResource(directory, id, file, version, options);\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) =>\n async (id: string, schema: { schema: string; fileName: string }, version?: string, options?: { path?: string }) => {\n await addFileToCommand(directory)(id, { content: schema.schema, fileName: schema.fileName }, version, options);\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, invalidateFileCache } 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 * // Gets the query with the schema attached\n * const event = await getQuery('GetOrder', '0.0.1', { attachSchema: true });\n * ```\n */\nexport const getQuery =\n (directory: string) =>\n async (id: string, version?: string, options?: { attachSchema?: boolean }): Promise<Query> =>\n getResource(directory, id, version, { type: 'query', ...options }) 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 * // Gets all queries with the schema attached\n * const queries = await getQueries({ attachSchema: true });\n * ```\n */\nexport const getQueries =\n (directory: string) =>\n async (options?: { latestOnly?: boolean; attachSchema?: 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'; override?: boolean } = { path: '', format: 'mdx', override: false }\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 invalidateFileCache();\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) =>\n async (id: string, file: { content: string; fileName: string }, version?: string, options?: { path?: string }) =>\n addFileToResource(directory, id, file, version, options);\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) =>\n async (id: string, schema: { schema: string; fileName: string }, version?: string, options?: { path?: string }) => {\n await addFileToQuery(directory)(id, { content: schema.schema, fileName: schema.fileName }, version, options);\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, relative } from 'node:path';\nimport {\n addFileToResource,\n getFileFromResource,\n getResource,\n rmResourceById,\n versionResource,\n writeResource,\n getVersionedDirectory,\n getResources,\n getResourcePath,\n toResource,\n} from './internal/resources';\nimport { findFileById, invalidateFileCache, 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 a service from EventCatalog by it's path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getServiceByPath } = utils('/path/to/eventcatalog');\n *\n * // Returns a service from the catalog by it's path\n * const service = await getServiceByPath('/services/InventoryService/index.mdx');\n * ```\n */\nexport const getServiceByPath = (directory: string) => async (path: string) => {\n const service = await getResource(directory, undefined, undefined, { type: 'service' }, path);\n return service as Service;\n};\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: [\n '**/events/**',\n '**/commands/**',\n '**/queries/**',\n '**/entities/**',\n '**/channels/**',\n '**/containers/**',\n '**/data-products/**',\n '**/data-stores/**',\n '**/flows/**',\n '**/subdomains/**/entities/**',\n ],\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 as { id: string; version: string }[]);\n }\n\n if (Array.isArray(service.receives)) {\n resource.receives = uniqueVersions(service.receives as { id: string; version: string }[]);\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'; override?: boolean } = { path: '', format: 'mdx', override: false }\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 invalidateFileCache();\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 await rmResourceById(directory, id, version, { type: 'service', persistFiles });\n};\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 let specificationFiles;\n\n if (Array.isArray(serviceSpecifications)) {\n specificationFiles = serviceSpecifications.map((spec) => ({ key: spec.type, path: spec.path }));\n } else {\n specificationFiles = Object.keys(serviceSpecifications).map((spec) => ({\n key: spec,\n path: serviceSpecifications[spec as keyof Specifications] as string,\n }));\n }\n\n const getSpecs = specificationFiles.map(async ({ key, path: fileName }) => {\n if (!fileName) {\n throw new Error(`Specification file name for ${fileName} is undefined`);\n }\n const rawFile = await getFileFromResource(directory, id, { fileName }, version);\n\n return { key, 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\n/**\n * Check to see if the path is a service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { isService } = utils('/path/to/eventcatalog');\n *\n * // returns true if the path is a service\n * await isService('/services/InventoryService/index.mdx');\n * ```\n */\nexport const isService = (directory: string) => async (path: string) => {\n const service = await getServiceByPath(directory)(path);\n // Get relative path from root directory\n const relativePath = relative(directory, path);\n\n // Split into path segments using regex to handle both / and \\\n const segments = relativePath.split(/[/\\\\]+/);\n\n // needs to workf or windows too\n return !!service && segments.includes('services');\n};\n\n/**\n * Takes a given raw file and converts it to a service.\n *\n * @param directory - The directory to convert the file to a service.\n * @returns The service.\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { toService } = utils('/path/to/eventcatalog');\n *\n * // Read the file from somewhere\n * const file = fs.readFileSync('/path/to/services/InventoryService/index.mdx', 'utf8');\n *\n * // Converts the raw file to a service\n * await toService(file);\n * ```\n */\nexport const toService = (directory: string) => async (file: string) => toResource(directory, file) as Promise<Service>;\n\n/**\n * Add an entity to a service by its id.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addEntityToService } = utils('/path/to/eventcatalog');\n *\n * // adds a new entity (User) to the InventoryService\n * await addEntityToService('InventoryService', { id: 'User', version: '1.0.0' });\n *\n * // adds a new entity (Product) to a specific version of the InventoryService\n * await addEntityToService('InventoryService', { id: 'Product', version: '1.0.0' }, '2.0.0');\n *\n * ```\n */\nexport const addEntityToService =\n (directory: string) => async (id: string, entity: { 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 (service.entities === undefined) {\n service.entities = [];\n }\n\n // Check if the entity is already in the list\n for (let i = 0; i < service.entities.length; i++) {\n if (service.entities[i].id === entity.id && service.entities[i].version === entity.version) {\n return;\n }\n }\n\n service.entities.push({ id: entity.id, version: entity.version });\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 * Add a data store to a service by it's id.\n *\n * Optionally specify a version to add the data store to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds an data store to the service\n * const { addDataStoreToService } = utils('/path/to/eventcatalog');\n *\n * // Adds a new data store (orders-db) that the InventoryService will write to\n * await addDataStoreToService('InventoryService', 'writesTo', { id: 'orders-db', version: '2.0.0' });\n *\n * * // Adds a new data store (OrderComplete) that the InventoryService will read from\n * await addDataStoreToService('InventoryService', 'readsFrom', { id: 'orders-db', version: '1.0.0' });\n *\n * ```\n */\n\nexport const addDataStoreToService =\n (directory: string) =>\n async (id: string, operation: 'writesTo' | 'readsFrom', dataStore: { 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 (operation === 'writesTo') {\n if (service.writesTo === undefined) {\n service.writesTo = [];\n }\n\n // We first check if the data store is already in the list\n for (let i = 0; i < service.writesTo.length; i++) {\n if (service.writesTo[i].id === dataStore.id && service.writesTo[i].version === dataStore.version) {\n return;\n }\n }\n\n service.writesTo.push({ id: dataStore.id, version: dataStore.version });\n } else if (operation === 'readsFrom') {\n if (service.readsFrom === undefined) {\n service.readsFrom = [];\n }\n\n // We first check if the data store is already in the list\n for (let i = 0; i < service.readsFrom.length; i++) {\n if (service.readsFrom[i].id === dataStore.id && service.readsFrom[i].version === dataStore.version) {\n return;\n }\n }\n service.readsFrom.push({ id: dataStore.id, version: dataStore.version });\n } else {\n throw new Error(`Operation ${operation} is invalid, only 'writesTo' and 'readsFrom' 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","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, invalidateFileCache, 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/**', '**/entities/**'],\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 as { id: string; version: string }[]);\n }\n\n if (Array.isArray(domain.domains)) {\n resource.domains = uniqueVersions(domain.domains as { id: string; version: string }[]);\n }\n\n if (Array.isArray(domain.sends)) {\n resource.sends = uniqueVersions(domain.sends as { id: string; version: string }[]);\n }\n\n if (Array.isArray(domain.receives)) {\n resource.receives = uniqueVersions(domain.receives as { id: string; version: string }[]);\n }\n\n if (Array.isArray(domain.dataProducts)) {\n resource.dataProducts = uniqueVersions(domain.dataProducts as { id: string; version: string }[]);\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 invalidateFileCache();\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\n/**\n * Add a subdomain to a domain by it's id.\n * Optionally specify a version to add the subdomain to a specific version of the domain\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds a subdomain to the given domain\n * const { addSubDomainToDomain } = utils('/path/to/eventcatalog');\n *\n * // Adds a subdomain (Payment Domain) to the domain (Orders)\n * await addSubDomainToDomain('Orders', { service: 'Payment Domain', version: '2.0.0' });\n * // Adds a subdomain (Inventory Domain) to the domain (Orders) with a specific version\n * await addSubDomainToDomain('Orders', { service: 'Inventory Domain', version: '2.0.0' }, '1.0.0');\n * ```\n */\n\nexport const addSubDomainToDomain =\n (directory: string) => async (id: string, subDomain: { 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.domains === undefined) {\n domain.domains = [];\n }\n\n const subDomainExistsInList = domain.domains.some((s) => s.id === subDomain.id && s.version === subDomain.version);\n\n if (subDomainExistsInList) {\n return;\n }\n\n // Add service to the list\n domain.domains.push(subDomain);\n\n await rmDomainById(directory)(id, version, true);\n await writeDomain(directory)(domain, { format: extension === '.md' ? 'md' : 'mdx' });\n };\n\n/**\n * Add an entity to a domain by its id.\n * Optionally specify a version to add the entity to a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds an entity to the domain\n * const { addEntityToDomain } = utils('/path/to/eventcatalog');\n *\n * // Adds an entity (User) to the domain (Orders)\n * await addEntityToDomain('Orders', { id: 'User', version: '1.0.0' });\n * // Adds an entity (Product) to the domain (Orders) with a specific version\n * await addEntityToDomain('Orders', { id: 'Product', version: '2.0.0' }, '1.0.0');\n * ```\n */\nexport const addEntityToDomain =\n (directory: string) => async (id: string, entity: { 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.entities === undefined) {\n domain.entities = [];\n }\n\n const entityExistsInList = domain.entities.some((e) => e.id === entity.id && e.version === entity.version);\n\n if (entityExistsInList) {\n return;\n }\n\n // Add entity to the list\n domain.entities.push(entity);\n\n await rmDomainById(directory)(id, version, true);\n await writeDomain(directory)(domain, { format: extension === '.md' ? 'md' : 'mdx' });\n };\n\n/**\n * Add a data product to a domain by its id.\n * Optionally specify a version to add the data product to a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds a data product to the domain\n * const { addDataProductToDomain } = utils('/path/to/eventcatalog');\n *\n * // Adds a data product (CustomerDataProduct) to the domain (Orders)\n * await addDataProductToDomain('Orders', { id: 'CustomerDataProduct', version: '1.0.0' });\n * // Adds a data product (SalesDataProduct) to the domain (Orders) with a specific version\n * await addDataProductToDomain('Orders', { id: 'SalesDataProduct', version: '2.0.0' }, '1.0.0');\n * ```\n */\nexport const addDataProductToDomain =\n (directory: string) => async (id: string, dataProduct: { 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.dataProducts === undefined) {\n domain.dataProducts = [];\n }\n\n const dataProductExistsInList = domain.dataProducts.some(\n (dp) => dp.id === dataProduct.id && dp.version === dataProduct.version\n );\n\n if (dataProductExistsInList) {\n return;\n }\n\n // Add data product to the list\n domain.dataProducts.push(dataProduct);\n\n await rmDomainById(directory)(id, version, true);\n await writeDomain(directory)(domain, { format: extension === '.md' ? 'md' : 'mdx' });\n };\n\n/**\n * Add an event/command/query to a domain by its id.\n *\n * Optionally specify a version to add the message to a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds an event to the domain\n * const { addEventToDomain, addCommandToDomain, addQueryToDomain } = utils('/path/to/eventcatalog');\n *\n * // Adds a new event (OrderCreated) that the Orders domain will send\n * await addEventToDomain('Orders', 'sends', { id: 'OrderCreated', version: '2.0.0' });\n *\n * // Adds a new event (PaymentProcessed) that the Orders domain will receive\n * await addEventToDomain('Orders', 'receives', { id: 'PaymentProcessed', version: '1.0.0' });\n *\n * // Adds a new command (ProcessOrder) that the Orders domain will receive\n * await addCommandToDomain('Orders', 'receives', { id: 'ProcessOrder', version: '1.0.0' });\n *\n * // Adds a message to a specific version of the domain\n * await addEventToDomain('Orders', 'sends', { id: 'OrderShipped', version: '1.0.0' }, '2.0.0');\n * ```\n */\nexport const addMessageToDomain =\n (directory: string) => async (id: string, direction: string, message: { id: string; version: string }, version?: string) => {\n let domain: Domain = await getDomain(directory)(id, version);\n const domainPath = await getResourcePath(directory, id, version);\n const extension = path.extname(domainPath?.fullPath || '');\n\n if (direction === 'sends') {\n if (domain.sends === undefined) {\n domain.sends = [];\n }\n // Check if the message is already in the list\n for (let i = 0; i < domain.sends.length; i++) {\n if (domain.sends[i].id === message.id && domain.sends[i].version === message.version) {\n return;\n }\n }\n domain.sends.push({ id: message.id, version: message.version });\n } else if (direction === 'receives') {\n if (domain.receives === undefined) {\n domain.receives = [];\n }\n // Check if the message is already in the list\n for (let i = 0; i < domain.receives.length; i++) {\n if (domain.receives[i].id === message.id && domain.receives[i].version === message.version) {\n return;\n }\n }\n domain.receives.push({ id: message.id, version: message.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 domain ${id} in the catalog`);\n }\n\n // Get where the domain was located, make sure it goes back there (handles subdomains)\n // Use lastIndexOf to find the last /domains/ in the path (for nested domains)\n const normalizedPath = existingResource.replace(/\\\\/g, '/');\n const lastDomainsIndex = normalizedPath.lastIndexOf('/domains/');\n const pathToResource = existingResource.substring(0, lastDomainsIndex + '/domains'.length);\n\n await rmDomainById(directory)(id, version, true);\n await writeDomain(pathToResource)(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, invalidateFileCache } 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 invalidateFileCache();\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 { dirname, join } from 'node:path';\nimport fsSync from 'node:fs';\nimport type { Message, Service } from './types';\nimport matter from 'gray-matter';\nimport { getResource, getResourcePath, isLatestVersion } from './internal/resources';\nimport { findFileById, getFiles } from './internal/utils';\nimport { getServices } from './services';\nimport { satisfies, validRange } from 'semver';\n\n/**\n * Returns a message from EventCatalog by a given schema path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getMessageBySchemaPath } = utils('/path/to/eventcatalog');\n *\n * // Get the message by the schema path\n * const message = await getMessageBySchemaPath('/path/to/eventcatalog/messages/InventoryAdjusted/schema.json');\n * const message = await getMessageBySchemaPath('/path/to/eventcatalog/messages/InventoryAdjusted/schema.avro');\n * ```\n */\nexport const getMessageBySchemaPath =\n (directory: string) =>\n async (path: string, options?: { attachSchema?: boolean }): Promise<Message> => {\n const pathToMessage = dirname(path);\n try {\n const files = await getFiles(`${directory}/${pathToMessage}/index.{md,mdx}`);\n\n if (!files || files.length === 0) {\n throw new Error(`No message definition file (index.md or index.mdx) found in directory: ${pathToMessage}`);\n }\n const messageFile = files[0];\n\n const { data } = matter.read(messageFile);\n const { id, version } = data;\n\n if (!id || !version) {\n throw new Error(`Message definition file at ${messageFile} is missing 'id' or 'version' in its frontmatter.`);\n }\n\n const message = await getResource(directory, id, version, { type: 'message', ...options });\n\n if (!message) {\n throw new Error(`Message resource with id '${id}' and version '${version}' not found, as referenced in ${messageFile}.`);\n }\n return message as Message;\n } catch (error) {\n // console.error(`Failed to get message for schema path ${path}. Error processing directory ${pathToMessage}:`, error);\n if (error instanceof Error) {\n // Prepend more context to the existing error message\n error.message = `Failed to retrieve message from ${pathToMessage}: ${error.message}`;\n throw error;\n }\n throw new Error(`Failed to retrieve message from ${pathToMessage} due to an unknown error.`);\n }\n };\n\n/**\n * Returns the producers and consumers (services) for a given message.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getProducersAndConsumersForMessage } = utils('/path/to/eventcatalog');\n *\n * // Returns the producers and consumers (services) for a given message\n * const { producers, consumers } = await getProducersAndConsumersForMessage('InventoryAdjusted', '0.0.1');\n */\nexport const getProducersAndConsumersForMessage =\n (directory: string) =>\n async (\n id: string,\n version?: string,\n options?: { latestOnly?: boolean }\n ): Promise<{ producers: Service[]; consumers: Service[] }> => {\n const services = await getServices(directory)({ latestOnly: options?.latestOnly ?? true });\n const message = (await getResource(directory, id, version, { type: 'message' })) as Message;\n const isMessageLatestVersion = await isLatestVersion(directory, id, version);\n\n if (!message) {\n throw new Error(`Message resource with id '${id}' and version '${version}' not found.`);\n }\n\n const producers: Service[] = [];\n const consumers: Service[] = [];\n\n for (const service of services) {\n const servicePublishesMessage = service.sends?.some((_message) => {\n if (_message.version) {\n const isServiceUsingSemverRange = validRange(_message.version);\n if (isServiceUsingSemverRange) {\n return _message.id === message.id && satisfies(message.version, _message.version);\n } else {\n return _message.id === message.id && message.version === _message.version;\n }\n }\n if (isMessageLatestVersion && _message.id === message.id) {\n return true;\n }\n return false;\n });\n const serviceSubscribesToMessage = service.receives?.some((_message) => {\n if (_message.version) {\n const isServiceUsingSemverRange = validRange(_message.version);\n if (isServiceUsingSemverRange) {\n return _message.id === message.id && satisfies(message.version, _message.version);\n } else {\n return _message.id === message.id && message.version === _message.version;\n }\n }\n if (isMessageLatestVersion && _message.id === message.id) {\n return true;\n }\n return false;\n });\n\n if (servicePublishesMessage) {\n producers.push(service);\n }\n if (serviceSubscribesToMessage) {\n consumers.push(service);\n }\n }\n\n return { producers, consumers };\n };\n\n/**\n * Returns the consumers of a given schema path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getConsumersOfSchema } = utils('/path/to/eventcatalog');\n *\n * // Returns the consumers of a given schema path\n * const consumers = await getConsumersOfSchema('events/InventoryAdjusted/schema.json');\n */\nexport const getConsumersOfSchema = (directory: string) => async (path: string) => {\n try {\n const message = await getMessageBySchemaPath(directory)(path);\n const { consumers } = await getProducersAndConsumersForMessage(directory)(message.id, message.version);\n return consumers;\n } catch (error) {\n return [];\n }\n};\n\n/**\n * Returns the producers of a given schema path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getProducersOfSchema } = utils('/path/to/eventcatalog');\n *\n * // Returns the producers of a given schema path\n * const producers = await getProducersOfSchema('events/InventoryAdjusted/schema.json');\n */\nexport const getProducersOfSchema = (directory: string) => async (path: string) => {\n try {\n const message = await getMessageBySchemaPath(directory)(path);\n const { producers } = await getProducersAndConsumersForMessage(directory)(message.id, message.version);\n return producers;\n } catch (error) {\n return [];\n }\n};\n\n/**\n * Returns the schema for a given message (event, command or query) by its id and version.\n *\n * If no version is given, the latest version is used.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getSchemaForMessage } = utils('/path/to/eventcatalog');\n *\n * // Get the schema for the latest version of the message\n * const schema = await getSchemaForMessage('InventoryAdjusted');\n *\n * // Get the schema for a specific version\n * const schema = await getSchemaForMessage('InventoryAdjusted', '0.0.1');\n * ```\n */\nexport const getSchemaForMessage =\n (directory: string) =>\n async (id: string, version?: string): Promise<{ schema: string; fileName: string } | undefined> => {\n const file = await findFileById(directory, id, version);\n if (!file || !fsSync.existsSync(file)) return undefined;\n\n const { data } = matter.read(file);\n\n if (!data.schemaPath) return undefined;\n\n const resourceDirectory = dirname(file);\n const pathToSchema = join(resourceDirectory, data.schemaPath);\n\n if (!fsSync.existsSync(pathToSchema)) return undefined;\n\n const schema = fsSync.readFileSync(pathToSchema, 'utf8');\n\n return {\n schema,\n fileName: data.schemaPath,\n };\n };\n","import path, { join } from 'node:path';\nimport { invalidateFileCache, 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 invalidateFileCache();\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 invalidateFileCache();\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, invalidateFileCache } from './internal/utils';\nimport { getResource } from './internal/resources';\nimport path from 'node:path';\nimport { getUser, getUsers } from './users';\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}/*.{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 invalidateFileCache();\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 invalidateFileCache();\n};\n\n/**\n * Returns the owners for a given resource (e.g domain, service, event, command, query, etc.)\n * @param id - The id of the resource to get the owners for\n * @param version - Optional version of the resource\n * @returns { owners: User[] }\n */\nexport const getOwnersForResource = (catalogDir: string) => async (id: string, version?: string) => {\n const resource = await getResource(catalogDir, id, version);\n let owners: Team[] = [];\n if (!resource) return [];\n\n if (!resource.owners) return [];\n\n // First check if the owner is a team\n for (const owner of resource.owners) {\n const team = await getTeam(path.join(catalogDir, 'teams'))(owner);\n if (team) {\n owners.push(team);\n } else {\n // If the owner is not a team, check if it's a user\n const user = await getUser(path.join(catalogDir, 'users'))(owner);\n if (user) {\n owners.push(user);\n }\n }\n }\n\n return owners;\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, invalidateFileCache } 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 invalidateFileCache();\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 invalidateFileCache();\n};\n","import type { EventCatalog } from './types';\nimport fs from 'fs';\nimport path, { join } from 'node:path';\nimport utils from './index';\nimport { getResourcePath } from './internal/resources';\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/**\n * Returns the event catalog configuration file.\n * The event catalog configuration file is the file that contains the configuration for the event catalog.\n *\n * @param directory - The directory of the catalog.\n * @returns A JSON object with the configuration for the event catalog.\n */\nexport const getEventCatalogConfigurationFile = (directory: string) => async (): Promise<any> => {\n // Read package.json in the catalogDir\n try {\n const path = join(directory, 'eventcatalog.config.js');\n // Dynamically import the ES module\n const configModule = await import(path);\n return configModule.default;\n } catch (error) {\n console.error('Error getting event catalog configuration file', error);\n return null;\n }\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<EventCatalog> => {\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 fs from 'node:fs';\nimport path from 'node:path';\nimport { execSync } from 'node:child_process';\nimport { compare } from 'semver';\nimport type { CatalogSnapshot, SnapshotOptions, SnapshotResult, SnapshotMeta, SnapshotDiff } from './snapshot-types';\nimport utils from './index';\nimport { computeResourceDiff, computeRelationshipDiff } from './snapshot-diff';\n\nconst SNAPSHOT_VERSION = '1.0.0';\n\nconst getEventCatalogVersion = (catalogDir: string): string => {\n try {\n const packageJson = fs.readFileSync(path.join(catalogDir, 'package.json'), 'utf8');\n const packageJsonObject = JSON.parse(packageJson);\n return packageJsonObject['dependencies']?.['@eventcatalog/core'] ?? 'unknown';\n } catch {\n return 'unknown';\n }\n};\n\nconst pickCoreFields = (resource: any): any => {\n const picked: any = { id: resource.id, version: resource.version, name: resource.name };\n if (resource.sends) picked.sends = resource.sends;\n if (resource.receives) picked.receives = resource.receives;\n if (resource.deprecated) picked.deprecated = resource.deprecated;\n if (resource.owners) picked.owners = resource.owners;\n return picked;\n};\n\nconst deduplicateByLatestVersion = (resources: any[]): any[] => {\n const seen = new Map<string, any>();\n for (const r of resources) {\n const existing = seen.get(r.id);\n if (!existing || compare(r.version, existing.version) > 0) {\n seen.set(r.id, r);\n }\n }\n return Array.from(seen.values());\n};\n\nconst stripToCore = (resources: any[] | undefined): any[] => {\n if (!resources || resources.length === 0) return [];\n return deduplicateByLatestVersion(resources).map(pickCoreFields);\n};\n\nconst detectGitInfo = (catalogDir: string): { branch: string; commit: string; dirty: boolean } | undefined => {\n try {\n const opts = { cwd: catalogDir, encoding: 'utf8' as const, stdio: 'pipe' as const };\n const branch = execSync('git rev-parse --abbrev-ref HEAD', opts).trim();\n const commit = execSync('git rev-parse --short HEAD', opts).trim();\n const status = execSync('git status --porcelain', opts).trim();\n return { branch, commit, dirty: status.length > 0 };\n } catch {\n return undefined;\n }\n};\n\nexport const createSnapshot = (directory: string) => {\n // Note: sdk is created lazily inside the inner function to avoid circular\n // dependency issues (index.ts imports snapshots.ts and vice versa).\n return async (options?: SnapshotOptions): Promise<SnapshotResult> => {\n const { label, outputDir, git } = options || {};\n const sdk = utils(directory);\n\n // Fetch all resources in parallel\n const [domains, services, events, commands, queries, channels] = await Promise.all([\n sdk.getDomains(),\n sdk.getServices(),\n sdk.getEvents(),\n sdk.getCommands(),\n sdk.getQueries(),\n sdk.getChannels(),\n ]);\n\n // Strip to core fields only (id, version, name, sends, receives, deprecated)\n const snapshotDomains = stripToCore(domains);\n const snapshotServices = stripToCore(services);\n const snapshotEvents = stripToCore(events);\n const snapshotCommands = stripToCore(commands);\n const snapshotQueries = stripToCore(queries);\n const snapshotChannels = stripToCore(channels);\n\n const snapshotLabel = label || new Date().toISOString().replace(/[:.]/g, '-');\n const gitInfo = git || detectGitInfo(directory);\n\n const snapshot: CatalogSnapshot = {\n snapshotVersion: SNAPSHOT_VERSION,\n catalogVersion: getEventCatalogVersion(directory),\n label: snapshotLabel,\n createdAt: new Date().toISOString(),\n ...(gitInfo ? { git: gitInfo } : {}),\n resources: {\n domains: snapshotDomains,\n services: snapshotServices,\n messages: {\n events: snapshotEvents,\n commands: snapshotCommands,\n queries: snapshotQueries,\n },\n channels: snapshotChannels,\n },\n };\n\n // Write to disk\n const snapshotsDir = outputDir || path.join(directory, '.snapshots');\n fs.mkdirSync(snapshotsDir, { recursive: true });\n const fileName = `${snapshotLabel}.snapshot.json`;\n const filePath = path.join(snapshotsDir, fileName);\n fs.writeFileSync(filePath, JSON.stringify(snapshot));\n\n return { filePath, snapshot };\n };\n};\n\nexport const diffSnapshots =\n (directory: string) =>\n async (snapshotAPath: string, snapshotBPath: string): Promise<SnapshotDiff> => {\n const snapshotA: CatalogSnapshot = JSON.parse(fs.readFileSync(snapshotAPath, 'utf-8'));\n const snapshotB: CatalogSnapshot = JSON.parse(fs.readFileSync(snapshotBPath, 'utf-8'));\n\n const resourceChanges = computeResourceDiff(snapshotA, snapshotB);\n const relationshipChanges = computeRelationshipDiff(snapshotA, snapshotB);\n\n const resourceCounts = { added: 0, removed: 0, modified: 0, versioned: 0 };\n for (const r of resourceChanges) resourceCounts[r.changeType]++;\n const relCounts = { added: 0, removed: 0 };\n for (const r of relationshipChanges) relCounts[r.changeType]++;\n\n return {\n snapshotA: { label: snapshotA.label, createdAt: snapshotA.createdAt },\n snapshotB: { label: snapshotB.label, createdAt: snapshotB.createdAt },\n summary: {\n totalChanges: resourceChanges.length + relationshipChanges.length,\n resourcesAdded: resourceCounts.added,\n resourcesRemoved: resourceCounts.removed,\n resourcesModified: resourceCounts.modified,\n resourcesVersioned: resourceCounts.versioned,\n relationshipsAdded: relCounts.added,\n relationshipsRemoved: relCounts.removed,\n },\n resources: resourceChanges,\n relationships: relationshipChanges,\n };\n };\n\nexport const listSnapshots = (directory: string) => async (): Promise<SnapshotMeta[]> => {\n const snapshotsDir = path.join(directory, '.snapshots');\n if (!fs.existsSync(snapshotsDir)) return [];\n\n const files = fs.readdirSync(snapshotsDir).filter((f) => f.endsWith('.snapshot.json'));\n const snapshots: SnapshotMeta[] = [];\n\n for (const file of files) {\n try {\n const filePath = path.join(snapshotsDir, file);\n const content: CatalogSnapshot = JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n snapshots.push({\n label: content.label,\n createdAt: content.createdAt,\n filePath,\n ...(content.git ? { git: content.git } : {}),\n });\n } catch {\n // skip invalid files\n }\n }\n\n return snapshots.sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n};\n","import type { CatalogSnapshot, ResourceChange, SnapshotResourceType, RelationshipChange } from './snapshot-types';\n\n/**\n * Stable JSON stringify with sorted keys for deep comparison.\n * Recurses into nested objects and arrays to ensure key order doesn't affect output.\n */\nconst stableStringify = (value: unknown): string => {\n if (value === null || value === undefined || typeof value !== 'object') {\n return JSON.stringify(value);\n }\n if (Array.isArray(value)) {\n return '[' + value.map(stableStringify).join(',') + ']';\n }\n const sorted = Object.keys(value as Record<string, unknown>)\n .sort()\n .map((key) => JSON.stringify(key) + ':' + stableStringify((value as Record<string, unknown>)[key]));\n return '{' + sorted.join(',') + '}';\n};\n\ntype FlatResource = {\n resourceId: string;\n version: string;\n type: SnapshotResourceType;\n data: Record<string, unknown>;\n};\n\nconst flattenResources = (snapshot: CatalogSnapshot): FlatResource[] => {\n const resources: FlatResource[] = [];\n\n const addResources = (items: Record<string, unknown>[], type: SnapshotResourceType) => {\n for (const item of items) {\n resources.push({\n resourceId: item.id as string,\n version: item.version as string,\n type,\n data: item,\n });\n }\n };\n\n addResources(snapshot.resources.domains, 'domain');\n addResources(snapshot.resources.services, 'service');\n addResources(snapshot.resources.messages.events, 'event');\n addResources(snapshot.resources.messages.commands, 'command');\n addResources(snapshot.resources.messages.queries, 'query');\n addResources(snapshot.resources.channels, 'channel');\n\n return resources;\n};\n\n// Fields to exclude from comparison\nconst EXCLUDED_FIELDS = new Set(['markdown', '_eventcatalog']);\n\nconst getComparableFields = (data: Record<string, unknown>): Record<string, unknown> => {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (!EXCLUDED_FIELDS.has(key)) {\n result[key] = value;\n }\n }\n return result;\n};\n\nconst findChangedFields = (dataA: Record<string, unknown>, dataB: Record<string, unknown>): string[] => {\n const fieldsA = getComparableFields(dataA);\n const fieldsB = getComparableFields(dataB);\n const allKeys = new Set([...Object.keys(fieldsA), ...Object.keys(fieldsB)]);\n const changed: string[] = [];\n\n for (const key of allKeys) {\n if (stableStringify(fieldsA[key] ?? null) !== stableStringify(fieldsB[key] ?? null)) {\n changed.push(key);\n }\n }\n\n return changed;\n};\n\nconst resourceKey = (r: FlatResource): string => `${r.resourceId}@${r.version}`;\nconst idTypeKey = (r: FlatResource): string => `${r.resourceId}:${r.type}`;\n\nexport const computeResourceDiff = (snapshotA: CatalogSnapshot, snapshotB: CatalogSnapshot): ResourceChange[] => {\n const resourcesA = flattenResources(snapshotA);\n const resourcesB = flattenResources(snapshotB);\n\n // Build both maps in a single pass per array\n const mapA = new Map<string, FlatResource>();\n const byIdA = new Map<string, FlatResource>();\n for (const r of resourcesA) {\n mapA.set(resourceKey(r), r);\n byIdA.set(idTypeKey(r), r);\n }\n\n const mapB = new Map<string, FlatResource>();\n const byIdB = new Map<string, FlatResource>();\n for (const r of resourcesB) {\n mapB.set(resourceKey(r), r);\n byIdB.set(idTypeKey(r), r);\n }\n\n const changes: ResourceChange[] = [];\n const handledIds = new Set<string>();\n\n // Find added resources (in B but not A)\n for (const resource of resourcesB) {\n const key = resourceKey(resource);\n if (!mapA.has(key)) {\n const idKey = idTypeKey(resource);\n const oldResource = byIdA.get(idKey);\n if (oldResource && oldResource.version !== resource.version && !handledIds.has(idKey)) {\n // Version bump: same id, different version\n const changedFields = findChangedFields(oldResource.data, resource.data);\n changes.push({\n resourceId: resource.resourceId,\n version: resource.version,\n type: resource.type,\n changeType: 'versioned',\n previousVersion: oldResource.version,\n newVersion: resource.version,\n changedFields: changedFields.length > 0 ? changedFields : undefined,\n });\n handledIds.add(idKey);\n } else if (!handledIds.has(idKey)) {\n changes.push({\n resourceId: resource.resourceId,\n version: resource.version,\n type: resource.type,\n changeType: 'added',\n });\n }\n }\n }\n\n // Find removed resources (in A but not B)\n for (const resource of resourcesA) {\n const key = resourceKey(resource);\n if (!mapB.has(key)) {\n const idKey = idTypeKey(resource);\n if (!handledIds.has(idKey)) {\n changes.push({\n resourceId: resource.resourceId,\n version: resource.version,\n type: resource.type,\n changeType: 'removed',\n });\n }\n }\n }\n\n // Find modified resources (in both, but fields differ)\n for (const resourceB of resourcesB) {\n const key = resourceKey(resourceB);\n const resourceA = mapA.get(key);\n if (resourceA) {\n const changedFields = findChangedFields(resourceA.data, resourceB.data);\n if (changedFields.length > 0) {\n changes.push({\n resourceId: resourceB.resourceId,\n version: resourceB.version,\n type: resourceB.type,\n changeType: 'modified',\n changedFields,\n });\n }\n }\n }\n\n return changes;\n};\n\ntype ServicePointer = { id: string; version?: string };\n\nconst getRelationshipKey = (\n serviceId: string,\n resourceId: string,\n resourceVersion: string | undefined,\n direction: string\n): string => {\n return `${serviceId}:${direction}:${resourceId}@${resourceVersion || 'latest'}`;\n};\n\ntype RelationshipInfo = Omit<RelationshipChange, 'changeType'>;\n\nconst extractRelationships = (snapshot: CatalogSnapshot): Map<string, RelationshipInfo> => {\n const relationships = new Map<string, RelationshipInfo>();\n\n for (const service of snapshot.resources.services) {\n for (const direction of ['sends', 'receives'] as const) {\n const pointers: ServicePointer[] = (service as Record<string, any>)[direction] || [];\n for (const pointer of pointers) {\n const key = getRelationshipKey(service.id as string, pointer.id, pointer.version, direction);\n relationships.set(key, {\n serviceId: service.id as string,\n serviceVersion: service.version as string,\n resourceId: pointer.id,\n resourceVersion: pointer.version,\n direction,\n });\n }\n }\n }\n\n return relationships;\n};\n\nexport const computeRelationshipDiff = (snapshotA: CatalogSnapshot, snapshotB: CatalogSnapshot): RelationshipChange[] => {\n const relsA = extractRelationships(snapshotA);\n const relsB = extractRelationships(snapshotB);\n\n const changes: RelationshipChange[] = [];\n\n // Relationships in B but not in A = added\n for (const [key, rel] of relsB) {\n if (!relsA.has(key)) {\n changes.push({ ...rel, changeType: 'added' });\n }\n }\n\n // Relationships in A but not in B = removed\n for (const [key, rel] of relsA) {\n if (!relsB.has(key)) {\n changes.push({ ...rel, changeType: 'removed' });\n }\n }\n\n return changes;\n};\n","import path, { dirname } from 'node:path';\nimport fsSync from 'node:fs';\nimport fs from 'node:fs/promises';\nimport matter from 'gray-matter';\nimport { findFileById, invalidateFileCache } from './internal/utils';\nimport type { Changelog } from './types';\n\n/**\n * Writes a changelog entry to a resource in EventCatalog.\n *\n * The changelog file (`changelog.mdx`) is written to the same directory as the resource's `index.mdx`.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeChangelog } = utils('/path/to/eventcatalog');\n *\n * // Write a changelog to a resource\n * await writeChangelog('OrderCreated', {\n * createdAt: '2024-08-01',\n * markdown: '### Added support for JSON Schema\\n\\nOrderCreated now supports JSON Draft 7.',\n * badges: [{ content: '⭐️ JSON Schema', backgroundColor: 'purple', textColor: 'purple' }],\n * });\n *\n * // Write a changelog to a specific version\n * await writeChangelog('OrderCreated', {\n * createdAt: '2024-08-01',\n * markdown: '### Breaking change\\n\\nRemoved `gender` field from schema.',\n * }, { version: '1.0.0' });\n * ```\n */\nexport const writeChangelog =\n (catalogDir: string) =>\n async (id: string, changelog: Changelog, options: { version?: string; format?: 'md' | 'mdx' } = {}): Promise<void> => {\n const { version, format = 'mdx' } = options;\n\n const resourceFile = await findFileById(catalogDir, id, version);\n if (!resourceFile) {\n throw new Error(`No resource found with id: ${id}${version ? ` and version: ${version}` : ''}`);\n }\n\n const resourceDir = dirname(resourceFile);\n const changelogPath = path.join(resourceDir, `changelog.${format}`);\n\n const { markdown, ...frontmatter } = changelog;\n\n // Ensure createdAt is serialized correctly for gray-matter\n const fm: Record<string, any> = { ...frontmatter };\n if (fm.createdAt instanceof Date) {\n fm.createdAt = fm.createdAt;\n }\n\n // Remove undefined/empty values from frontmatter\n if (!fm.badges || fm.badges.length === 0) {\n delete fm.badges;\n }\n\n fsSync.mkdirSync(resourceDir, { recursive: true });\n const document = matter.stringify(markdown.trim(), fm);\n fsSync.writeFileSync(changelogPath, document);\n invalidateFileCache();\n };\n\n/**\n * Appends a changelog entry to an existing changelog for a resource.\n * If no changelog exists, one is created.\n *\n * New entries are prepended to the top of the existing content, separated by `---`.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { appendChangelog } = utils('/path/to/eventcatalog');\n *\n * // Append to an existing changelog (or create if none exists)\n * await appendChangelog('OrderCreated', {\n * createdAt: '2024-09-01',\n * markdown: '### New field added\\n\\nAdded `priority` field.',\n * });\n *\n * // Append to a specific version's changelog\n * await appendChangelog('OrderCreated', {\n * createdAt: '2024-09-01',\n * markdown: '### Bugfix\\n\\nFixed validation.',\n * }, { version: '1.0.0' });\n * ```\n */\nexport const appendChangelog =\n (catalogDir: string) =>\n async (id: string, changelog: Changelog, options: { version?: string; format?: 'md' | 'mdx' } = {}): Promise<void> => {\n const { version, format = 'mdx' } = options;\n\n const resourceFile = await findFileById(catalogDir, id, version);\n if (!resourceFile) {\n throw new Error(`No resource found with id: ${id}${version ? ` and version: ${version}` : ''}`);\n }\n\n const resourceDir = dirname(resourceFile);\n\n // Find existing changelog file\n const mdxPath = path.join(resourceDir, 'changelog.mdx');\n const mdPath = path.join(resourceDir, 'changelog.md');\n const existingPath = fsSync.existsSync(mdxPath) ? mdxPath : fsSync.existsSync(mdPath) ? mdPath : undefined;\n\n if (!existingPath) {\n // No existing changelog — delegate to writeChangelog\n return writeChangelog(catalogDir)(id, changelog, options);\n }\n\n const existing = matter.read(existingPath);\n const existingContent = existing.content.trim();\n\n // Build the new entry markdown\n const newEntry = changelog.markdown.trim();\n\n // Prepend new entry, separated by ---\n const combined = `${newEntry}\\n\\n---\\n\\n${existingContent}`;\n\n // Merge frontmatter: use the new createdAt, merge badges\n const fm: Record<string, any> = { ...existing.data };\n fm.createdAt = changelog.createdAt;\n\n if (changelog.badges && changelog.badges.length > 0) {\n fm.badges = changelog.badges;\n } else {\n delete fm.badges;\n }\n\n const document = matter.stringify(combined, fm);\n fsSync.writeFileSync(existingPath, document);\n invalidateFileCache();\n };\n\n/**\n * Returns the changelog for a resource in EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getChangelog } = utils('/path/to/eventcatalog');\n *\n * // Get the changelog for a resource\n * const changelog = await getChangelog('OrderCreated');\n *\n * // Get the changelog for a specific version\n * const changelog = await getChangelog('OrderCreated', { version: '1.0.0' });\n * ```\n */\nexport const getChangelog =\n (catalogDir: string) =>\n async (id: string, options: { version?: string } = {}): Promise<Changelog | undefined> => {\n const { version } = options;\n\n const resourceFile = await findFileById(catalogDir, id, version);\n if (!resourceFile) return undefined;\n\n const resourceDir = dirname(resourceFile);\n\n // Try .mdx first, then .md\n const mdxPath = path.join(resourceDir, 'changelog.mdx');\n const mdPath = path.join(resourceDir, 'changelog.md');\n\n const changelogPath = fsSync.existsSync(mdxPath) ? mdxPath : fsSync.existsSync(mdPath) ? mdPath : undefined;\n\n if (!changelogPath) return undefined;\n\n const { data, content } = matter.read(changelogPath);\n return { ...data, markdown: content.trim() } as Changelog;\n };\n\n/**\n * Removes the changelog for a resource in EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmChangelog } = utils('/path/to/eventcatalog');\n *\n * // Remove the changelog for a resource\n * await rmChangelog('OrderCreated');\n *\n * // Remove the changelog for a specific version\n * await rmChangelog('OrderCreated', { version: '1.0.0' });\n * ```\n */\nexport const rmChangelog =\n (catalogDir: string) =>\n async (id: string, options: { version?: string } = {}): Promise<void> => {\n const { version } = options;\n\n const resourceFile = await findFileById(catalogDir, id, version);\n if (!resourceFile) {\n throw new Error(`No resource found with id: ${id}${version ? ` and version: ${version}` : ''}`);\n }\n\n const resourceDir = dirname(resourceFile);\n\n const mdxPath = path.join(resourceDir, 'changelog.mdx');\n const mdPath = path.join(resourceDir, 'changelog.md');\n\n if (fsSync.existsSync(mdxPath)) {\n await fs.rm(mdxPath);\n }\n if (fsSync.existsSync(mdPath)) {\n await fs.rm(mdPath);\n }\n\n invalidateFileCache();\n };\n","import fs from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { findFileById, invalidateFileCache } from './internal/utils';\nimport type { Entity } from './types';\nimport { getResource, getResources, rmResourceById, versionResource, writeResource } from './internal/resources';\n\n/**\n * Returns an entity from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the entity\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getEntity } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the entity\n * const entity = await getEntity('User');\n *\n * // Gets a version of the entity\n * const entity = await getEntity('User', '0.0.1');\n *\n * ```\n */\nexport const getEntity =\n (directory: string) =>\n async (id: string, version?: string): Promise<Entity> =>\n getResource(directory, id, version, { type: 'entity' }) as Promise<Entity>;\n\n/**\n * Returns all entities from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the entities.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getEntities } = utils('/path/to/eventcatalog');\n *\n * // Gets all entities (and versions) from the catalog\n * const entities = await getEntities();\n *\n * // Gets all entities (only latest version) from the catalog\n * const entities = await getEntities({ latestOnly: true });\n *\n * ```\n */\nexport const getEntities =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Entity[]> =>\n getResources(directory, { type: 'entities', latestOnly: options?.latestOnly }) as Promise<Entity[]>;\n\n/**\n * Write an entity to EventCatalog.\n *\n * You can optionally override the path of the entity.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeEntity } = utils('/path/to/eventcatalog');\n *\n * // Write an entity to the catalog\n * // Entity would be written to entities/User\n * await writeEntity({\n * id: 'User',\n * name: 'User',\n * version: '0.0.1',\n * summary: 'User entity',\n * markdown: '# User entity',\n * });\n *\n * // Write an entity to the catalog but override the path\n * // Entity would be written to entities/Account/User\n * await writeEntity({\n * id: 'User',\n * name: 'User',\n * version: '0.0.1',\n * summary: 'User entity',\n * markdown: '# User entity',\n * }, { path: \"/Account/User\"});\n *\n * // Write an entity to the catalog and override the existing content (if there is any)\n * await writeEntity({\n * id: 'User',\n * name: 'User',\n * version: '0.0.1',\n * summary: 'User entity',\n * markdown: '# User entity',\n * }, { override: true });\n *\n * // Write an entity to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeEntity({\n * id: 'User',\n * name: 'User',\n * version: '0.0.1',\n * summary: 'User entity',\n * markdown: '# User entity',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeEntity =\n (directory: string) =>\n async (\n entity: Entity,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...entity }, { ...options, type: 'entity' });\n\n/**\n * Delete an entity at its given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmEntity } = utils('/path/to/eventcatalog');\n *\n * // removes an entity at the given path (entities dir is appended to the given path)\n * // Removes the entity at entities/User\n * await rmEntity('/User');\n * ```\n */\nexport const rmEntity = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n invalidateFileCache();\n};\n\n/**\n * Delete an entity by its id.\n *\n * Optionally specify a version to delete a specific version of the entity.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmEntityById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest User entity\n * await rmEntityById('User');\n *\n * // deletes a specific version of the User entity\n * await rmEntityById('User', '0.0.1');\n * ```\n */\nexport const rmEntityById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) => {\n await rmResourceById(directory, id, version, { type: 'entity', persistFiles });\n};\n\n/**\n * Version an entity by its id.\n *\n * Takes the latest entity and moves it to a versioned directory.\n * All files with this entity are also versioned (e.g /entities/User/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionEntity } = utils('/path/to/eventcatalog');\n *\n * // moves the latest User entity to a versioned directory\n * // the version within that entity is used as the version number.\n * await versionEntity('User');\n *\n * ```\n */\nexport const versionEntity = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Check to see if the catalog has a version for the given entity.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { entityHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given entity and version (supports semver)\n * await entityHasVersion('User', '0.0.1');\n * await entityHasVersion('User', 'latest');\n * await entityHasVersion('User', '0.0.x');\n *\n * ```\n */\nexport const entityHasVersion = (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, invalidateFileCache } from './internal/utils';\nimport type { Container } 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 container (e.g. data store) from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the container\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getContainer } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the container\n * const container = await getContainer('User');\n *\n * // Gets a version of the entity\n * const container = await getContainer('User', '0.0.1');\n *\n * ```\n */\nexport const getContainer =\n (directory: string) =>\n async (id: string, version?: string): Promise<Container> =>\n getResource(directory, id, version, { type: 'container' }) as Promise<Container>;\n\n/**\n * Returns all containers (e.g. data stores) from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the containers.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getContainers } = utils('/path/to/eventcatalog');\n *\n * // Gets all containers (and versions) from the catalog\n * const containers = await getContainers();\n *\n * // Gets all entities (only latest version) from the catalog\n * const containers = await getContainers({ latestOnly: true });\n *\n * ```\n */\nexport const getContainers =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Container[]> =>\n getResources(directory, { type: 'containers', latestOnly: options?.latestOnly }) as Promise<Container[]>;\n\n/**\n * Write a container (e.g. data store) to EventCatalog.\n */\nexport const writeContainer =\n (directory: string) =>\n async (\n data: Container,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...data }, { ...options, type: 'container' });\n\n/**\n * Version an container (e.g. data store) by its id.\n *\n * Takes the latest container and moves it to a versioned directory.\n * All files with this container are also versioned (e.g /containers/orders-db/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionContainer } = utils('/path/to/eventcatalog');\n *\n * // moves the latest orders-db container to a versioned directory\n * // the version within that container is used as the version number.\n * await versionContainer('orders-db');\n *\n * ```\n */\nexport const versionContainer = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Delete an container (e.g. data store) at its given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmContainer } = utils('/path/to/eventcatalog');\n *\n * // removes an container at the given path (containers dir is appended to the given path)\n * // Removes the container at containers/orders-db\n * await rmContainer('/orders-db');\n * ```\n */\nexport const rmContainer = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n invalidateFileCache();\n};\n\n/**\n * Delete an container (e.g. data store) by its id.\n *\n * Optionally specify a version to delete a specific version of the container.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmContainerById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest orders-db container\n * await rmContainerById('orders-db');\n *\n * // deletes a specific version of the orders-db container\n * await rmContainerById('orders-db', '0.0.1');\n * ```\n */\nexport const rmContainerById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) => {\n await rmResourceById(directory, id, version, { type: 'container', persistFiles });\n};\n\n/**\n * Check to see if the catalog has a version for the given container (e.g. data store).\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { containerHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given entity and version (supports semver)\n * await containerHasVersion('orders-db', '0.0.1');\n * await containerHasVersion('orders-db', 'latest');\n * await containerHasVersion('orders-db', '0.0.x');\n *\n * ```\n */\nexport const containerHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n\n/**\n * Add a file to a container (e.g. data store) by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the container.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToContainer } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest InventoryAdjusted event\n * await addFileToContainer('InventoryAdjusted', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the InventoryAdjusted event\n * await addFileToContainer('InventoryAdjusted', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToContainer =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Write an data store (e.g. data store) to a service in EventCatalog.\n *\n * You can optionally override the path of the data store.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeContainerToService } = utils('/path/to/eventcatalog');\n *\n * // Write a container to a given service in the catalog\n * // Container would be written to services/Inventory/containers/orders-db\n * await writeContainerToService({\n * id: 'orders-db',\n * name: 'Orders DB',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * container_type: 'database',\n * }, { id: 'Inventory' });\n * ```\n */\nexport const writeContainerToService =\n (directory: string) =>\n async (\n container: Container,\n service: { id: string; version?: string },\n options: { path?: string; format?: 'md' | 'mdx'; override?: boolean } = { path: '', format: 'mdx', override: false }\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 pathForContainer =\n service.version && service.version !== 'latest'\n ? `${resourcePath.directory}/versioned/${service.version}/containers`\n : `${resourcePath.directory}/containers`;\n pathForContainer = join(pathForContainer, container.id);\n await writeResource(directory, { ...container }, { ...options, path: pathForContainer, type: 'container' });\n };\n","import * as Containers from './containers';\n\n/**\n * Returns a data store (e.g. database, cache, etc.) from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the data store\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getContainer } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the data store\n * const container = await getDataStore('orders-db');\n *\n * // Gets a version of the entity\n * const container = await getDataStore('orders-db', '0.0.1');\n *\n * ```\n */\nexport const getDataStore = Containers.getContainer;\n\n/**\n * Returns all data stores (e.g. databases, caches, etc.) from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the data stores.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getDataStores } = utils('/path/to/eventcatalog');\n *\n * // Gets all data stores (and versions) from the catalog\n * const containers = await getDataStores();\n *\n * // Gets all data stores (only latest version) from the catalog\n * const containers = await getDataStores({ latestOnly: true });\n *\n * ```\n */\nexport const getDataStores = Containers.getContainers;\n\n/**\n * Write a data store (e.g. database, cache, etc.) to EventCatalog.\n */\nexport const writeDataStore = Containers.writeContainer;\n\n/**\n * Version an data store (e.g. database, cache, etc.) by its id.\n *\n * Takes the latest data store and moves it to a versioned directory.\n * All files with this data store are also versioned (e.g /containers/orders-db/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionDataStore } = utils('/path/to/eventcatalog');\n *\n * // moves the latest orders-db data store to a versioned directory\n * // the version within that data store is used as the version number.\n * await versionDataStore('orders-db');\n *\n * ```\n */\nexport const versionDataStore = Containers.versionContainer;\n\n/**\n * Delete an data store (e.g. database, cache, etc.) at its given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDataStore } = utils('/path/to/eventcatalog');\n *\n * // removes an data store at the given path (containers dir is appended to the given path)\n * // Removes the data store at containers/orders-db\n * await rmDataStore('/orders-db');\n * ```\n */\nexport const rmDataStore = Containers.rmContainer;\n\n/**\n * Delete an data store (e.g. database, cache, etc.) by its id.\n *\n * Optionally specify a version to delete a specific version of the data store.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDataStoreById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest orders-db data store\n * await rmDataStoreById('orders-db');\n *\n * // deletes a specific version of the orders-db data store\n * await rmDataStoreById('orders-db', '0.0.1');\n * ```\n */\nexport const rmDataStoreById = Containers.rmContainerById;\n\n/**\n * Check to see if the catalog has a version for the given data store (e.g. database, cache, etc.).\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { dataStoreHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given data store and version (supports semver)\n * await dataStoreHasVersion('orders-db', '0.0.1');\n * await dataStoreHasVersion('orders-db', 'latest');\n * await dataStoreHasVersion('orders-db', '0.0.x');\n *\n * ```\n */\nexport const dataStoreHasVersion = Containers.containerHasVersion;\n\n/**\n * Add a file to a data store (e.g. database, cache, etc.) by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the data store.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToDataStore } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest InventoryAdjusted data store\n * await addFileToDataStore('InventoryAdjusted', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the InventoryAdjusted data store\n * await addFileToDataStore('InventoryAdjusted', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToDataStore = Containers.addFileToContainer;\n\n/**\n * Write an data store (e.g. database, cache, etc.) to a service in EventCatalog.\n *\n * You can optionally override the path of the data store.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeDataStoreToService } = utils('/path/to/eventcatalog');\n *\n * // Write a data store to a given service in the catalog\n * // Data store would be written to services/Inventory/containers/orders-db\n * await writeDataStoreToService({\n * id: 'orders-db',\n * name: 'Orders DB',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * container_type: 'database',\n * }, { id: 'Inventory' });\n * ```\n */\nexport const writeDataStoreToService = Containers.writeContainerToService;\n","import fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { findFileById, invalidateFileCache } from './internal/utils';\nimport type { DataProduct } from './types';\nimport {\n addFileToResource,\n getResource,\n getResources,\n rmResourceById,\n versionResource,\n writeResource,\n} from './internal/resources';\n\n/**\n * Returns a data product from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the data product\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getDataProduct } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the data product\n * const dataProduct = await getDataProduct('CustomerDataProduct');\n *\n * // Gets a version of the data product\n * const dataProduct = await getDataProduct('CustomerDataProduct', '0.0.1');\n *\n * ```\n */\nexport const getDataProduct =\n (directory: string) =>\n async (id: string, version?: string): Promise<DataProduct> =>\n getResource(directory, id, version, { type: 'data-product' }) as Promise<DataProduct>;\n\n/**\n * Returns all data products from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the data products.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getDataProducts } = utils('/path/to/eventcatalog');\n *\n * // Gets all data products (and versions) from the catalog\n * const dataProducts = await getDataProducts();\n *\n * // Gets all data products (only latest version) from the catalog\n * const dataProducts = await getDataProducts({ latestOnly: true });\n *\n * ```\n */\nexport const getDataProducts =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<DataProduct[]> =>\n getResources(directory, { type: 'data-products', latestOnly: options?.latestOnly }) as Promise<DataProduct[]>;\n\n/**\n * Write a data product to EventCatalog.\n *\n * You can optionally override the path of the data product.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeDataProduct } = utils('/path/to/eventcatalog');\n *\n * // Write a data product to the catalog\n * // Data product would be written to data-products/CustomerDataProduct\n * await writeDataProduct({\n * id: 'CustomerDataProduct',\n * name: 'Customer Data Product',\n * version: '0.0.1',\n * summary: 'Customer data product',\n * markdown: '# Customer data product',\n * });\n *\n * // Write a data product to the catalog but override the path\n * // Data product would be written to data-products/Account/CustomerDataProduct\n * await writeDataProduct({\n * id: 'CustomerDataProduct',\n * name: 'Customer Data Product',\n * version: '0.0.1',\n * summary: 'Customer data product',\n * markdown: '# Customer data product',\n * }, { path: \"/Account/CustomerDataProduct\"});\n *\n * // Write a data product to the catalog and override the existing content (if there is any)\n * await writeDataProduct({\n * id: 'CustomerDataProduct',\n * name: 'Customer Data Product',\n * version: '0.0.1',\n * summary: 'Customer data product',\n * markdown: '# Customer data product',\n * }, { override: true });\n *\n * // Write a data product to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeDataProduct({\n * id: 'CustomerDataProduct',\n * name: 'Customer Data Product',\n * version: '0.0.1',\n * summary: 'Customer data product',\n * markdown: '# Customer data product',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeDataProduct =\n (directory: string) =>\n async (\n dataProduct: DataProduct,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...dataProduct }, { ...options, type: 'data-product' });\n\n/**\n * Write a data product to a domain in EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeDataProductToDomain } = utils('/path/to/eventcatalog');\n *\n * // Write a data product to a domain\n * // Data product would be written to domains/Shopping/data-products/CustomerDataProduct\n * await writeDataProductToDomain({\n * id: 'CustomerDataProduct',\n * name: 'Customer Data Product',\n * version: '0.0.1',\n * summary: 'Customer data product',\n * markdown: '# Customer data product',\n * }, { id: 'Shopping' });\n * ```\n */\nexport const writeDataProductToDomain =\n (directory: string) =>\n async (\n dataProduct: DataProduct,\n domain: { id: string; version?: string },\n options: { path?: string; format?: 'md' | 'mdx'; override?: boolean } = { path: '', format: 'mdx', override: false }\n ) => {\n let pathForDataProduct =\n domain.version && domain.version !== 'latest'\n ? `/${domain.id}/versioned/${domain.version}/data-products`\n : `/${domain.id}/data-products`;\n pathForDataProduct = join(pathForDataProduct, dataProduct.id);\n\n await writeResource(directory, { ...dataProduct }, { ...options, path: pathForDataProduct, type: 'data-product' });\n };\n\n/**\n * Delete a data product at its given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDataProduct } = utils('/path/to/eventcatalog');\n *\n * // removes a data product at the given path (data-products dir is appended to the given path)\n * // Removes the data product at data-products/CustomerDataProduct\n * await rmDataProduct('/CustomerDataProduct');\n * ```\n */\nexport const rmDataProduct = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n invalidateFileCache();\n};\n\n/**\n * Delete a data product by its id.\n *\n * Optionally specify a version to delete a specific version of the data product.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDataProductById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest CustomerDataProduct data product\n * await rmDataProductById('CustomerDataProduct');\n *\n * // deletes a specific version of the CustomerDataProduct data product\n * await rmDataProductById('CustomerDataProduct', '0.0.1');\n * ```\n */\nexport const rmDataProductById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) => {\n await rmResourceById(directory, id, version, { type: 'data-product', persistFiles });\n};\n\n/**\n * Version a data product by its id.\n *\n * Takes the latest data product and moves it to a versioned directory.\n * All files with this data product are also versioned (e.g /data-products/CustomerDataProduct/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionDataProduct } = utils('/path/to/eventcatalog');\n *\n * // moves the latest CustomerDataProduct data product to a versioned directory\n * // the version within that data product is used as the version number.\n * await versionDataProduct('CustomerDataProduct');\n *\n * ```\n */\nexport const versionDataProduct = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Check to see if the catalog has a version for the given data product.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { dataProductHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given data product and version (supports semver)\n * await dataProductHasVersion('CustomerDataProduct', '0.0.1');\n * await dataProductHasVersion('CustomerDataProduct', 'latest');\n * await dataProductHasVersion('CustomerDataProduct', '0.0.x');\n *\n * ```\n */\nexport const dataProductHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n\n/**\n * Add a file to a data product by its id.\n *\n * Optionally specify a version to add a file to a specific version of the data product.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToDataProduct } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest CustomerDataProduct data product\n * await addFileToDataProduct('CustomerDataProduct', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the CustomerDataProduct data product\n * await addFileToDataProduct('CustomerDataProduct', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToDataProduct =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n","import fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { findFileById, invalidateFileCache } from './internal/utils';\nimport type { Diagram } from './types';\nimport {\n getResource,\n getResources,\n rmResourceById,\n versionResource,\n writeResource,\n addFileToResource,\n} from './internal/resources';\n\n/**\n * Returns a diagram from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the diagram\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getDiagram } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the diagram\n * const diagram = await getDiagram('ArchitectureDiagram');\n *\n * // Gets a version of the diagram\n * const diagram = await getDiagram('ArchitectureDiagram', '0.0.1');\n *\n * ```\n */\nexport const getDiagram =\n (directory: string) =>\n async (id: string, version?: string): Promise<Diagram> =>\n getResource(directory, id, version, { type: 'diagram' }) as Promise<Diagram>;\n\n/**\n * Returns all diagrams from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the diagrams.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getDiagrams } = utils('/path/to/eventcatalog');\n *\n * // Gets all diagrams (and versions) from the catalog\n * const diagrams = await getDiagrams();\n *\n * // Gets all diagrams (only latest version) from the catalog\n * const diagrams = await getDiagrams({ latestOnly: true });\n *\n * ```\n */\nexport const getDiagrams =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Diagram[]> =>\n getResources(directory, { type: 'diagrams', latestOnly: options?.latestOnly }) as Promise<Diagram[]>;\n\n/**\n * Write a diagram to EventCatalog.\n *\n * You can optionally override the path of the diagram.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeDiagram } = utils('/path/to/eventcatalog');\n *\n * // Write a diagram to the catalog\n * // Diagram would be written to diagrams/ArchitectureDiagram\n * await writeDiagram({\n * id: 'ArchitectureDiagram',\n * name: 'Architecture Diagram',\n * version: '0.0.1',\n * summary: 'Architecture diagram',\n * markdown: '# Architecture Diagram',\n * });\n *\n * // Write a diagram to the catalog but override the path\n * // Diagram would be written to diagrams/System/ArchitectureDiagram\n * await writeDiagram({\n * id: 'ArchitectureDiagram',\n * name: 'Architecture Diagram',\n * version: '0.0.1',\n * summary: 'Architecture diagram',\n * markdown: '# Architecture Diagram',\n * }, { path: \"/System/ArchitectureDiagram\"});\n *\n * // Write a diagram to the catalog and override the existing content (if there is any)\n * await writeDiagram({\n * id: 'ArchitectureDiagram',\n * name: 'Architecture Diagram',\n * version: '0.0.1',\n * summary: 'Architecture diagram',\n * markdown: '# Architecture Diagram',\n * }, { override: true });\n *\n * // Write a diagram to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeDiagram({\n * id: 'ArchitectureDiagram',\n * name: 'Architecture Diagram',\n * version: '0.0.1',\n * summary: 'Architecture diagram',\n * markdown: '# Architecture Diagram',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeDiagram =\n (directory: string) =>\n async (\n diagram: Diagram,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...diagram }, { ...options, type: 'diagram' });\n\n/**\n * Delete a diagram at its given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDiagram } = utils('/path/to/eventcatalog');\n *\n * // removes a diagram at the given path (diagrams dir is appended to the given path)\n * // Removes the diagram at diagrams/ArchitectureDiagram\n * await rmDiagram('/ArchitectureDiagram');\n * ```\n */\nexport const rmDiagram = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n invalidateFileCache();\n};\n\n/**\n * Delete a diagram by its id.\n *\n * Optionally specify a version to delete a specific version of the diagram.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDiagramById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest ArchitectureDiagram diagram\n * await rmDiagramById('ArchitectureDiagram');\n *\n * // deletes a specific version of the ArchitectureDiagram diagram\n * await rmDiagramById('ArchitectureDiagram', '0.0.1');\n * ```\n */\nexport const rmDiagramById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) => {\n await rmResourceById(directory, id, version, { type: 'diagram', persistFiles });\n};\n\n/**\n * Version a diagram by its id.\n *\n * Takes the latest diagram and moves it to a versioned directory.\n * All files with this diagram are also versioned (e.g /diagrams/ArchitectureDiagram/diagram.png)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionDiagram } = utils('/path/to/eventcatalog');\n *\n * // moves the latest ArchitectureDiagram diagram to a versioned directory\n * // the version within that diagram is used as the version number.\n * await versionDiagram('ArchitectureDiagram');\n *\n * ```\n */\nexport const versionDiagram = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Check to see if the catalog has a version for the given diagram.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { diagramHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given diagram and version (supports semver)\n * await diagramHasVersion('ArchitectureDiagram', '0.0.1');\n * await diagramHasVersion('ArchitectureDiagram', 'latest');\n * await diagramHasVersion('ArchitectureDiagram', '0.0.x');\n *\n * ```\n */\nexport const diagramHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n\n/**\n * Adds a file to the given diagram.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToDiagram } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the diagram\n * await addFileToDiagram('ArchitectureDiagram', { content: '...', fileName: 'diagram.png' });\n *\n * // adds a file to a specific version of the diagram\n * await addFileToDiagram('ArchitectureDiagram', { content: '...', fileName: 'diagram.png' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToDiagram =\n (directory: string) =>\n async (id: string, file: { content: string; fileName: string }, version?: string): Promise<void> =>\n addFileToResource(directory, id, file, version, { type: 'diagram' });\n"],"mappings":";AAAA,SAAS,QAAAA,cAAY;;;ACArB,SAAS,gBAAgB;AACzB,SAAS,WAAW,kBAAkB;AAM/B,SAAS,kBAAkB,gBAAoC,gBAA6C;AACjH,MAAI,CAAC,eAAgB,QAAO;AAC5B,MAAI,CAAC,eAAgB,QAAO;AAC5B,MAAI,mBAAmB,eAAgB,QAAO;AAC9C,MAAI;AAEF,QAAI,WAAW,cAAc,GAAG;AAC9B,UAAI,UAAU,gBAAgB,cAAc,EAAG,QAAO;AAAA,IACxD;AAEA,QAAI,WAAW,cAAc,GAAG;AAC9B,UAAI,UAAU,gBAAgB,cAAc,EAAG,QAAO;AAAA,IACxD;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAmCO,SAAS,oBAAoB,UAAwB,SAAiB,MAAc;AACzF,QAAM,QAAkB,CAAC;AAEzB,MAAI,SAAS,SAAS;AACpB,UAAM,KAAK,GAAG,MAAM,WAAW,SAAS,OAAO,EAAE;AAAA,EACnD;AAEA,MAAI,SAAS,MAAM;AACjB,UAAM,KAAK,GAAG,MAAM,SAAS,SAAS,IAAI,GAAG;AAAA,EAC/C;AAEA,MAAI,SAAS,SAAS;AACpB,UAAM,KAAK,GAAG,MAAM,YAAY,SAAS,QAAQ,KAAK,CAAC,GAAG;AAAA,EAC5D;AAEA,MAAI,SAAS,UAAU,SAAS,OAAO,SAAS,GAAG;AACjD,eAAW,SAAS,SAAS,QAAQ;AACnC,YAAM,KAAK,GAAG,MAAM,SAAS,KAAK,EAAE;AAAA,IACtC;AAAA,EACF;AAEA,MAAI,SAAS,eAAe,MAAM;AAChC,UAAM,KAAK,GAAG,MAAM,iBAAiB;AAAA,EACvC;AAEA,MAAI,SAAS,UAAU,MAAM;AAC3B,UAAM,KAAK,GAAG,MAAM,YAAY;AAAA,EAClC;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,sBAAsB,YAAsC;AAC1E,QAAM,QAA0B,oBAAI,IAAI;AACxC,QAAM,QAAQ,CAAC,UAAU,YAAY,SAAS;AAC9C,QAAM,UAAU,EAAE,QAAQ,SAAS,UAAU,WAAW,SAAS,QAAQ;AAEzE,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,SAAS,MAAM,IAAI,qBAAqB,EAAE,KAAK,WAAW,CAAC;AAC3E,eAAW,SAAS,SAAS;AAC3B,YAAM,QAAQ,MAAM,QAAQ,OAAO,GAAG,EAAE,MAAM,GAAG;AACjD,YAAM,UAAU,MAAM,YAAY,IAAI;AACtC,UAAI,YAAY,MAAM,UAAU,IAAI,MAAM,QAAQ;AAChD,cAAM,KAAK,MAAM,UAAU,CAAC;AAC5B,YAAI,CAAC,MAAM,IAAI,EAAE,EAAG,OAAM,IAAI,IAAI,QAAQ,IAAI,CAAC;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,mBAAmB,mBAA8C,IAAqC;AACpH,MAAI,OAAO,sBAAsB,UAAU;AACzC,WAAO,kBAAkB,IAAI,EAAE;AAAA,EACjC;AAEA,MAAI,SAAS,aAAa,EAAE,mBAAmB,EAAE,KAAK,kBAAkB,CAAC,EAAE,SAAS,EAAG,QAAO;AAC9F,MAAI,SAAS,eAAe,EAAE,mBAAmB,EAAE,KAAK,kBAAkB,CAAC,EAAE,SAAS,EAAG,QAAO;AAChG,MAAI,SAAS,cAAc,EAAE,mBAAmB,EAAE,KAAK,kBAAkB,CAAC,EAAE,SAAS,EAAG,QAAO;AAC/F,SAAO;AACT;AAEA,SAAS,oBAAoB,SAAiC;AAC5D,MAAI,MAAM,QAAQ;AAClB,MAAI,QAAQ,QAAS,QAAO,IAAI,QAAQ,OAAO;AAC/C,SAAO;AACT;AAEO,SAAS,yBACd,OACA,WACA,mBACA,SAAiB,MACT;AACR,QAAM,QAAkB,CAAC;AAEzB,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,mBAAmB,mBAAmB,KAAK,EAAE;AAC7D,QAAI,CAAC,QAAS;AAEd,QAAI,MAAM,GAAG,KAAK,EAAE;AACpB,QAAI,KAAK,QAAS,QAAO,IAAI,KAAK,OAAO;AAEzC,UAAM,WAAW,cAAc,UAAW,KAAsB,KAAM,KAAyB;AAE/F,UAAM,iBAAiB,cAAc,UAAU,OAAO;AAEtD,QAAI,YAAY,SAAS,WAAW,GAAG;AACrC,YAAM,KAAK,GAAG,MAAM,GAAG,SAAS,IAAI,OAAO,IAAI,GAAG,IAAI,cAAc,IAAI,oBAAoB,SAAS,CAAC,CAAC,CAAC,EAAE;AAAA,IAC5G,WAAW,YAAY,SAAS,SAAS,GAAG;AAC1C,YAAM,cAAc,SAAS,IAAI,mBAAmB,EAAE,KAAK,IAAI;AAC/D,YAAM,KAAK,GAAG,MAAM,GAAG,SAAS,IAAI,OAAO,IAAI,GAAG,IAAI,cAAc,IAAI,WAAW,EAAE;AAAA,IACvF,OAAO;AACL,YAAM,KAAK,GAAG,MAAM,GAAG,SAAS,IAAI,OAAO,IAAI,GAAG,EAAE;AAAA,IACtD;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;AC3JO,SAAS,aAAa,UAAmC,MAA2B;AACzF,QAAM,OAAO,oBAAoB,QAAQ;AAEzC,MAAI,CAAC,MAAM;AACT,WAAO,GAAG,IAAI,IAAI,SAAS,EAAE;AAAA,EAC/B;AAEA,SAAO,GAAG,IAAI,IAAI,SAAS,EAAE;AAAA,EAAO,IAAI;AAAA;AAC1C;;;ACPA,SAAS,SAAS,mBAAmB;AASrC,eAAsB,aACpB,UACA,SACA,cACiB;AACjB,QAAM,EAAE,YAAY,UAAU,OAAO,QAAQ,oBAAI,IAAY,EAAE,IAAI;AACnE,QAAM,WAAW,QAAQ,aAAa,sBAAsB,UAAU;AACtE,QAAM,QAAkB,CAAC;AACzB,QAAM,mBAAmB,oBAAI,IAAoB;AAEjD,MAAI,WAAW,cAAc;AAC3B,UAAM,cAAc,CAAC,GAAI,SAAS,SAAS,CAAC,GAAI,GAAI,SAAS,YAAY,CAAC,CAAE;AAC5E,eAAW,OAAO,aAAa;AAC7B,YAAM,MAAM,GAAG,IAAI,EAAE,IAAI,IAAI,WAAW,QAAQ;AAChD,UAAI,MAAM,IAAI,GAAG,EAAG;AACpB,YAAM,IAAI,GAAG;AAEb,YAAM,UAAU,mBAAmB,UAAU,IAAI,EAAE;AACnD,UAAI,CAAC,QAAS;AAEd,YAAM,cAAc,MAAM,aAAa,IAAI,IAAI,IAAI,OAAO;AAC1D,UAAI,aAAa;AACf,cAAM,KAAK,aAAa,aAAa,OAAO,CAAC;AAE7C,YAAI,IAAI,WAAW,CAAC,YAAY,IAAI,OAAO,KAAK,YAAY,SAAS;AACnE,2BAAiB,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,OAAO,IAAI,YAAY,OAAO;AAAA,QACtE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,kBAAkB,CAA6C,aACnE,SAAS,IAAI,CAAC,MAAM;AAClB,QAAI,EAAE,WAAW,CAAC,YAAY,EAAE,OAAO,GAAG;AACxC,YAAM,WAAW,iBAAiB,IAAI,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE;AAC5D,UAAI,SAAU,QAAO,EAAE,GAAG,GAAG,SAAS,SAAS;AAAA,IACjD;AACA,WAAO;AAAA,EACT,CAAC;AAEH,QAAM,QAAQ,SAAS,QAAQ,gBAAgB,SAAS,KAAK,IAAI;AACjE,QAAM,WAAW,SAAS,WAAW,gBAAgB,SAAS,QAAQ,IAAI;AAE1E,QAAM,QAAkB,CAAC;AACzB,QAAM,aAAa,oBAAoB,QAAQ;AAC/C,MAAI,WAAY,OAAM,KAAK,UAAU;AAErC,MAAI,SAAS,MAAM,SAAS,GAAG;AAC7B,UAAM,WAAW,yBAAyB,OAAO,SAAS,QAAQ;AAClE,QAAI,SAAU,OAAM,KAAK,QAAQ;AAAA,EACnC;AAEA,MAAI,YAAY,SAAS,SAAS,GAAG;AACnC,UAAM,UAAU,yBAAyB,UAAU,YAAY,QAAQ;AACvE,QAAI,QAAS,OAAM,KAAK,OAAO;AAAA,EACjC;AAEA,MAAI,SAAS,YAAY,SAAS,SAAS,SAAS,GAAG;AACrD,eAAW,aAAa,SAAS,UAAU;AACzC,UAAI,MAAM,UAAU;AACpB,UAAI,UAAU,QAAS,QAAO,IAAI,UAAU,OAAO;AACnD,YAAM,KAAK,yBAAyB,GAAG,EAAE;AAAA,IAC3C;AAAA,EACF;AAEA,MAAI,SAAS,aAAa,SAAS,UAAU,SAAS,GAAG;AACvD,eAAW,aAAa,SAAS,WAAW;AAC1C,UAAI,MAAM,UAAU;AACpB,UAAI,UAAU,QAAS,QAAO,IAAI,UAAU,OAAO;AACnD,YAAM,KAAK,0BAA0B,GAAG,EAAE;AAAA,IAC5C;AAAA,EACF;AAEA,QAAM,OAAO,MAAM,KAAK,IAAI;AAC5B,QAAM,KAAK,WAAW,SAAS,EAAE;AAAA,EAAO,IAAI;AAAA,EAAK;AAEjD,SAAO,MAAM,KAAK,MAAM;AAC1B;;;ACzFO,SAAS,aAAa,UAA2B;AACtD,QAAM,QAAkB,CAAC;AAEzB,MAAI,SAAS,SAAS;AACpB,UAAM,KAAK,aAAa,SAAS,OAAO,EAAE;AAAA,EAC5C;AAEA,MAAI,SAAS,MAAM;AACjB,UAAM,KAAK,WAAW,SAAS,IAAI,GAAG;AAAA,EACxC;AAEA,MAAI,SAAS,SAAS;AACpB,UAAM,KAAK,cAAc,SAAS,OAAO,GAAG;AAAA,EAC9C;AAEA,MAAI,SAAS,aAAa,SAAS,UAAU,SAAS,GAAG;AACvD,eAAW,YAAY,SAAS,WAAW;AACzC,YAAM,KAAK,eAAe,QAAQ,GAAG;AAAA,IACvC;AAAA,EACF;AAEA,MAAI,SAAS,SAAS;AACpB,UAAM,KAAK,cAAc,SAAS,QAAQ,KAAK,CAAC,GAAG;AAAA,EACrD;AAEA,MAAI,SAAS,UAAU,SAAS,OAAO,SAAS,GAAG;AACjD,eAAW,SAAS,SAAS,QAAQ;AACnC,UAAI,MAAM,MAAM;AAChB,UAAI,MAAM,QAAS,QAAO,IAAI,MAAM,OAAO;AAC3C,YAAM,KAAK,WAAW,GAAG,EAAE;AAAA,IAC7B;AAAA,EACF;AAEA,MAAI,CAAC,MAAM,QAAQ;AACjB,WAAO,WAAW,SAAS,EAAE;AAAA,EAC/B;AAEA,SAAO,WAAW,SAAS,EAAE;AAAA,EAAO,MAAM,KAAK,IAAI,CAAC;AAAA;AACtD;;;ACtCO,SAAS,UAAU,MAAoB;AAC5C,QAAM,QAAkB,CAAC;AAEzB,MAAI,KAAK,KAAM,OAAM,KAAK,WAAW,KAAK,IAAI,GAAG;AACjD,MAAI,KAAK,UAAW,OAAM,KAAK,aAAa,KAAK,SAAS,GAAG;AAC7D,MAAI,KAAK,KAAM,OAAM,KAAK,WAAW,KAAK,IAAI,GAAG;AACjD,MAAI,KAAK,QAAS,OAAM,KAAK,cAAc,KAAK,OAAO,GAAG;AAC1D,MAAI,KAAK,MAAO,OAAM,KAAK,YAAY,KAAK,KAAK,GAAG;AACpD,MAAI,KAAK,sBAAuB,OAAM,KAAK,YAAY,KAAK,qBAAqB,GAAG;AAEpF,SAAO,QAAQ,KAAK,EAAE;AAAA,EAAO,MAAM,KAAK,IAAI,CAAC;AAAA;AAC/C;AAEO,SAAS,UAAU,MAAoB;AAC5C,QAAM,QAAkB,CAAC;AAEzB,MAAI,KAAK,KAAM,OAAM,KAAK,WAAW,KAAK,IAAI,GAAG;AACjD,MAAI,KAAK,UAAW,OAAM,KAAK,aAAa,KAAK,SAAS,GAAG;AAC7D,MAAI,KAAK,KAAM,OAAM,KAAK,WAAW,KAAK,IAAI,GAAG;AACjD,MAAI,KAAK,MAAO,OAAM,KAAK,YAAY,KAAK,KAAK,GAAG;AACpD,MAAI,KAAK,sBAAuB,OAAM,KAAK,YAAY,KAAK,qBAAqB,GAAG;AAEpF,SAAO,QAAQ,KAAK,EAAE;AAAA,EAAO,MAAM,KAAK,IAAI,CAAC;AAAA;AAC/C;;;ACDA,eAAe,cAAc,QAA8B,WAA4B,MAAmB,OAAiB;AACzH,MAAI,CAAC,UAAU,CAAC,UAAU,WAAW,CAAC,UAAU,QAAS;AACzD,aAAW,WAAW,QAAQ;AAC5B,UAAM,MAAM,SAAS,OAAO;AAC5B,QAAI,KAAK,IAAI,GAAG,EAAG;AACnB,SAAK,IAAI,GAAG;AAEZ,UAAM,OAAO,MAAM,UAAU,QAAQ,OAAO;AAC5C,QAAI,MAAM;AACR,YAAM,KAAK,UAAU,IAAI,CAAC;AAC1B;AAAA,IACF;AAEA,UAAM,OAAO,MAAM,UAAU,QAAQ,OAAO;AAC5C,QAAI,MAAM;AACR,YAAM,KAAK,UAAU,IAAI,CAAC;AAAA,IAC5B;AAAA,EACF;AACF;AAEA,eAAe,4BACb,UAMA,WACA,MACA,OACA;AACA,MAAI,CAAC,UAAU,WAAY;AAC3B,aAAW,OAAO,UAAU;AAC1B,UAAM,WAAY,IAAY,MAAO,IAAY;AACjD,QAAI,CAAC,SAAU;AACf,eAAW,MAAM,UAAU;AACzB,YAAM,MAAM,WAAW,GAAG,EAAE,IAAI,GAAG,WAAW,QAAQ;AACtD,UAAI,KAAK,IAAI,GAAG,EAAG;AACnB,WAAK,IAAI,GAAG;AAEZ,YAAM,UAAU,MAAM,UAAU,WAAW,GAAG,IAAI,GAAG,OAAO;AAC5D,UAAI,SAAS;AACX,cAAM,KAAK,aAAa,OAAO,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,gBACb,UACA,SACA,WACA,SACqD;AACrD,QAAM,EAAE,YAAY,UAAU,OAAO,QAAQ,oBAAI,IAAY,EAAE,IAAI;AACnE,QAAM,WAAW,QAAQ,aAAa,sBAAsB,UAAU;AACtE,QAAM,gBAA0B,CAAC;AAEjC,MAAI,WAAW,WAAW;AAExB,QAAI,SAAS,YAAY,SAAS,SAAS,SAAS,KAAK,UAAU,YAAY;AAC7E,iBAAW,UAAU,SAAS,UAAU;AACtC,cAAM,SAAS,WAAW,OAAO,EAAE,IAAI,OAAO,WAAW,QAAQ;AACjE,YAAI,MAAM,IAAI,MAAM,EAAG;AACvB,cAAM,IAAI,MAAM;AAEhB,cAAM,MAAM,MAAM,UAAU,WAAW,OAAO,IAAI,OAAO,OAAO;AAChE,YAAI,KAAK;AAEP,gBAAM,cAAc,IAAI,QAAQ,WAAW,OAAO,aAAa;AAE/D,gBAAM,cAAc,CAAC,GAAI,IAAI,SAAS,CAAC,GAAI,GAAI,IAAI,YAAY,CAAC,CAAE;AAClE,gBAAM,4BAA4B,aAAa,WAAW,OAAO,aAAa;AAE9E,gBAAM,SAAS,MAAM,aAAa,KAAK,EAAE,YAAY,SAAS,MAAM,OAAO,WAAW,SAAS,GAAG,UAAU,UAAU;AACtH,wBAAc,KAAK,MAAM;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AAGA,UAAM,iBAAiB,CAAC,GAAI,SAAS,SAAS,CAAC,GAAI,GAAI,SAAS,YAAY,CAAC,CAAE;AAC/E,UAAM,4BAA4B,gBAAgB,WAAW,OAAO,aAAa;AAGjF,QAAI,UAAU,YAAY;AACxB,iBAAW,OAAO,gBAAgB;AAChC,cAAM,MAAM,GAAG,IAAI,EAAE,IAAI,IAAI,WAAW,QAAQ;AAChD,YAAI,MAAM,IAAI,GAAG,EAAG;AACpB,cAAM,IAAI,GAAG;AAEb,cAAM,UAAU,mBAAmB,UAAU,IAAI,EAAE;AACnD,YAAI,CAAC,QAAS;AAEd,cAAM,cAAc,MAAM,UAAU,WAAW,IAAI,IAAI,IAAI,OAAO;AAClE,YAAI,aAAa;AACf,wBAAc,KAAK,aAAa,aAAa,OAAO,CAAC;AAAA,QACvD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,aAAa,oBAAoB,QAAQ;AAC/C,MAAI,WAAY,OAAM,KAAK,UAAU;AAGrC,MAAI,SAAS,YAAY,SAAS,SAAS,SAAS,GAAG;AACrD,eAAW,OAAO,SAAS,UAAU;AACnC,UAAI,MAAM,IAAI;AACd,UAAI,IAAI,QAAS,QAAO,IAAI,IAAI,OAAO;AACvC,YAAM,KAAK,aAAa,GAAG,EAAE;AAAA,IAC/B;AAAA,EACF;AAEA,MAAI,SAAS,SAAS,SAAS,MAAM,SAAS,GAAG;AAC/C,UAAM,WAAW,yBAAyB,SAAS,OAAO,SAAS,QAAQ;AAC3E,QAAI,SAAU,OAAM,KAAK,QAAQ;AAAA,EACnC;AAEA,MAAI,SAAS,YAAY,SAAS,SAAS,SAAS,GAAG;AACrD,UAAM,UAAU,yBAAyB,SAAS,UAAU,YAAY,QAAQ;AAChF,QAAI,QAAS,OAAM,KAAK,OAAO;AAAA,EACjC;AAGA,MAAI,SAAS,WAAW,SAAS,QAAQ,SAAS,GAAG;AACnD,QAAI,WAAW,WAAW,WAAW;AACnC,iBAAW,UAAU,SAAS,SAAS;AACrC,cAAM,SAAS,UAAU,OAAO,EAAE,IAAI,OAAO,WAAW,QAAQ;AAChE,YAAI,MAAM,IAAI,MAAM,EAAG;AACvB,cAAM,IAAI,MAAM;AAEhB,cAAM,YAAY,MAAM,UAAU,UAAU,OAAO,IAAI,OAAO,OAAO;AACrE,YAAI,WAAW;AAEb,gBAAM,cAAc,UAAU,QAAQ,WAAW,OAAO,aAAa;AAErE,gBAAM,MAAM,MAAM;AAAA,YAChB;AAAA,YACA,EAAE,YAAY,SAAS,OAAO,WAAW,SAAS;AAAA,YAClD;AAAA,YACA;AAAA,UACF;AACA,wBAAc,KAAK,GAAG,IAAI,aAAa;AAEvC,gBAAM,WAAW,IAAI,MAClB,MAAM,IAAI,EACV,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,EACzB,KAAK,IAAI;AACZ,gBAAM,KAAK,QAAQ;AAAA,QACrB;AAAA,MACF;AAAA,IACF,OAAO;AAEL,iBAAW,OAAO,SAAS,SAAS;AAClC,YAAI,MAAM,IAAI;AACd,YAAI,IAAI,QAAS,QAAO,IAAI,IAAI,OAAO;AACvC,cAAM,KAAK,eAAe,GAAG,EAAE;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,OAAO,MAAM,KAAK,IAAI;AAC5B,QAAM,QAAQ,GAAG,OAAO,IAAI,SAAS,EAAE;AAAA,EAAO,IAAI;AAAA;AAElD,SAAO,EAAE,eAAe,MAAM;AAChC;AAEA,eAAsB,YAAY,UAAkB,SAA6B,WAA8C;AAC7H,QAAM,EAAE,YAAY,UAAU,OAAO,QAAQ,oBAAI,IAAY,EAAE,IAAI;AACnE,QAAM,WAAW,QAAQ,aAAa,sBAAsB,UAAU;AAEtE,QAAM,SAAS,MAAM,gBAAgB,UAAU,EAAE,YAAY,SAAS,OAAO,WAAW,SAAS,GAAG,WAAW,QAAQ;AACvH,QAAM,QAAQ,CAAC,GAAG,OAAO,eAAe,OAAO,KAAK;AAEpD,SAAO,MAAM,KAAK,MAAM;AAC1B;;;ACtMO,SAAS,eAAe,UAA6B;AAC1D,QAAM,QAAkB,CAAC;AACzB,QAAM,aAAa,oBAAoB,QAAQ;AAC/C,MAAI,WAAY,OAAM,KAAK,UAAU;AAErC,MAAI,SAAS,gBAAgB;AAC3B,UAAM,KAAK,oBAAoB,SAAS,cAAc,EAAE;AAAA,EAC1D;AAEA,MAAI,SAAS,YAAY;AACvB,UAAM,KAAK,iBAAiB,SAAS,UAAU,GAAG;AAAA,EACpD;AAEA,MAAI,SAAS,kBAAkB,MAAM;AACnC,UAAM,KAAK,sBAAsB;AAAA,EACnC;AAEA,MAAI,SAAS,aAAa;AACxB,UAAM,KAAK,iBAAiB,SAAS,WAAW,EAAE;AAAA,EACpD;AAEA,MAAI,SAAS,gBAAgB;AAC3B,UAAM,KAAK,oBAAoB,SAAS,cAAc,EAAE;AAAA,EAC1D;AAEA,MAAI,SAAS,WAAW;AACtB,UAAM,KAAK,gBAAgB,SAAS,SAAS,GAAG;AAAA,EAClD;AAEA,MAAI,SAAS,WAAW;AACtB,UAAM,KAAK,gBAAgB,SAAS,SAAS,GAAG;AAAA,EAClD;AAEA,QAAM,OAAO,MAAM,KAAK,IAAI;AAC5B,SAAO,aAAa,SAAS,EAAE;AAAA,EAAO,IAAI;AAAA;AAC5C;;;ACLA,SAAS,WAAW,WAA8B,UAA4B;AAC5E,SAAO,OAAO,IAAY,YAAqB;AAC7C,UAAM,UAAU,mBAAmB,UAAU,EAAE;AAC/C,QAAI,CAAC,QAAS,QAAO;AACrB,YAAQ,SAAS;AAAA,MACf,KAAK;AACH,eAAO,UAAU,SAAS,IAAI,OAAO;AAAA,MACvC,KAAK;AACH,eAAO,UAAU,WAAW,IAAI,OAAO;AAAA,MACzC,KAAK;AACH,eAAO,UAAU,SAAS,IAAI,OAAO;AAAA,IACzC;AAAA,EACF;AACF;AAEA,eAAe,eACb,WACA,gBACA,WACA,MACA,OACA;AACA,QAAM,MAAM,WAAW,SAAS,IAAI,kBAAkB,QAAQ;AAC9D,MAAI,KAAK,IAAI,GAAG,EAAG;AACnB,OAAK,IAAI,GAAG;AAEZ,QAAM,UAAU,MAAM,UAAU,WAAW,WAAW,cAAc;AACpE,MAAI,CAAC,QAAS;AAGd,MAAI,QAAQ,UAAU,QAAQ,OAAO,SAAS,GAAG;AAC/C,eAAW,SAAS,QAAQ,QAAQ;AAClC,YAAM,eAAe,MAAM,IAAI,MAAM,SAAS,WAAW,MAAM,KAAK;AAAA,IACtE;AAAA,EACF;AAGA,QAAM,cAAe,MAAM,UAAU,YAAY,EAAE,YAAY,MAAM,CAAC,KAAM,CAAC;AAC7E,QAAM,gBAAgB,kBAAkB,QAAQ;AAChD,aAAW,YAAY,aAAa;AAClC,QAAI,CAAC,SAAS,OAAQ;AACtB,UAAM,eAAe,SAAS,OAAO,KAAK,CAAC,UAAU;AACnD,UAAI,MAAM,OAAO,UAAW,QAAO;AACnC,UAAI,CAAC,MAAM,SAAS;AAElB,eAAO,CAAC;AAAA,MACV;AACA,aAAO,kBAAkB,MAAM,SAAS,aAAa;AAAA,IACvD,CAAC;AACD,QAAI,cAAc;AAChB,YAAM,eAAe,SAAS,IAAI,SAAS,SAAS,WAAW,MAAM,KAAK;AAAA,IAC5E;AAAA,EACF;AAEA,QAAM,KAAK,aAAa,OAAO,CAAC;AAClC;AAEA,eAAe,gBAAgB,UAA4B,WAA8B,MAAmB,OAAiB;AAC3H,QAAM,cAAc,CAAC,GAAK,SAAqB,SAAS,CAAC,GAAI,GAAK,SAAqB,YAAY,CAAC,CAAE;AACtG,aAAW,OAAO,aAAa;AAC7B,UAAM,WAAW,QAAQ,MAAO,IAAY,KAAK,UAAU,MAAO,IAAY,OAAO;AACrF,QAAI,CAAC,SAAU;AACf,eAAW,MAAM,UAAU;AACzB,YAAM,eAAe,GAAG,IAAI,GAAG,SAAS,WAAW,MAAM,KAAK;AAAA,IAChE;AAAA,EACF;AACF;AAEA,eAAe,kBAAkB,UAAmB,WAA8B,MAAmB,OAAiB;AACpH,QAAM,gBAAgB,CAAC,GAAI,SAAS,YAAY,CAAC,GAAI,GAAI,SAAS,aAAa,CAAC,CAAE;AAClF,aAAW,OAAO,eAAe;AAC/B,UAAM,MAAM,aAAa,IAAI,EAAE,IAAI,IAAI,WAAW,QAAQ;AAC1D,QAAI,KAAK,IAAI,GAAG,EAAG;AACnB,SAAK,IAAI,GAAG;AAEZ,UAAM,YAAY,MAAM,UAAU,aAAa,IAAI,IAAI,IAAI,OAAO;AAClE,QAAI,CAAC,UAAW;AAEhB,UAAM,KAAK,eAAe,SAAS,CAAC;AAAA,EACtC;AACF;AAEA,eAAeC,eAAc,QAA8B,WAA8B,MAAmB,OAAiB;AAC3H,MAAI,CAAC,OAAQ;AACb,aAAW,WAAW,QAAQ;AAC5B,UAAM,MAAM,SAAS,OAAO;AAC5B,QAAI,KAAK,IAAI,GAAG,EAAG;AACnB,SAAK,IAAI,GAAG;AAEZ,UAAM,OAAO,MAAM,UAAU,QAAQ,OAAO;AAC5C,QAAI,MAAM;AACR,YAAM,KAAK,UAAU,IAAI,CAAC;AAC1B;AAAA,IACF;AAEA,UAAM,OAAO,MAAM,UAAU,QAAQ,OAAO;AAC5C,QAAI,MAAM;AACR,YAAM,KAAK,UAAU,IAAI,CAAC;AAAA,IAC5B;AAAA,EACF;AACF;AAEA,eAAe,uBACb,WACA,gBACA,WACA,MACA,OACA,YACA,UACA;AACA,QAAM,WAAY,MAAM,UAAU,YAAY,EAAE,YAAY,MAAM,CAAC,KAAM,CAAC;AAC1E,aAAW,WAAW,UAAU;AAC9B,UAAM,MAAM,WAAW,QAAQ,EAAE,IAAI,QAAQ,WAAW,QAAQ;AAChE,QAAI,KAAK,IAAI,GAAG,EAAG;AAEnB,UAAM,oBAAoB,CAAC,GAAI,QAAQ,SAAS,CAAC,GAAI,GAAI,QAAQ,YAAY,CAAC,CAAE,EAAE;AAAA,MAChF,CAAC,QAAQ,IAAI,OAAO,aAAa,kBAAkB,IAAI,SAAS,cAAc;AAAA,IAChF;AAEA,QAAI,mBAAmB;AACrB,WAAK,IAAI,GAAG;AACZ,YAAM,WAAW,CAAC,QAChB,IAAI,OAAO,aAAa,kBAAkB,IAAI,SAAS,cAAc;AACvE,YAAM,wBAAwB,CAA6C,QAAc;AACvF,YAAI,IAAI,OAAO,aAAa,IAAI,WAAW,IAAI,YAAY,kBAAkB,gBAAgB;AAC3F,iBAAO,EAAE,GAAG,KAAK,SAAS,eAAe;AAAA,QAC3C;AACA,eAAO;AAAA,MACT;AACA,YAAM,WAAoB;AAAA,QACxB,GAAG;AAAA,QACH,OAAO,QAAQ,OAAO,OAAO,QAAQ,EAAE,IAAI,qBAAqB;AAAA,QAChE,UAAU,QAAQ,UAAU,OAAO,QAAQ,EAAE,IAAI,qBAAqB;AAAA,MACxE;AACA,YAAM,gBAAgB,UAAU,WAAW,MAAM,KAAK;AACtD,YAAM,KAAK,MAAM,aAAa,UAAU,EAAE,YAAY,SAAS,OAAO,OAAO,IAAI,IAAI,IAAI,GAAG,WAAW,SAAS,CAAC,CAAC;AAAA,IACpH;AAAA,EACF;AACF;AAEA,eAAe,uBACb,UACA,WACA,WACA,MACA,OACA,YACA,UACA;AACA,MAAI,CAAC,SAAS,OAAQ;AAEtB,QAAM,4BAA4B,CAAC,QACjC,SAAS,KAAK,CAAC,UAAU,IAAI,OAAO,MAAM,MAAM,kBAAkB,IAAI,SAAS,MAAM,OAAO,CAAC;AAE/F,QAAM,WAAY,MAAM,UAAU,YAAY,EAAE,YAAY,MAAM,CAAC,KAAM,CAAC;AAC1E,aAAW,WAAW,UAAU;AAC9B,UAAM,MAAM,WAAW,QAAQ,EAAE,IAAI,QAAQ,WAAW,QAAQ;AAChE,QAAI,KAAK,IAAI,GAAG,EAAG;AAEnB,QAAI,cAAc,SAAS;AACzB,YAAM,mBAAmB,QAAQ,SAAS,CAAC,GAAG,OAAO,yBAAyB;AAC9E,UAAI,gBAAgB,SAAS,GAAG;AAC9B,aAAK,IAAI,GAAG;AACZ,cAAM,WAAoB;AAAA,UACxB,GAAG;AAAA,UACH,OAAO;AAAA,UACP,UAAU;AAAA,QACZ;AACA,cAAM,gBAAgB,UAAU,WAAW,MAAM,KAAK;AACtD,cAAM,KAAK,MAAM,aAAa,UAAU,EAAE,YAAY,SAAS,OAAO,OAAO,IAAI,IAAI,IAAI,GAAG,WAAW,SAAS,CAAC,CAAC;AAAA,MACpH;AAAA,IACF,OAAO;AACL,YAAM,mBAAmB,QAAQ,YAAY,CAAC,GAAG,OAAO,yBAAyB;AACjF,UAAI,gBAAgB,SAAS,GAAG;AAC9B,aAAK,IAAI,GAAG;AACZ,cAAM,WAAoB;AAAA,UACxB,GAAG;AAAA,UACH,OAAO;AAAA,UACP,UAAU;AAAA,QACZ;AACA,cAAM,gBAAgB,UAAU,WAAW,MAAM,KAAK;AACtD,cAAM,KAAK,MAAM,aAAa,UAAU,EAAE,YAAY,SAAS,OAAO,OAAO,IAAI,IAAI,IAAI,GAAG,WAAW,SAAS,CAAC,CAAC;AAAA,MACpH;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,QACX,CAAC,YAAoB,cACrB,OAAO,UAAuC,YAA2C;AACvF,QAAM,YAAY,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,QAAQ;AAChE,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,QAAkB,CAAC;AACzB,QAAM,WAAW,sBAAsB,UAAU;AAEjD,aAAW,OAAO,WAAW;AAC3B,UAAM,MAAM,GAAG,QAAQ,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,WAAW,QAAQ;AAChE,QAAI,KAAK,IAAI,GAAG,EAAG;AACnB,SAAK,IAAI,GAAG;AAEZ,YAAQ,QAAQ,MAAM;AAAA,MACpB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,YAAI,QAAQ,SAAS;AACnB,gBAAMA,eAAc,IAAI,QAAQ,WAAW,MAAM,KAAK;AACtD,gBAAM,uBAAuB,IAAI,IAAI,IAAI,SAAS,WAAW,MAAM,OAAO,YAAY,QAAQ;AAAA,QAChG;AACA,cAAM,KAAK,aAAa,KAAgC,QAAQ,IAAmB,CAAC;AACpF;AAAA,MACF,KAAK;AACH,YAAI,QAAQ,SAAS;AACnB,gBAAMA,eAAc,IAAI,QAAQ,WAAW,MAAM,KAAK;AACtD,gBAAM,gBAAgB,KAAgB,WAAW,MAAM,KAAK;AAC5D,gBAAM,kBAAkB,KAAgB,WAAW,MAAM,KAAK;AAAA,QAChE;AACA,cAAM;AAAA,UACJ,MAAM;AAAA,YACJ;AAAA,YACA,EAAE,YAAY,SAAS,QAAQ,SAAS,OAAO,MAAM,WAAW,SAAS;AAAA,YACzE,WAAW,WAAW,QAAQ;AAAA,UAChC;AAAA,QACF;AACA,YAAI,QAAQ,SAAS;AACnB,gBAAM,MAAM;AAEZ,gBAAM,uBAAuB,IAAI,SAAS,CAAC,GAAG,YAAY,WAAW,MAAM,OAAO,YAAY,QAAQ;AAEtG,gBAAM,uBAAuB,IAAI,YAAY,CAAC,GAAG,SAAS,WAAW,MAAM,OAAO,YAAY,QAAQ;AAAA,QACxG;AACA;AAAA,MACF,KAAK;AACH,YAAI,QAAQ,SAAS;AACnB,gBAAMA,eAAc,IAAI,QAAQ,WAAW,MAAM,KAAK;AAAA,QACxD;AACA,cAAM;AAAA,UACJ,MAAM;AAAA,YACJ;AAAA,YACA,EAAE,YAAY,SAAS,QAAQ,SAAS,OAAO,MAAM,WAAW,SAAS;AAAA,YACzE;AAAA,cACE,YAAY,UAAU;AAAA,cACtB,WAAW,UAAU;AAAA,cACrB,YAAY,WAAW,WAAW,QAAQ;AAAA,cAC1C,YAAY,UAAU;AAAA,cACtB,SAAS,UAAU;AAAA,cACnB,SAAS,UAAU;AAAA,YACrB;AAAA,UACF;AAAA,QACF;AACA,YAAI,QAAQ,SAAS;AACnB,gBAAM,SAAS;AACf,gBAAM,WAA+C,CAAC;AACtD,gBAAM,cAAkD,CAAC;AAEzD,cAAI,OAAO,UAAU,QAAQ;AAC3B,uBAAW,UAAU,OAAO,UAAU;AACpC,oBAAM,MAAM,MAAM,UAAU,WAAW,OAAO,IAAI,OAAO,OAAO;AAChE,kBAAI,KAAK;AACP,yBAAS,KAAK,GAAI,IAAI,SAAS,CAAC,CAAE;AAClC,4BAAY,KAAK,GAAI,IAAI,YAAY,CAAC,CAAE;AAAA,cAC1C;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,uBAAuB,UAAU,YAAY,WAAW,MAAM,OAAO,YAAY,QAAQ;AAE/F,gBAAM,uBAAuB,aAAa,SAAS,WAAW,MAAM,OAAO,YAAY,QAAQ;AAAA,QACjG;AACA;AAAA,IACJ;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,MAAM;AAC1B;;;ACpTF,OAAOC,SAAQ;AACf,SAAS,QAAAC,aAAqB;;;ACD9B,SAAS,YAAAC,iBAAgB;AACzB,OAAO,YAAY;AACnB,SAAS,YAA6C;AACtD,SAAS,MAAM,SAAS,WAAW,OAAO,eAAe,SAAmB,gBAAgB;AAC5F,OAAO,YAAY;AACnB,SAAS,aAAAC,YAAW,cAAAC,mBAAyB;AAU7C,IAAI,kBAAwD;AAC5D,IAAI,uBAAsC;AAC1C,IAAI,eAAkE;AACtE,IAAI,qBAAiD;AACrD,IAAI,oBAA4B;AAEhC,SAAS,gBAAgB,WAA2B;AAClD,SAAO,UAAU,QAAQ,SAAS,CAAC;AACrC;AAEA,SAAS,eAAe,YAA0B;AAChD,QAAM,sBAAsB,gBAAgB,UAAU;AACtD,QAAM,QAAQF,UAAS,qBAAqB;AAAA,IAC1C,KAAK;AAAA,IACL,QAAQ,CAAC,iBAAiB;AAAA,IAC1B,UAAU;AAAA,IACV,OAAO;AAAA,EACT,CAAC,EAAE,IAAI,SAAS;AAEhB,QAAM,QAAQ,oBAAI,IAA8B;AAChD,QAAM,gBAAgB,oBAAI,IAA2C;AACrE,QAAM,WAAW,oBAAI,IAAoB;AAEzC,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,OAAO,aAAa,MAAM,OAAO;AACjD,UAAM,SAAS,OAAO,OAAO;AAC7B,kBAAc,IAAI,MAAM,MAAM;AAE9B,UAAM,KAAK,OAAO,KAAK;AACvB,QAAI,CAAC,GAAI;AAET,UAAM,aAAa,OAAO,EAAE;AAC5B,UAAM,UAAU,OAAO,KAAK,WAAW;AACvC,UAAM,cAAc,KAAK,SAAS,WAAW;AAC7C,UAAM,QAAwB,EAAE,MAAM,MAAM,IAAI,YAAY,SAAS,OAAO,OAAO,GAAG,YAAY;AAClG,aAAS,IAAI,MAAM,UAAU;AAE7B,UAAM,WAAW,MAAM,IAAI,UAAU;AACrC,QAAI,UAAU;AACZ,eAAS,KAAK,KAAK;AAAA,IACrB,OAAO;AACL,YAAM,IAAI,YAAY,CAAC,KAAK,CAAC;AAAA,IAC/B;AAAA,EACF;AAEA,oBAAkB;AAClB,yBAAuB;AACvB,iBAAe;AACf,uBAAqB;AACrB,MAAI;AACF,wBAAoB,OAAO,SAAS,mBAAmB,EAAE;AAAA,EAC3D,QAAQ;AACN,wBAAoB;AAAA,EACtB;AACF;AAEA,SAAS,gBAAgB,YAA0B;AACjD,QAAM,sBAAsB,gBAAgB,UAAU;AACtD,MAAI,CAAC,mBAAmB,yBAAyB,qBAAqB;AACpE,mBAAe,UAAU;AACzB;AAAA,EACF;AAEA,MAAI;AACF,UAAM,eAAe,OAAO,SAAS,mBAAmB,EAAE;AAC1D,QAAI,iBAAiB,mBAAmB;AACtC,qBAAe,UAAU;AAAA,IAC3B;AAAA,EACF,QAAQ;AACN,mBAAe,UAAU;AAAA,EAC3B;AACF;AAGO,SAAS,sBAA4B;AAC1C,oBAAkB;AAClB,yBAAuB;AACvB,iBAAe;AACf,uBAAqB;AACvB;AAMO,SAAS,qBAAqB,YAAoB,UAAkB,YAA0B;AACnG,QAAM,sBAAsB,gBAAgB,UAAU;AACtD,MAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,sBAAsB,yBAAyB,qBAAqB;AAC5G;AAAA,EACF;AAEA,QAAM,iBAAiB,gBAAgB,QAAQ;AAC/C,QAAM,SAAS,OAAO,UAAU;AAGhC,QAAM,aAAa,mBAAmB,IAAI,cAAc;AACxD,MAAI,YAAY;AACd,UAAM,kBAAkB,gBAAgB,IAAI,UAAU,KAAK,CAAC;AAC5D,UAAM,cAAc,gBAAgB,OAAO,CAACG,WAAUA,OAAM,SAAS,cAAc;AACnF,QAAI,YAAY,WAAW,GAAG;AAC5B,sBAAgB,OAAO,UAAU;AAAA,IACnC,OAAO;AACL,sBAAgB,IAAI,YAAY,WAAW;AAAA,IAC7C;AACA,uBAAmB,OAAO,cAAc;AAAA,EAC1C;AAEA,eAAa,IAAI,gBAAgB,MAAM;AAEvC,QAAM,KAAK,OAAO,KAAK;AACvB,MAAI,CAAC,IAAI;AACP,uBAAmB,OAAO,cAAc;AACxC;AAAA,EACF;AAEA,QAAM,aAAa,OAAO,EAAE;AAC5B,QAAM,QAAwB;AAAA,IAC5B,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,SAAS,OAAO,OAAO,KAAK,WAAW,EAAE;AAAA,IACzC,aAAa,eAAe,SAAS,GAAG,aAAa,YAAY,aAAa,EAAE;AAAA,EAClF;AAEA,QAAM,UAAU,gBAAgB,IAAI,UAAU,KAAK,CAAC;AACpD,UAAQ,KAAK,KAAK;AAClB,kBAAgB,IAAI,YAAY,OAAO;AACvC,qBAAmB,IAAI,gBAAgB,UAAU;AAEjD,MAAI;AACF,wBAAoB,OAAO,SAAS,mBAAmB,EAAE;AAAA,EAC3D,QAAQ;AAAA,EAER;AACF;AASO,SAAS,iBAAiB,UAAiD;AAChF,MAAI,cAAc;AAChB,UAAM,SAAS,aAAa,IAAI,QAAQ;AACxC,QAAI,OAAQ,QAAO;AAAA,EACrB;AACA,SAAO,OAAO,KAAK,QAAQ;AAC7B;AAKO,IAAM,gBAAgB,OAAO,YAAoB,IAAY,YAAoB;AACtF,kBAAgB,UAAU;AAC1B,QAAM,UAAU,gBAAiB,IAAI,EAAE;AACvC,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO;AAClD;AAEO,IAAM,eAAe,OAAO,YAAoB,IAAY,YAAkD;AACnH,kBAAgB,UAAU;AAE1B,QAAM,UAAU,gBAAiB,IAAI,EAAE;AACvC,MAAI,CAAC,WAAW,QAAQ,WAAW,EAAG,QAAO;AAE7C,QAAM,cAAc,QAAQ,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW;AAEtD,MAAI,CAAC,WAAW,YAAY,UAAU;AACpC,WAAO,aAAa;AAAA,EACtB;AAGA,QAAM,aAAa,QAAQ,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO;AAC5D,MAAI,WAAY,QAAO,WAAW;AAGlC,QAAM,cAAcC,YAAW,OAAO;AACtC,MAAI,aAAa;AACf,UAAM,QAAQ,QAAQ,KAAK,CAAC,MAAM;AAChC,UAAI;AACF,eAAOC,WAAU,EAAE,SAAS,WAAW;AAAA,MACzC,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AACD,WAAO,OAAO;AAAA,EAChB;AAEA,SAAO;AACT;AAEO,IAAM,WAAW,OAAO,SAAiB,SAA4B,OAAO;AACjF,MAAI;AAEF,UAAM,yBAAyB,UAAU,OAAO;AAIhD,UAAM,kBAAkB;AAAA,MACtB,uBAAuB,SAAS,IAAI,IAAI,uBAAuB,MAAM,IAAI,EAAE,CAAC,IAAI,QAAQ,sBAAsB;AAAA,IAChH;AAIA,QAAI,kBAAkB,SAAS,iBAAiB,sBAAsB;AAStE,sBAAkB,gBAAgB,QAAQ,OAAO,GAAG;AAEpD,UAAM,aAAa,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AAE3D,UAAM,QAAQC,UAAS,iBAAiB;AAAA,MACtC,KAAK;AAAA,MACL,QAAQ,CAAC,mBAAmB,GAAG,UAAU;AAAA,MACzC,UAAU;AAAA,MACV,OAAO;AAAA,IACT,CAAC;AAGD,WAAO,MAAM,IAAI,SAAS;AAAA,EAC5B,SAAS,OAAY;AAEnB,UAAM,0BAA0B;AAAA,MAC9B,UAAU,OAAO,EAAE,SAAS,IAAI,IAAI,UAAU,OAAO,EAAE,MAAM,IAAI,EAAE,CAAC,IAAI,QAAQ,UAAU,OAAO,CAAC;AAAA,IACpG;AACA,UAAM,0BAA0B,SAAS,yBAAyB,UAAU,OAAO,CAAC,EAAE,QAAQ,OAAO,GAAG;AACxG,UAAM,IAAI;AAAA,MACR,oCAAoC,OAAO,kBAAkB,uBAAuB,oBAAoB,uBAAuB,OAAO,MAAM,OAAO;AAAA,IACrJ;AAAA,EACF;AACF;AAEO,IAAM,cAAc,OAAOC,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;AAEvF,QAAM,YAAY,GAAG,QAAQ,uBAAuB,MAAM;AAC1D,QAAM,UAAU,IAAI,OAAO,yBAAyB,SAAS,cAAc,GAAG;AAE9E,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;;;AClUA,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAW9B,OAAOC,aAAY;AACnB,OAAO,QAAQ;AACf,OAAOC,aAAY;AAEnB,SAAS,aAAAC,kBAAiB;AAC1B,SAAS,MAAM,cAAc;AAC7B,SAAS,YAAAC,iBAAgB;AACzB,OAAO,UAAU;AAIV,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;AAE3B,QAAM,kBAAkBC,SAAQ,IAAI,EAAE,QAAQ,mCAAmC,KAAK,GAAG;AACzF,QAAM,EAAE,MAAM,EAAE,UAAU,QAAQ,IAAI,CAAC,EAAE,IAAIJ,QAAO,KAAK,IAAI;AAC7D,QAAM,kBAAkB,sBAAsB,iBAAiB,OAAO;AAEtE,EAAAC,QAAO,UAAU,iBAAiB,EAAE,WAAW,KAAK,CAAC;AAErD,QAAM,mBAAmB,CAAC,UAAU,YAAY,WAAW,WAAW;AAGtE,QAAM,QAAQ,YAAY,iBAAiB,iBAAiB,CAAC,QAAQ;AAEnE,UAAM,aAAaE,UAAS,GAAG;AAE/B,QAAI,iBAAiB,SAAS,UAAU,GAAG;AACzC,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,CAAC;AAGD,QAAM,GAAG,QAAQ,eAAe,EAAE,KAAK,OAAO,kBAAkB;AAC9D,UAAM,QAAQ;AAAA,MACZ,cAAc,IAAI,OAAOE,UAAS;AAEhC,YAAI,iBAAiB,SAASA,KAAI,GAAG;AACnC;AAAA,QACF;AACA,YAAIA,UAAS,aAAa;AACxB,UAAAJ,QAAO,OAAOK,MAAK,iBAAiBD,KAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,QAChE;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,sBAAoB;AACtB;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,EAAAN,QAAO,UAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AAG9C,QAAM,WAAWK,MAAK,UAAU,SAAS,MAAM,EAAE;AAGjD,MAAI,CAACL,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;AACvC,yBAAqB,YAAY,UAAU,QAAQ;AAAA,EACrD,UAAE;AAEA,UAAM,OAAO,QAAQ,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACvC;AACF;AAEO,IAAM,cAAc,OACzB,YACA,IACA,SACA,SACA,aACkC;AAClC,QAAM,eAAe,SAAS,gBAAgB;AAC9C,QAAM,OAAO,aAAa,KAAK,MAAM,aAAa,YAAY,IAAI,OAAO,IAAI;AAC7E,MAAI,CAAC,QAAQ,CAACA,QAAO,WAAW,IAAI,EAAG;AAEvC,QAAM,EAAE,MAAM,QAAQ,IAAI,iBAAiB,IAAI;AAE/C,MAAI,gBAAgB,MAAM,YAAY;AACpC,UAAM,oBAAoBG,SAAQ,IAAI;AACtC,UAAM,eAAeE,MAAK,mBAAmB,KAAK,UAAU;AAC5D,QAAIL,QAAO,WAAW,YAAY,GAAG;AACnC,YAAM,SAASA,QAAO,aAAa,cAAc,MAAM;AAEvD,UAAI;AACF,aAAK,SAAS,KAAK,MAAM,MAAM;AAAA,MACjC,SAAS,OAAO;AACd,aAAK,SAAS;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAEA,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,wBAAwB,OAAO,YAAoB,IAAY,YAAqB;AAC/F,QAAM,QAAQ,MAAM,gBAAgB,YAAY,IAAI,OAAO;AAC3D,MAAI,CAAC,MAAO;AACZ,SAAO,OAAO,UAAU,MAAM,KAAK,GAAG,EAAE,OAAO,OAAO,EAAE,IAAI;AAC9D;AAEO,IAAM,aAAa,OAAO,YAAoB,gBAAwB;AAC3E,QAAM,EAAE,MAAM,QAAQ,IAAIJ,QAAO,WAAW;AAC5C,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU,QAAQ,KAAK;AAAA,EACzB;AACF;AAEO,IAAM,eAAe,OAC1B,YACA;AAAA,EACE;AAAA,EACA,aAAa;AAAA,EACb,SAAS,CAAC;AAAA,EACV,UAAU;AAAA,EACV,eAAe;AACjB,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,IAAI,iBAAiB,IAAI;AAG/C,QAAI,gBAAgB,MAAM,YAAY;AACpC,YAAM,oBAAoBI,SAAQ,IAAI;AACtC,YAAM,eAAeE,MAAK,mBAAmB,KAAK,UAAU;AAC5D,UAAIL,QAAO,WAAW,YAAY,GAAG;AACnC,cAAM,SAASA,QAAO,aAAa,cAAc,MAAM;AAEvD,YAAI;AACF,eAAK,SAAS,KAAK,MAAM,MAAM;AAAA,QACjC,SAAS,OAAO;AACd,eAAK,SAAS;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AACA,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;AAErC,cAAM,mBAAmB,IAAI;AAAA,MAC/B,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;AAEvD,cAAM,mBAAmB,SAAS;AAAA,MACpC,CAAC;AAAA,IACH;AAAA,EACF;AAEA,sBAAoB;AACtB;AAGA,IAAM,qBAAqB,OAAOG,OAAc,aAAqB,IAAI,QAAgB,OAAsB;AAC7G,WAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,QAAI;AACF,YAAM,GAAG,OAAOA,KAAI;AAEpB,YAAM,IAAI,QAAQ,CAACC,aAAY,WAAWA,UAAS,KAAK,CAAC;AAAA,IAC3D,SAAS,OAAO;AAEd;AAAA,IACF;AAAA,EACF;AAEA,QAAM,IAAI,MAAM,kBAAkBD,KAAI,0BAA0B,UAAU,WAAW;AACvF;AAEO,IAAM,oBAAoB,OAC/B,YACA,IACA,MACA,SACA,YACG;AACH,MAAI;AAEJ,MAAI,SAAS,MAAM;AACjB,qBAAiBD,MAAK,YAAY,QAAQ,MAAM,WAAW;AAAA,EAC7D,OAAO;AAEL,qBAAiB,MAAM,aAAa,YAAY,IAAI,OAAO;AAAA,EAC7D;AAEA,MAAI,CAAC,eAAgB,OAAM,IAAI,MAAM,wCAAwC;AAG7E,EAAAL,QAAO,UAAU,KAAK,QAAQ,cAAc,GAAG,EAAE,WAAW,KAAK,CAAC;AAElE,MAAI,cAAc,KAAK,QAAQ,KAAK;AAEpC,MAAI;AACF,UAAM,OAAO,KAAK,MAAM,WAAW;AACnC,kBAAc,KAAK,UAAU,MAAM,MAAM,CAAC;AAAA,EAC5C,SAAS,OAAO;AAAA,EAGhB;AAEA,EAAAA,QAAO,cAAcK,MAAKF,SAAQ,cAAc,GAAG,KAAK,QAAQ,GAAG,WAAW;AAChF;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,SAAOH,QAAO,aAAaK,MAAKF,SAAQ,cAAc,GAAG,KAAK,QAAQ,GAAG,OAAO;AAClF;AACO,IAAM,wBAAwB,CAAC,iBAAyB,YAAyB;AACtF,SAAOE,MAAK,iBAAiB,aAAa,OAAO;AACnD;AAEO,IAAM,kBAAkB,OAAO,YAAoB,IAAY,YAAqB;AACzF,QAAM,WAAW,MAAM,YAAY,YAAY,IAAI,OAAO;AAC1D,MAAI,CAAC,SAAU,QAAO;AAEtB,QAAM,iBAAiB,MAAM,gBAAgB,YAAY,IAAI,OAAO;AAEpE,SAAO,CAAC,gBAAgB,aAAa,QAAQ,OAAO,GAAG,EAAE,SAAS,aAAa;AACjF;;;AFlTO,IAAM,WACX,CAAC,cACD,OAAO,IAAY,SAAkB,YACnC,YAAY,WAAW,IAAI,SAAS,EAAE,MAAM,SAAS,GAAG,QAAQ,CAAC;AAuB9D,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,UAAwE,EAAE,MAAM,IAAI,QAAQ,OAAO,UAAU,MAAM,MAChH;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,iBAAeG,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;AACtD,sBAAoB;AACtB;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,cACD,OAAO,IAAY,MAA6C,SAAkB,YAChF,kBAAkB,WAAW,IAAI,MAAM,SAAS,OAAO;AAoCpD,IAAM,mBACX,CAAC,cACD,OAAO,IAAY,QAA8C,SAAkB,YAAgC;AACjH,QAAM,eAAe,SAAS,EAAE,IAAI,EAAE,SAAS,OAAO,QAAQ,UAAU,OAAO,SAAS,GAAG,SAAS,OAAO;AAC7G;AAkBK,IAAM,kBAAkB,CAAC,cAAsB,OAAO,IAAY,YAAqB;AAC5F,QAAM,OAAO,MAAM,aAAa,WAAW,IAAI,OAAO;AACtD,SAAO,CAAC,CAAC;AACX;;;AG3TA,OAAOE,SAAQ;AACf,SAAS,QAAAC,aAAY;AAmCd,IAAM,aACX,CAAC,cACD,OAAO,IAAY,SAAkB,YACnC,YAAY,WAAW,IAAI,SAAS,EAAE,MAAM,WAAW,GAAG,QAAQ,CAAC;AAuBhE,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,UAAwE,EAAE,MAAM,IAAI,QAAQ,OAAO,UAAU,MAAM,MAChH;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;AACtD,sBAAoB;AACtB;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,cACD,OAAO,IAAY,MAA6C,SAAkB,YAChF,kBAAkB,WAAW,IAAI,MAAM,SAAS,OAAO;AAoCpD,IAAM,qBACX,CAAC,cACD,OAAO,IAAY,QAA8C,SAAkB,YAAgC;AACjH,QAAM,iBAAiB,SAAS,EAAE,IAAI,EAAE,SAAS,OAAO,QAAQ,UAAU,OAAO,SAAS,GAAG,SAAS,OAAO;AAC/G;AAkBK,IAAM,oBAAoB,CAAC,cAAsB,OAAO,IAAY,YAAqB;AAC9F,QAAM,OAAO,MAAM,aAAa,WAAW,IAAI,OAAO;AACtD,SAAO,CAAC,CAAC;AACX;;;AC5TA,OAAOE,SAAQ;AACf,SAAS,QAAAC,aAAY;AAkCd,IAAM,WACX,CAAC,cACD,OAAO,IAAY,SAAkB,YACnC,YAAY,WAAW,IAAI,SAAS,EAAE,MAAM,SAAS,GAAG,QAAQ,CAAC;AAsD9D,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;AAuBjE,IAAM,aACX,CAAC,cACD,OAAO,YACL,aAAa,WAAW,EAAE,MAAM,WAAW,GAAG,QAAQ,CAAC;AAwBpD,IAAM,sBACX,CAAC,cACD,OACE,OACA,SACA,UAAwE,EAAE,MAAM,IAAI,QAAQ,OAAO,UAAU,MAAM,MAChH;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;AACtD,sBAAoB;AACtB;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,cACD,OAAO,IAAY,MAA6C,SAAkB,YAChF,kBAAkB,WAAW,IAAI,MAAM,SAAS,OAAO;AAoCpD,IAAM,mBACX,CAAC,cACD,OAAO,IAAY,QAA8C,SAAkB,YAAgC;AACjH,QAAM,eAAe,SAAS,EAAE,IAAI,EAAE,SAAS,OAAO,QAAQ,UAAU,OAAO,SAAS,GAAG,SAAS,OAAO;AAC7G;AAkBK,IAAM,kBAAkB,CAAC,cAAsB,OAAO,IAAY,YAAqB;AAC5F,QAAM,OAAO,MAAM,aAAa,WAAW,IAAI,OAAO;AACtD,SAAO,CAAC,CAAC;AACX;;;AC3TA,OAAOE,SAAQ;AACf,SAAS,QAAAC,OAAM,WAAAC,UAAS,SAAS,YAAAC,iBAAgB;AAiC1C,IAAM,aACX,CAAC,cACD,OAAO,IAAY,YACjB,YAAY,WAAW,IAAI,SAAS,EAAE,MAAM,UAAU,CAAC;AAepD,IAAM,mBAAmB,CAAC,cAAsB,OAAOC,UAAiB;AAC7E,QAAM,UAAU,MAAM,YAAY,WAAW,QAAW,QAAW,EAAE,MAAM,UAAU,GAAGA,KAAI;AAC5F,SAAO;AACT;AAoBO,IAAM,cACX,CAAC,cACD,OAAO,YACL,aAAa,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,QAAQ;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,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,KAA0C;AAAA,EACpF;AAEA,MAAI,MAAM,QAAQ,QAAQ,QAAQ,GAAG;AACnC,aAAS,WAAW,eAAe,QAAQ,QAA6C;AAAA,EAC1F;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,QAAMA,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,UAAwE,EAAE,MAAM,IAAI,QAAQ,OAAO,UAAU,MAAM,MAChH;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;AACtD,sBAAoB;AACtB;AAoBO,IAAM,gBAAgB,CAAC,cAAsB,OAAO,IAAY,SAAkB,iBAA2B;AAClH,QAAM,eAAe,WAAW,IAAI,SAAS,EAAE,MAAM,WAAW,aAAa,CAAC;AAChF;AAsBO,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,QAAI;AAEJ,QAAI,MAAM,QAAQ,qBAAqB,GAAG;AACxC,2BAAqB,sBAAsB,IAAI,CAAC,UAAU,EAAE,KAAK,KAAK,MAAM,MAAM,KAAK,KAAK,EAAE;AAAA,IAChG,OAAO;AACL,2BAAqB,OAAO,KAAK,qBAAqB,EAAE,IAAI,CAAC,UAAU;AAAA,QACrE,KAAK;AAAA,QACL,MAAM,sBAAsB,IAA4B;AAAA,MAC1D,EAAE;AAAA,IACJ;AAEA,UAAM,WAAW,mBAAmB,IAAI,OAAO,EAAE,KAAK,MAAM,SAAS,MAAM;AACzE,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,SAAS,SAAS,UAAoB,MAAMC,MAAKE,SAAQ,iBAAiB,GAAG,QAAQ,EAAE;AAAA,IACvG,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,gBAAgB,EAAE,CAAC;AACvD,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;AAeO,IAAM,YAAY,CAAC,cAAsB,OAAOA,UAAiB;AACtE,QAAM,UAAU,MAAM,iBAAiB,SAAS,EAAEA,KAAI;AAEtD,QAAM,eAAeI,UAAS,WAAWJ,KAAI;AAG7C,QAAM,WAAW,aAAa,MAAM,QAAQ;AAG5C,SAAO,CAAC,CAAC,WAAW,SAAS,SAAS,UAAU;AAClD;AAoBO,IAAM,YAAY,CAAC,cAAsB,OAAO,SAAiB,WAAW,WAAW,IAAI;AAmB3F,IAAM,qBACX,CAAC,cAAsB,OAAO,IAAY,QAAyC,YAAqB;AACtG,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,QAAQ,aAAa,QAAW;AAClC,YAAQ,WAAW,CAAC;AAAA,EACtB;AAGA,WAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,QAAQ,KAAK;AAChD,QAAI,QAAQ,SAAS,CAAC,EAAE,OAAO,OAAO,MAAM,QAAQ,SAAS,CAAC,EAAE,YAAY,OAAO,SAAS;AAC1F;AAAA,IACF;AAAA,EACF;AAEA,UAAQ,SAAS,KAAK,EAAE,IAAI,OAAO,IAAI,SAAS,OAAO,QAAQ,CAAC;AAEhE,QAAM,mBAAmB,MAAM,aAAa,WAAW,IAAI,OAAO;AAElE,MAAI,CAAC,kBAAkB;AACrB,UAAM,IAAI,MAAM,uBAAuB,EAAE,iBAAiB;AAAA,EAC5D;AAGA,QAAMA,QAAO,iBAAiB,MAAM,gBAAgB,EAAE,CAAC;AACvD,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;AAuBK,IAAM,wBACX,CAAC,cACD,OAAO,IAAY,WAAqC,WAA4C,YAAqB;AACvH,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,YAAY;AAC5B,QAAI,QAAQ,aAAa,QAAW;AAClC,cAAQ,WAAW,CAAC;AAAA,IACtB;AAGA,aAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,QAAQ,KAAK;AAChD,UAAI,QAAQ,SAAS,CAAC,EAAE,OAAO,UAAU,MAAM,QAAQ,SAAS,CAAC,EAAE,YAAY,UAAU,SAAS;AAChG;AAAA,MACF;AAAA,IACF;AAEA,YAAQ,SAAS,KAAK,EAAE,IAAI,UAAU,IAAI,SAAS,UAAU,QAAQ,CAAC;AAAA,EACxE,WAAW,cAAc,aAAa;AACpC,QAAI,QAAQ,cAAc,QAAW;AACnC,cAAQ,YAAY,CAAC;AAAA,IACvB;AAGA,aAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,KAAK;AACjD,UAAI,QAAQ,UAAU,CAAC,EAAE,OAAO,UAAU,MAAM,QAAQ,UAAU,CAAC,EAAE,YAAY,UAAU,SAAS;AAClG;AAAA,MACF;AAAA,IACF;AACA,YAAQ,UAAU,KAAK,EAAE,IAAI,UAAU,IAAI,SAAS,UAAU,QAAQ,CAAC;AAAA,EACzE,OAAO;AACL,UAAM,IAAI,MAAM,aAAa,SAAS,4DAA4D;AAAA,EACpG;AAEA,QAAM,mBAAmB,MAAM,aAAa,WAAW,IAAI,OAAO;AAElE,MAAI,CAAC,kBAAkB;AACrB,UAAM,IAAI,MAAM,uBAAuB,EAAE,iBAAiB;AAAA,EAC5D;AAGA,QAAMA,QAAO,iBAAiB,MAAM,gBAAgB,EAAE,CAAC;AACvD,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;;;ACpnBF,OAAOK,SAAQ;AACf,OAAOC,SAAQ,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,eAAe,gBAAgB;AAAA,EAC7G,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,QAA6C;AAAA,EACzF;AAEA,MAAI,MAAM,QAAQ,OAAO,OAAO,GAAG;AACjC,aAAS,UAAU,eAAe,OAAO,OAA4C;AAAA,EACvF;AAEA,MAAI,MAAM,QAAQ,OAAO,KAAK,GAAG;AAC/B,aAAS,QAAQ,eAAe,OAAO,KAA0C;AAAA,EACnF;AAEA,MAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG;AAClC,aAAS,WAAW,eAAe,OAAO,QAA6C;AAAA,EACzF;AAEA,MAAI,MAAM,QAAQ,OAAO,YAAY,GAAG;AACtC,aAAS,eAAe,eAAe,OAAO,YAAiD;AAAA,EACjG;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;AACtD,sBAAoB;AACtB;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,2BAA2BC,MAAK,KAAKA,MAAK,QAAQ,YAAY,GAAG,yBAAyB;AAEhG,QAAM,aAAaG,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,YAAYH,MAAK,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;AAoBK,IAAM,uBACX,CAAC,cAAsB,OAAO,IAAY,WAA4C,YAAqB;AACzG,MAAI,SAAiB,MAAM,UAAU,SAAS,EAAE,IAAI,OAAO;AAC3D,QAAM,aAAa,MAAM,gBAAgB,WAAW,IAAI,OAAO;AAG/D,QAAM,YAAYA,MAAK,QAAQ,YAAY,YAAY,EAAE;AAEzD,MAAI,OAAO,YAAY,QAAW;AAChC,WAAO,UAAU,CAAC;AAAA,EACpB;AAEA,QAAM,wBAAwB,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU,MAAM,EAAE,YAAY,UAAU,OAAO;AAEjH,MAAI,uBAAuB;AACzB;AAAA,EACF;AAGA,SAAO,QAAQ,KAAK,SAAS;AAE7B,QAAM,aAAa,SAAS,EAAE,IAAI,SAAS,IAAI;AAC/C,QAAM,YAAY,SAAS,EAAE,QAAQ,EAAE,QAAQ,cAAc,QAAQ,OAAO,MAAM,CAAC;AACrF;AAmBK,IAAM,oBACX,CAAC,cAAsB,OAAO,IAAY,QAAyC,YAAqB;AACtG,MAAI,SAAiB,MAAM,UAAU,SAAS,EAAE,IAAI,OAAO;AAC3D,QAAM,aAAa,MAAM,gBAAgB,WAAW,IAAI,OAAO;AAG/D,QAAM,YAAYA,MAAK,QAAQ,YAAY,YAAY,EAAE;AAEzD,MAAI,OAAO,aAAa,QAAW;AACjC,WAAO,WAAW,CAAC;AAAA,EACrB;AAEA,QAAM,qBAAqB,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO,MAAM,EAAE,YAAY,OAAO,OAAO;AAEzG,MAAI,oBAAoB;AACtB;AAAA,EACF;AAGA,SAAO,SAAS,KAAK,MAAM;AAE3B,QAAM,aAAa,SAAS,EAAE,IAAI,SAAS,IAAI;AAC/C,QAAM,YAAY,SAAS,EAAE,QAAQ,EAAE,QAAQ,cAAc,QAAQ,OAAO,MAAM,CAAC;AACrF;AAmBK,IAAM,yBACX,CAAC,cAAsB,OAAO,IAAY,aAA8C,YAAqB;AAC3G,MAAI,SAAiB,MAAM,UAAU,SAAS,EAAE,IAAI,OAAO;AAC3D,QAAM,aAAa,MAAM,gBAAgB,WAAW,IAAI,OAAO;AAG/D,QAAM,YAAYA,MAAK,QAAQ,YAAY,YAAY,EAAE;AAEzD,MAAI,OAAO,iBAAiB,QAAW;AACrC,WAAO,eAAe,CAAC;AAAA,EACzB;AAEA,QAAM,0BAA0B,OAAO,aAAa;AAAA,IAClD,CAAC,OAAO,GAAG,OAAO,YAAY,MAAM,GAAG,YAAY,YAAY;AAAA,EACjE;AAEA,MAAI,yBAAyB;AAC3B;AAAA,EACF;AAGA,SAAO,aAAa,KAAK,WAAW;AAEpC,QAAM,aAAa,SAAS,EAAE,IAAI,SAAS,IAAI;AAC/C,QAAM,YAAY,SAAS,EAAE,QAAQ,EAAE,QAAQ,cAAc,QAAQ,OAAO,MAAM,CAAC;AACrF;AA2BK,IAAM,qBACX,CAAC,cAAsB,OAAO,IAAY,WAAmB,SAA0C,YAAqB;AAC1H,MAAI,SAAiB,MAAM,UAAU,SAAS,EAAE,IAAI,OAAO;AAC3D,QAAM,aAAa,MAAM,gBAAgB,WAAW,IAAI,OAAO;AAC/D,QAAM,YAAYA,MAAK,QAAQ,YAAY,YAAY,EAAE;AAEzD,MAAI,cAAc,SAAS;AACzB,QAAI,OAAO,UAAU,QAAW;AAC9B,aAAO,QAAQ,CAAC;AAAA,IAClB;AAEA,aAAS,IAAI,GAAG,IAAI,OAAO,MAAM,QAAQ,KAAK;AAC5C,UAAI,OAAO,MAAM,CAAC,EAAE,OAAO,QAAQ,MAAM,OAAO,MAAM,CAAC,EAAE,YAAY,QAAQ,SAAS;AACpF;AAAA,MACF;AAAA,IACF;AACA,WAAO,MAAM,KAAK,EAAE,IAAI,QAAQ,IAAI,SAAS,QAAQ,QAAQ,CAAC;AAAA,EAChE,WAAW,cAAc,YAAY;AACnC,QAAI,OAAO,aAAa,QAAW;AACjC,aAAO,WAAW,CAAC;AAAA,IACrB;AAEA,aAAS,IAAI,GAAG,IAAI,OAAO,SAAS,QAAQ,KAAK;AAC/C,UAAI,OAAO,SAAS,CAAC,EAAE,OAAO,QAAQ,MAAM,OAAO,SAAS,CAAC,EAAE,YAAY,QAAQ,SAAS;AAC1F;AAAA,MACF;AAAA,IACF;AACA,WAAO,SAAS,KAAK,EAAE,IAAI,QAAQ,IAAI,SAAS,QAAQ,QAAQ,CAAC;AAAA,EACnE,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,sBAAsB,EAAE,iBAAiB;AAAA,EAC3D;AAIA,QAAM,iBAAiB,iBAAiB,QAAQ,OAAO,GAAG;AAC1D,QAAM,mBAAmB,eAAe,YAAY,WAAW;AAC/D,QAAM,iBAAiB,iBAAiB,UAAU,GAAG,mBAAmB,WAAW,MAAM;AAEzF,QAAM,aAAa,SAAS,EAAE,IAAI,SAAS,IAAI;AAC/C,QAAM,YAAY,cAAc,EAAE,QAAQ,EAAE,QAAQ,cAAc,QAAQ,OAAO,MAAM,CAAC;AAC1F;;;ACjjBF,OAAOI,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;AACtD,sBAAoB;AACtB;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,YAAAG,aAAY,eAAe,aAAa,IAAI,UAAU,UAAoC;AAElG,QAAM,UAAU,MAAMA,YAAW,SAAS,EAAE,SAAS,IAAI,SAAS,OAAO;AACzE,QAAM,cAAc,MAAM,gBAAgB,WAAW,SAAS,IAAI,SAAS,OAAO;AAClF,QAAM,YAAYC,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,QAAMJ,QAAO,iBAAiB,MAAM,UAAU,UAAU,EAAE,EAAE,CAAC;AAC7D,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;;;AC1RF,SAAS,WAAAK,UAAS,QAAAC,aAAY;AAC9B,OAAOC,aAAY;AAEnB,OAAOC,aAAY;AAInB,SAAS,aAAAC,YAAW,cAAAC,mBAAkB;AAgB/B,IAAM,yBACX,CAAC,cACD,OAAOC,OAAc,YAA2D;AAC9E,QAAM,gBAAgBC,SAAQD,KAAI;AAClC,MAAI;AACF,UAAM,QAAQ,MAAM,SAAS,GAAG,SAAS,IAAI,aAAa,iBAAiB;AAE3E,QAAI,CAAC,SAAS,MAAM,WAAW,GAAG;AAChC,YAAM,IAAI,MAAM,0EAA0E,aAAa,EAAE;AAAA,IAC3G;AACA,UAAM,cAAc,MAAM,CAAC;AAE3B,UAAM,EAAE,KAAK,IAAIE,QAAO,KAAK,WAAW;AACxC,UAAM,EAAE,IAAI,QAAQ,IAAI;AAExB,QAAI,CAAC,MAAM,CAAC,SAAS;AACnB,YAAM,IAAI,MAAM,8BAA8B,WAAW,mDAAmD;AAAA,IAC9G;AAEA,UAAM,UAAU,MAAM,YAAY,WAAW,IAAI,SAAS,EAAE,MAAM,WAAW,GAAG,QAAQ,CAAC;AAEzF,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,6BAA6B,EAAE,kBAAkB,OAAO,iCAAiC,WAAW,GAAG;AAAA,IACzH;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AAEd,QAAI,iBAAiB,OAAO;AAE1B,YAAM,UAAU,mCAAmC,aAAa,KAAK,MAAM,OAAO;AAClF,YAAM;AAAA,IACR;AACA,UAAM,IAAI,MAAM,mCAAmC,aAAa,2BAA2B;AAAA,EAC7F;AACF;AAcK,IAAM,qCACX,CAAC,cACD,OACE,IACA,SACA,YAC4D;AAC5D,QAAM,WAAW,MAAM,YAAY,SAAS,EAAE,EAAE,YAAY,SAAS,cAAc,KAAK,CAAC;AACzF,QAAM,UAAW,MAAM,YAAY,WAAW,IAAI,SAAS,EAAE,MAAM,UAAU,CAAC;AAC9E,QAAM,yBAAyB,MAAM,gBAAgB,WAAW,IAAI,OAAO;AAE3E,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,6BAA6B,EAAE,kBAAkB,OAAO,cAAc;AAAA,EACxF;AAEA,QAAM,YAAuB,CAAC;AAC9B,QAAM,YAAuB,CAAC;AAE9B,aAAW,WAAW,UAAU;AAC9B,UAAM,0BAA0B,QAAQ,OAAO,KAAK,CAAC,aAAa;AAChE,UAAI,SAAS,SAAS;AACpB,cAAM,4BAA4BH,YAAW,SAAS,OAAO;AAC7D,YAAI,2BAA2B;AAC7B,iBAAO,SAAS,OAAO,QAAQ,MAAMD,WAAU,QAAQ,SAAS,SAAS,OAAO;AAAA,QAClF,OAAO;AACL,iBAAO,SAAS,OAAO,QAAQ,MAAM,QAAQ,YAAY,SAAS;AAAA,QACpE;AAAA,MACF;AACA,UAAI,0BAA0B,SAAS,OAAO,QAAQ,IAAI;AACxD,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,CAAC;AACD,UAAM,6BAA6B,QAAQ,UAAU,KAAK,CAAC,aAAa;AACtE,UAAI,SAAS,SAAS;AACpB,cAAM,4BAA4BC,YAAW,SAAS,OAAO;AAC7D,YAAI,2BAA2B;AAC7B,iBAAO,SAAS,OAAO,QAAQ,MAAMD,WAAU,QAAQ,SAAS,SAAS,OAAO;AAAA,QAClF,OAAO;AACL,iBAAO,SAAS,OAAO,QAAQ,MAAM,QAAQ,YAAY,SAAS;AAAA,QACpE;AAAA,MACF;AACA,UAAI,0BAA0B,SAAS,OAAO,QAAQ,IAAI;AACxD,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,CAAC;AAED,QAAI,yBAAyB;AAC3B,gBAAU,KAAK,OAAO;AAAA,IACxB;AACA,QAAI,4BAA4B;AAC9B,gBAAU,KAAK,OAAO;AAAA,IACxB;AAAA,EACF;AAEA,SAAO,EAAE,WAAW,UAAU;AAChC;AAcK,IAAM,uBAAuB,CAAC,cAAsB,OAAOE,UAAiB;AACjF,MAAI;AACF,UAAM,UAAU,MAAM,uBAAuB,SAAS,EAAEA,KAAI;AAC5D,UAAM,EAAE,UAAU,IAAI,MAAM,mCAAmC,SAAS,EAAE,QAAQ,IAAI,QAAQ,OAAO;AACrG,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO,CAAC;AAAA,EACV;AACF;AAcO,IAAM,uBAAuB,CAAC,cAAsB,OAAOA,UAAiB;AACjF,MAAI;AACF,UAAM,UAAU,MAAM,uBAAuB,SAAS,EAAEA,KAAI;AAC5D,UAAM,EAAE,UAAU,IAAI,MAAM,mCAAmC,SAAS,EAAE,QAAQ,IAAI,QAAQ,OAAO;AACrG,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO,CAAC;AAAA,EACV;AACF;AAoBO,IAAM,sBACX,CAAC,cACD,OAAO,IAAY,YAAgF;AACjG,QAAM,OAAO,MAAM,aAAa,WAAW,IAAI,OAAO;AACtD,MAAI,CAAC,QAAQ,CAACG,QAAO,WAAW,IAAI,EAAG,QAAO;AAE9C,QAAM,EAAE,KAAK,IAAID,QAAO,KAAK,IAAI;AAEjC,MAAI,CAAC,KAAK,WAAY,QAAO;AAE7B,QAAM,oBAAoBD,SAAQ,IAAI;AACtC,QAAM,eAAeG,MAAK,mBAAmB,KAAK,UAAU;AAE5D,MAAI,CAACD,QAAO,WAAW,YAAY,EAAG,QAAO;AAE7C,QAAM,SAASA,QAAO,aAAa,cAAc,MAAM;AAEvD,SAAO;AAAA,IACL;AAAA,IACA,UAAU,KAAK;AAAA,EACjB;AACF;;;ACrNF,OAAOE,SAAQ,QAAAC,cAAY;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;AACvC,sBAAoB;AACtB;AAgBK,IAAM,cAAc,CAAC,cAAsB,OAAO,aAAqB;AAC5E,QAAM,gBAAgB,SAAS,SAAS,MAAM,IAAI,WAAW,GAAG,QAAQ;AACxE,QAAME,IAAG,GAAGC,OAAK,WAAW,aAAa,GAAG,EAAE,WAAW,KAAK,CAAC;AAC/D,sBAAoB;AACtB;;;AC9HA,OAAOC,SAAQ;AACf,OAAOC,aAAY;AACnB,SAAS,QAAAC,cAAY;AAErB,OAAOC,aAAY;AAGnB,OAAOC,WAAU;;;ACNjB,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,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;AACzE,sBAAoB;AACtB;AAgBK,IAAM,aAAa,CAAC,eAAuB,OAAO,OAAe;AACtE,EAAAD,QAAO,OAAOC,OAAK,YAAY,GAAG,EAAE,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;AAChE,sBAAoB;AACtB;;;ADnHO,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,aAAa;AACvD,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;AACzE,sBAAoB;AACtB;AAgBK,IAAM,aAAa,CAAC,eAAuB,OAAO,OAAe;AACtE,QAAMC,IAAG,GAAGD,OAAK,YAAY,GAAG,EAAE,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9D,sBAAoB;AACtB;AAQO,IAAM,uBAAuB,CAAC,eAAuB,OAAO,IAAY,YAAqB;AAClG,QAAM,WAAW,MAAM,YAAY,YAAY,IAAI,OAAO;AAC1D,MAAI,SAAiB,CAAC;AACtB,MAAI,CAAC,SAAU,QAAO,CAAC;AAEvB,MAAI,CAAC,SAAS,OAAQ,QAAO,CAAC;AAG9B,aAAW,SAAS,SAAS,QAAQ;AACnC,UAAM,OAAO,MAAM,QAAQE,MAAK,KAAK,YAAY,OAAO,CAAC,EAAE,KAAK;AAChE,QAAI,MAAM;AACR,aAAO,KAAK,IAAI;AAAA,IAClB,OAAO;AAEL,YAAM,OAAO,MAAM,QAAQA,MAAK,KAAK,YAAY,OAAO,CAAC,EAAE,KAAK;AAChE,UAAI,MAAM;AACR,eAAO,KAAK,IAAI;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AE1KA,OAAOC,UAAQ;AACf,OAAOC,SAAQ,QAAAC,cAAY;AAI3B,IAAM,eAAe;AAErB,IAAM,yBAAyB,OAAO,eAAuB;AAE3D,MAAI;AACF,UAAM,cAAcC,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,YAAmB,CAAC,GACpB,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;AASO,IAAM,mCAAmC,CAAC,cAAsB,YAA0B;AAE/F,MAAI;AACF,UAAME,QAAOD,OAAK,WAAW,wBAAwB;AAErD,UAAM,eAAe,MAAM,OAAOC;AAClC,WAAO,aAAa;AAAA,EACtB,SAAS,OAAO;AACd,YAAQ,MAAM,kDAAkD,KAAK;AACrE,WAAO;AAAA,EACT;AACF;AAQO,IAAM,cACX,CAAC,cACD,OAAO,YAAmE;AACxE,QAAM,EAAE,YAAAC,aAAY,aAAAC,cAAa,WAAAC,YAAW,YAAAC,aAAY,aAAAC,cAAa,aAAAC,cAAa,UAAAC,WAAU,UAAAC,UAAS,IAAI,YAAM,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;;;AC9IF,OAAOG,UAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,gBAAgB;AACzB,SAAS,eAAe;;;ACGxB,IAAM,kBAAkB,CAAC,UAA2B;AAClD,MAAI,UAAU,QAAQ,UAAU,UAAa,OAAO,UAAU,UAAU;AACtE,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AACA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,MAAM,IAAI,eAAe,EAAE,KAAK,GAAG,IAAI;AAAA,EACtD;AACA,QAAM,SAAS,OAAO,KAAK,KAAgC,EACxD,KAAK,EACL,IAAI,CAAC,QAAQ,KAAK,UAAU,GAAG,IAAI,MAAM,gBAAiB,MAAkC,GAAG,CAAC,CAAC;AACpG,SAAO,MAAM,OAAO,KAAK,GAAG,IAAI;AAClC;AASA,IAAM,mBAAmB,CAAC,aAA8C;AACtE,QAAM,YAA4B,CAAC;AAEnC,QAAM,eAAe,CAAC,OAAkC,SAA+B;AACrF,eAAW,QAAQ,OAAO;AACxB,gBAAU,KAAK;AAAA,QACb,YAAY,KAAK;AAAA,QACjB,SAAS,KAAK;AAAA,QACd;AAAA,QACA,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AAEA,eAAa,SAAS,UAAU,SAAS,QAAQ;AACjD,eAAa,SAAS,UAAU,UAAU,SAAS;AACnD,eAAa,SAAS,UAAU,SAAS,QAAQ,OAAO;AACxD,eAAa,SAAS,UAAU,SAAS,UAAU,SAAS;AAC5D,eAAa,SAAS,UAAU,SAAS,SAAS,OAAO;AACzD,eAAa,SAAS,UAAU,UAAU,SAAS;AAEnD,SAAO;AACT;AAGA,IAAM,kBAAkB,oBAAI,IAAI,CAAC,YAAY,eAAe,CAAC;AAE7D,IAAM,sBAAsB,CAAC,SAA2D;AACtF,QAAM,SAAkC,CAAC;AACzC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,QAAI,CAAC,gBAAgB,IAAI,GAAG,GAAG;AAC7B,aAAO,GAAG,IAAI;AAAA,IAChB;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,oBAAoB,CAAC,OAAgC,UAA6C;AACtG,QAAM,UAAU,oBAAoB,KAAK;AACzC,QAAM,UAAU,oBAAoB,KAAK;AACzC,QAAM,UAAU,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK,OAAO,GAAG,GAAG,OAAO,KAAK,OAAO,CAAC,CAAC;AAC1E,QAAM,UAAoB,CAAC;AAE3B,aAAW,OAAO,SAAS;AACzB,QAAI,gBAAgB,QAAQ,GAAG,KAAK,IAAI,MAAM,gBAAgB,QAAQ,GAAG,KAAK,IAAI,GAAG;AACnF,cAAQ,KAAK,GAAG;AAAA,IAClB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAM,cAAc,CAAC,MAA4B,GAAG,EAAE,UAAU,IAAI,EAAE,OAAO;AAC7E,IAAM,YAAY,CAAC,MAA4B,GAAG,EAAE,UAAU,IAAI,EAAE,IAAI;AAEjE,IAAM,sBAAsB,CAAC,WAA4B,cAAiD;AAC/G,QAAM,aAAa,iBAAiB,SAAS;AAC7C,QAAM,aAAa,iBAAiB,SAAS;AAG7C,QAAM,OAAO,oBAAI,IAA0B;AAC3C,QAAM,QAAQ,oBAAI,IAA0B;AAC5C,aAAW,KAAK,YAAY;AAC1B,SAAK,IAAI,YAAY,CAAC,GAAG,CAAC;AAC1B,UAAM,IAAI,UAAU,CAAC,GAAG,CAAC;AAAA,EAC3B;AAEA,QAAM,OAAO,oBAAI,IAA0B;AAC3C,QAAM,QAAQ,oBAAI,IAA0B;AAC5C,aAAW,KAAK,YAAY;AAC1B,SAAK,IAAI,YAAY,CAAC,GAAG,CAAC;AAC1B,UAAM,IAAI,UAAU,CAAC,GAAG,CAAC;AAAA,EAC3B;AAEA,QAAM,UAA4B,CAAC;AACnC,QAAM,aAAa,oBAAI,IAAY;AAGnC,aAAW,YAAY,YAAY;AACjC,UAAM,MAAM,YAAY,QAAQ;AAChC,QAAI,CAAC,KAAK,IAAI,GAAG,GAAG;AAClB,YAAM,QAAQ,UAAU,QAAQ;AAChC,YAAM,cAAc,MAAM,IAAI,KAAK;AACnC,UAAI,eAAe,YAAY,YAAY,SAAS,WAAW,CAAC,WAAW,IAAI,KAAK,GAAG;AAErF,cAAM,gBAAgB,kBAAkB,YAAY,MAAM,SAAS,IAAI;AACvE,gBAAQ,KAAK;AAAA,UACX,YAAY,SAAS;AAAA,UACrB,SAAS,SAAS;AAAA,UAClB,MAAM,SAAS;AAAA,UACf,YAAY;AAAA,UACZ,iBAAiB,YAAY;AAAA,UAC7B,YAAY,SAAS;AAAA,UACrB,eAAe,cAAc,SAAS,IAAI,gBAAgB;AAAA,QAC5D,CAAC;AACD,mBAAW,IAAI,KAAK;AAAA,MACtB,WAAW,CAAC,WAAW,IAAI,KAAK,GAAG;AACjC,gBAAQ,KAAK;AAAA,UACX,YAAY,SAAS;AAAA,UACrB,SAAS,SAAS;AAAA,UAClB,MAAM,SAAS;AAAA,UACf,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,aAAW,YAAY,YAAY;AACjC,UAAM,MAAM,YAAY,QAAQ;AAChC,QAAI,CAAC,KAAK,IAAI,GAAG,GAAG;AAClB,YAAM,QAAQ,UAAU,QAAQ;AAChC,UAAI,CAAC,WAAW,IAAI,KAAK,GAAG;AAC1B,gBAAQ,KAAK;AAAA,UACX,YAAY,SAAS;AAAA,UACrB,SAAS,SAAS;AAAA,UAClB,MAAM,SAAS;AAAA,UACf,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,aAAW,aAAa,YAAY;AAClC,UAAM,MAAM,YAAY,SAAS;AACjC,UAAM,YAAY,KAAK,IAAI,GAAG;AAC9B,QAAI,WAAW;AACb,YAAM,gBAAgB,kBAAkB,UAAU,MAAM,UAAU,IAAI;AACtE,UAAI,cAAc,SAAS,GAAG;AAC5B,gBAAQ,KAAK;AAAA,UACX,YAAY,UAAU;AAAA,UACtB,SAAS,UAAU;AAAA,UACnB,MAAM,UAAU;AAAA,UAChB,YAAY;AAAA,UACZ;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAIA,IAAM,qBAAqB,CACzB,WACA,YACA,iBACA,cACW;AACX,SAAO,GAAG,SAAS,IAAI,SAAS,IAAI,UAAU,IAAI,mBAAmB,QAAQ;AAC/E;AAIA,IAAM,uBAAuB,CAAC,aAA6D;AACzF,QAAM,gBAAgB,oBAAI,IAA8B;AAExD,aAAW,WAAW,SAAS,UAAU,UAAU;AACjD,eAAW,aAAa,CAAC,SAAS,UAAU,GAAY;AACtD,YAAM,WAA8B,QAAgC,SAAS,KAAK,CAAC;AACnF,iBAAW,WAAW,UAAU;AAC9B,cAAM,MAAM,mBAAmB,QAAQ,IAAc,QAAQ,IAAI,QAAQ,SAAS,SAAS;AAC3F,sBAAc,IAAI,KAAK;AAAA,UACrB,WAAW,QAAQ;AAAA,UACnB,gBAAgB,QAAQ;AAAA,UACxB,YAAY,QAAQ;AAAA,UACpB,iBAAiB,QAAQ;AAAA,UACzB;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,IAAM,0BAA0B,CAAC,WAA4B,cAAqD;AACvH,QAAM,QAAQ,qBAAqB,SAAS;AAC5C,QAAM,QAAQ,qBAAqB,SAAS;AAE5C,QAAM,UAAgC,CAAC;AAGvC,aAAW,CAAC,KAAK,GAAG,KAAK,OAAO;AAC9B,QAAI,CAAC,MAAM,IAAI,GAAG,GAAG;AACnB,cAAQ,KAAK,EAAE,GAAG,KAAK,YAAY,QAAQ,CAAC;AAAA,IAC9C;AAAA,EACF;AAGA,aAAW,CAAC,KAAK,GAAG,KAAK,OAAO;AAC9B,QAAI,CAAC,MAAM,IAAI,GAAG,GAAG;AACnB,cAAQ,KAAK,EAAE,GAAG,KAAK,YAAY,UAAU,CAAC;AAAA,IAChD;AAAA,EACF;AAEA,SAAO;AACT;;;AD1NA,IAAM,mBAAmB;AAEzB,IAAMC,0BAAyB,CAAC,eAA+B;AAC7D,MAAI;AACF,UAAM,cAAcC,KAAG,aAAaC,MAAK,KAAK,YAAY,cAAc,GAAG,MAAM;AACjF,UAAM,oBAAoB,KAAK,MAAM,WAAW;AAChD,WAAO,kBAAkB,cAAc,IAAI,oBAAoB,KAAK;AAAA,EACtE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,IAAM,iBAAiB,CAAC,aAAuB;AAC7C,QAAM,SAAc,EAAE,IAAI,SAAS,IAAI,SAAS,SAAS,SAAS,MAAM,SAAS,KAAK;AACtF,MAAI,SAAS,MAAO,QAAO,QAAQ,SAAS;AAC5C,MAAI,SAAS,SAAU,QAAO,WAAW,SAAS;AAClD,MAAI,SAAS,WAAY,QAAO,aAAa,SAAS;AACtD,MAAI,SAAS,OAAQ,QAAO,SAAS,SAAS;AAC9C,SAAO;AACT;AAEA,IAAM,6BAA6B,CAAC,cAA4B;AAC9D,QAAM,OAAO,oBAAI,IAAiB;AAClC,aAAW,KAAK,WAAW;AACzB,UAAM,WAAW,KAAK,IAAI,EAAE,EAAE;AAC9B,QAAI,CAAC,YAAY,QAAQ,EAAE,SAAS,SAAS,OAAO,IAAI,GAAG;AACzD,WAAK,IAAI,EAAE,IAAI,CAAC;AAAA,IAClB;AAAA,EACF;AACA,SAAO,MAAM,KAAK,KAAK,OAAO,CAAC;AACjC;AAEA,IAAM,cAAc,CAAC,cAAwC;AAC3D,MAAI,CAAC,aAAa,UAAU,WAAW,EAAG,QAAO,CAAC;AAClD,SAAO,2BAA2B,SAAS,EAAE,IAAI,cAAc;AACjE;AAEA,IAAM,gBAAgB,CAAC,eAAuF;AAC5G,MAAI;AACF,UAAM,OAAO,EAAE,KAAK,YAAY,UAAU,QAAiB,OAAO,OAAgB;AAClF,UAAM,SAAS,SAAS,mCAAmC,IAAI,EAAE,KAAK;AACtE,UAAM,SAAS,SAAS,8BAA8B,IAAI,EAAE,KAAK;AACjE,UAAM,SAAS,SAAS,0BAA0B,IAAI,EAAE,KAAK;AAC7D,WAAO,EAAE,QAAQ,QAAQ,OAAO,OAAO,SAAS,EAAE;AAAA,EACpD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,IAAM,iBAAiB,CAAC,cAAsB;AAGnD,SAAO,OAAO,YAAuD;AACnE,UAAM,EAAE,OAAO,WAAW,IAAI,IAAI,WAAW,CAAC;AAC9C,UAAM,MAAM,YAAM,SAAS;AAG3B,UAAM,CAAC,SAAS,UAAU,QAAQ,UAAU,SAAS,QAAQ,IAAI,MAAM,QAAQ,IAAI;AAAA,MACjF,IAAI,WAAW;AAAA,MACf,IAAI,YAAY;AAAA,MAChB,IAAI,UAAU;AAAA,MACd,IAAI,YAAY;AAAA,MAChB,IAAI,WAAW;AAAA,MACf,IAAI,YAAY;AAAA,IAClB,CAAC;AAGD,UAAM,kBAAkB,YAAY,OAAO;AAC3C,UAAM,mBAAmB,YAAY,QAAQ;AAC7C,UAAM,iBAAiB,YAAY,MAAM;AACzC,UAAM,mBAAmB,YAAY,QAAQ;AAC7C,UAAM,kBAAkB,YAAY,OAAO;AAC3C,UAAM,mBAAmB,YAAY,QAAQ;AAE7C,UAAM,gBAAgB,UAAS,oBAAI,KAAK,GAAE,YAAY,EAAE,QAAQ,SAAS,GAAG;AAC5E,UAAM,UAAU,OAAO,cAAc,SAAS;AAE9C,UAAM,WAA4B;AAAA,MAChC,iBAAiB;AAAA,MACjB,gBAAgBF,wBAAuB,SAAS;AAAA,MAChD,OAAO;AAAA,MACP,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,GAAI,UAAU,EAAE,KAAK,QAAQ,IAAI,CAAC;AAAA,MAClC,WAAW;AAAA,QACT,SAAS;AAAA,QACT,UAAU;AAAA,QACV,UAAU;AAAA,UACR,QAAQ;AAAA,UACR,UAAU;AAAA,UACV,SAAS;AAAA,QACX;AAAA,QACA,UAAU;AAAA,MACZ;AAAA,IACF;AAGA,UAAM,eAAe,aAAaE,MAAK,KAAK,WAAW,YAAY;AACnE,IAAAD,KAAG,UAAU,cAAc,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAM,WAAW,GAAG,aAAa;AACjC,UAAM,WAAWC,MAAK,KAAK,cAAc,QAAQ;AACjD,IAAAD,KAAG,cAAc,UAAU,KAAK,UAAU,QAAQ,CAAC;AAEnD,WAAO,EAAE,UAAU,SAAS;AAAA,EAC9B;AACF;AAEO,IAAM,gBACX,CAAC,cACD,OAAO,eAAuB,kBAAiD;AAC7E,QAAM,YAA6B,KAAK,MAAMA,KAAG,aAAa,eAAe,OAAO,CAAC;AACrF,QAAM,YAA6B,KAAK,MAAMA,KAAG,aAAa,eAAe,OAAO,CAAC;AAErF,QAAM,kBAAkB,oBAAoB,WAAW,SAAS;AAChE,QAAM,sBAAsB,wBAAwB,WAAW,SAAS;AAExE,QAAM,iBAAiB,EAAE,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,EAAE;AACzE,aAAW,KAAK,gBAAiB,gBAAe,EAAE,UAAU;AAC5D,QAAM,YAAY,EAAE,OAAO,GAAG,SAAS,EAAE;AACzC,aAAW,KAAK,oBAAqB,WAAU,EAAE,UAAU;AAE3D,SAAO;AAAA,IACL,WAAW,EAAE,OAAO,UAAU,OAAO,WAAW,UAAU,UAAU;AAAA,IACpE,WAAW,EAAE,OAAO,UAAU,OAAO,WAAW,UAAU,UAAU;AAAA,IACpE,SAAS;AAAA,MACP,cAAc,gBAAgB,SAAS,oBAAoB;AAAA,MAC3D,gBAAgB,eAAe;AAAA,MAC/B,kBAAkB,eAAe;AAAA,MACjC,mBAAmB,eAAe;AAAA,MAClC,oBAAoB,eAAe;AAAA,MACnC,oBAAoB,UAAU;AAAA,MAC9B,sBAAsB,UAAU;AAAA,IAClC;AAAA,IACA,WAAW;AAAA,IACX,eAAe;AAAA,EACjB;AACF;AAEK,IAAM,gBAAgB,CAAC,cAAsB,YAAqC;AACvF,QAAM,eAAeC,MAAK,KAAK,WAAW,YAAY;AACtD,MAAI,CAACD,KAAG,WAAW,YAAY,EAAG,QAAO,CAAC;AAE1C,QAAM,QAAQA,KAAG,YAAY,YAAY,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,gBAAgB,CAAC;AACrF,QAAM,YAA4B,CAAC;AAEnC,aAAW,QAAQ,OAAO;AACxB,QAAI;AACF,YAAM,WAAWC,MAAK,KAAK,cAAc,IAAI;AAC7C,YAAM,UAA2B,KAAK,MAAMD,KAAG,aAAa,UAAU,OAAO,CAAC;AAC9E,gBAAU,KAAK;AAAA,QACb,OAAO,QAAQ;AAAA,QACf,WAAW,QAAQ;AAAA,QACnB;AAAA,QACA,GAAI,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;AAAA,MAC5C,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SAAO,UAAU,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,cAAc,EAAE,SAAS,CAAC;AACxE;;;AExKA,OAAOE,SAAQ,WAAAC,gBAAe;AAC9B,OAAOC,aAAY;AACnB,OAAOC,UAAQ;AACf,OAAOC,aAAY;AA6BZ,IAAM,iBACX,CAAC,eACD,OAAO,IAAY,WAAsB,UAAuD,CAAC,MAAqB;AACpH,QAAM,EAAE,SAAS,SAAS,MAAM,IAAI;AAEpC,QAAM,eAAe,MAAM,aAAa,YAAY,IAAI,OAAO;AAC/D,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,MAAM,8BAA8B,EAAE,GAAG,UAAU,iBAAiB,OAAO,KAAK,EAAE,EAAE;AAAA,EAChG;AAEA,QAAM,cAAcC,SAAQ,YAAY;AACxC,QAAM,gBAAgBC,MAAK,KAAK,aAAa,aAAa,MAAM,EAAE;AAElE,QAAM,EAAE,UAAU,GAAG,YAAY,IAAI;AAGrC,QAAM,KAA0B,EAAE,GAAG,YAAY;AACjD,MAAI,GAAG,qBAAqB,MAAM;AAChC,OAAG,YAAY,GAAG;AAAA,EACpB;AAGA,MAAI,CAAC,GAAG,UAAU,GAAG,OAAO,WAAW,GAAG;AACxC,WAAO,GAAG;AAAA,EACZ;AAEA,EAAAC,QAAO,UAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AACjD,QAAM,WAAWC,QAAO,UAAU,SAAS,KAAK,GAAG,EAAE;AACrD,EAAAD,QAAO,cAAc,eAAe,QAAQ;AAC5C,sBAAoB;AACtB;AA2BK,IAAM,kBACX,CAAC,eACD,OAAO,IAAY,WAAsB,UAAuD,CAAC,MAAqB;AACpH,QAAM,EAAE,SAAS,SAAS,MAAM,IAAI;AAEpC,QAAM,eAAe,MAAM,aAAa,YAAY,IAAI,OAAO;AAC/D,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,MAAM,8BAA8B,EAAE,GAAG,UAAU,iBAAiB,OAAO,KAAK,EAAE,EAAE;AAAA,EAChG;AAEA,QAAM,cAAcF,SAAQ,YAAY;AAGxC,QAAM,UAAUC,MAAK,KAAK,aAAa,eAAe;AACtD,QAAM,SAASA,MAAK,KAAK,aAAa,cAAc;AACpD,QAAM,eAAeC,QAAO,WAAW,OAAO,IAAI,UAAUA,QAAO,WAAW,MAAM,IAAI,SAAS;AAEjG,MAAI,CAAC,cAAc;AAEjB,WAAO,eAAe,UAAU,EAAE,IAAI,WAAW,OAAO;AAAA,EAC1D;AAEA,QAAM,WAAWC,QAAO,KAAK,YAAY;AACzC,QAAM,kBAAkB,SAAS,QAAQ,KAAK;AAG9C,QAAM,WAAW,UAAU,SAAS,KAAK;AAGzC,QAAM,WAAW,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA,EAAc,eAAe;AAGzD,QAAM,KAA0B,EAAE,GAAG,SAAS,KAAK;AACnD,KAAG,YAAY,UAAU;AAEzB,MAAI,UAAU,UAAU,UAAU,OAAO,SAAS,GAAG;AACnD,OAAG,SAAS,UAAU;AAAA,EACxB,OAAO;AACL,WAAO,GAAG;AAAA,EACZ;AAEA,QAAM,WAAWA,QAAO,UAAU,UAAU,EAAE;AAC9C,EAAAD,QAAO,cAAc,cAAc,QAAQ;AAC3C,sBAAoB;AACtB;AAkBK,IAAM,eACX,CAAC,eACD,OAAO,IAAY,UAAgC,CAAC,MAAsC;AACxF,QAAM,EAAE,QAAQ,IAAI;AAEpB,QAAM,eAAe,MAAM,aAAa,YAAY,IAAI,OAAO;AAC/D,MAAI,CAAC,aAAc,QAAO;AAE1B,QAAM,cAAcF,SAAQ,YAAY;AAGxC,QAAM,UAAUC,MAAK,KAAK,aAAa,eAAe;AACtD,QAAM,SAASA,MAAK,KAAK,aAAa,cAAc;AAEpD,QAAM,gBAAgBC,QAAO,WAAW,OAAO,IAAI,UAAUA,QAAO,WAAW,MAAM,IAAI,SAAS;AAElG,MAAI,CAAC,cAAe,QAAO;AAE3B,QAAM,EAAE,MAAM,QAAQ,IAAIC,QAAO,KAAK,aAAa;AACnD,SAAO,EAAE,GAAG,MAAM,UAAU,QAAQ,KAAK,EAAE;AAC7C;AAkBK,IAAM,cACX,CAAC,eACD,OAAO,IAAY,UAAgC,CAAC,MAAqB;AACvE,QAAM,EAAE,QAAQ,IAAI;AAEpB,QAAM,eAAe,MAAM,aAAa,YAAY,IAAI,OAAO;AAC/D,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,MAAM,8BAA8B,EAAE,GAAG,UAAU,iBAAiB,OAAO,KAAK,EAAE,EAAE;AAAA,EAChG;AAEA,QAAM,cAAcH,SAAQ,YAAY;AAExC,QAAM,UAAUC,MAAK,KAAK,aAAa,eAAe;AACtD,QAAM,SAASA,MAAK,KAAK,aAAa,cAAc;AAEpD,MAAIC,QAAO,WAAW,OAAO,GAAG;AAC9B,UAAME,KAAG,GAAG,OAAO;AAAA,EACrB;AACA,MAAIF,QAAO,WAAW,MAAM,GAAG;AAC7B,UAAME,KAAG,GAAG,MAAM;AAAA,EACpB;AAEA,sBAAoB;AACtB;;;ACpNF,OAAOC,UAAQ;AACf,SAAS,QAAAC,cAAqB;AAwBvB,IAAM,YACX,CAAC,cACD,OAAO,IAAY,YACjB,YAAY,WAAW,IAAI,SAAS,EAAE,MAAM,SAAS,CAAC;AAqBnD,IAAM,cACX,CAAC,cACD,OAAO,YACL,aAAa,WAAW,EAAE,MAAM,YAAY,YAAY,SAAS,WAAW,CAAC;AAsD1E,IAAM,cACX,CAAC,cACD,OACE,QACA,UAA0G;AAAA,EACxG,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ;AACV,MAEA,cAAc,WAAW,EAAE,GAAG,OAAO,GAAG,EAAE,GAAG,SAAS,MAAM,SAAS,CAAC;AAgBnE,IAAM,WAAW,CAAC,cAAsB,OAAOC,UAAiB;AACrE,QAAMC,KAAG,GAAGC,OAAK,WAAWF,KAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACtD,sBAAoB;AACtB;AAoBO,IAAM,eAAe,CAAC,cAAsB,OAAO,IAAY,SAAkB,iBAA2B;AACjH,QAAM,eAAe,WAAW,IAAI,SAAS,EAAE,MAAM,UAAU,aAAa,CAAC;AAC/E;AAoBO,IAAM,gBAAgB,CAAC,cAAsB,OAAO,OAAe,gBAAgB,WAAW,EAAE;AAkBhG,IAAM,mBAAmB,CAAC,cAAsB,OAAO,IAAY,YAAqB;AAC7F,QAAM,OAAO,MAAM,aAAa,WAAW,IAAI,OAAO;AACtD,SAAO,CAAC,CAAC;AACX;;;ACtMA,OAAOG,UAAQ;AACf,SAAS,QAAAC,cAAY;AAgCd,IAAM,eACX,CAAC,cACD,OAAO,IAAY,YACjB,YAAY,WAAW,IAAI,SAAS,EAAE,MAAM,YAAY,CAAC;AAqBtD,IAAM,gBACX,CAAC,cACD,OAAO,YACL,aAAa,WAAW,EAAE,MAAM,cAAc,YAAY,SAAS,WAAW,CAAC;AAK5E,IAAM,iBACX,CAAC,cACD,OACE,MACA,UAA0G;AAAA,EACxG,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ;AACV,MAEA,cAAc,WAAW,EAAE,GAAG,KAAK,GAAG,EAAE,GAAG,SAAS,MAAM,YAAY,CAAC;AAoBpE,IAAM,mBAAmB,CAAC,cAAsB,OAAO,OAAe,gBAAgB,WAAW,EAAE;AAgBnG,IAAM,cAAc,CAAC,cAAsB,OAAOC,UAAiB;AACxE,QAAMC,KAAG,GAAGC,OAAK,WAAWF,KAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACtD,sBAAoB;AACtB;AAoBO,IAAM,kBAAkB,CAAC,cAAsB,OAAO,IAAY,SAAkB,iBAA2B;AACpH,QAAM,eAAe,WAAW,IAAI,SAAS,EAAE,MAAM,aAAa,aAAa,CAAC;AAClF;AAkBO,IAAM,sBAAsB,CAAC,cAAsB,OAAO,IAAY,YAAqB;AAChG,QAAM,OAAO,MAAM,aAAa,WAAW,IAAI,OAAO;AACtD,SAAO,CAAC,CAAC;AACX;AAqBO,IAAM,qBACX,CAAC,cAAsB,OAAO,IAAY,MAA6C,YACrF,kBAAkB,WAAW,IAAI,MAAM,OAAO;AAyB3C,IAAM,0BACX,CAAC,cACD,OACE,WACA,SACA,UAAwE,EAAE,MAAM,IAAI,QAAQ,OAAO,UAAU,MAAM,MAChH;AACH,QAAM,eAAe,MAAM,gBAAgB,WAAW,QAAQ,IAAI,QAAQ,OAAO;AACjF,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,MAAM,mBAAmB;AAAA,EACrC;AAEA,MAAI,mBACF,QAAQ,WAAW,QAAQ,YAAY,WACnC,GAAG,aAAa,SAAS,cAAc,QAAQ,OAAO,gBACtD,GAAG,aAAa,SAAS;AAC/B,qBAAmBE,OAAK,kBAAkB,UAAU,EAAE;AACtD,QAAM,cAAc,WAAW,EAAE,GAAG,UAAU,GAAG,EAAE,GAAG,SAAS,MAAM,kBAAkB,MAAM,YAAY,CAAC;AAC5G;;;AC1MK,IAAM,eAA0B;AAqBhC,IAAM,gBAA2B;AAKjC,IAAM,iBAA4B;AAoBlC,IAAM,mBAA8B;AAgBpC,IAAM,cAAyB;AAoB/B,IAAM,kBAA6B;AAkBnC,IAAM,sBAAiC;AAqBvC,IAAM,qBAAgC;AAyBtC,IAAM,0BAAqC;;;ACvKlD,OAAOC,UAAQ;AACf,SAAS,QAAAC,cAAY;AA+Bd,IAAM,iBACX,CAAC,cACD,OAAO,IAAY,YACjB,YAAY,WAAW,IAAI,SAAS,EAAE,MAAM,eAAe,CAAC;AAqBzD,IAAM,kBACX,CAAC,cACD,OAAO,YACL,aAAa,WAAW,EAAE,MAAM,iBAAiB,YAAY,SAAS,WAAW,CAAC;AAsD/E,IAAM,mBACX,CAAC,cACD,OACE,aACA,UAA0G;AAAA,EACxG,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ;AACV,MAEA,cAAc,WAAW,EAAE,GAAG,YAAY,GAAG,EAAE,GAAG,SAAS,MAAM,eAAe,CAAC;AAsB9E,IAAM,2BACX,CAAC,cACD,OACE,aACA,QACA,UAAwE,EAAE,MAAM,IAAI,QAAQ,OAAO,UAAU,MAAM,MAChH;AACH,MAAI,qBACF,OAAO,WAAW,OAAO,YAAY,WACjC,IAAI,OAAO,EAAE,cAAc,OAAO,OAAO,mBACzC,IAAI,OAAO,EAAE;AACnB,uBAAqBC,OAAK,oBAAoB,YAAY,EAAE;AAE5D,QAAM,cAAc,WAAW,EAAE,GAAG,YAAY,GAAG,EAAE,GAAG,SAAS,MAAM,oBAAoB,MAAM,eAAe,CAAC;AACnH;AAgBK,IAAM,gBAAgB,CAAC,cAAsB,OAAOC,UAAiB;AAC1E,QAAMC,KAAG,GAAGF,OAAK,WAAWC,KAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACtD,sBAAoB;AACtB;AAoBO,IAAM,oBAAoB,CAAC,cAAsB,OAAO,IAAY,SAAkB,iBAA2B;AACtH,QAAM,eAAe,WAAW,IAAI,SAAS,EAAE,MAAM,gBAAgB,aAAa,CAAC;AACrF;AAoBO,IAAM,qBAAqB,CAAC,cAAsB,OAAO,OAAe,gBAAgB,WAAW,EAAE;AAkBrG,IAAM,wBAAwB,CAAC,cAAsB,OAAO,IAAY,YAAqB;AAClG,QAAM,OAAO,MAAM,aAAa,WAAW,IAAI,OAAO;AACtD,SAAO,CAAC,CAAC;AACX;AAqBO,IAAM,uBACX,CAAC,cAAsB,OAAO,IAAY,MAA6C,YACrF,kBAAkB,WAAW,IAAI,MAAM,OAAO;;;ACxQlD,OAAOE,UAAQ;AACf,SAAS,QAAAC,cAAY;AA+Bd,IAAM,aACX,CAAC,cACD,OAAO,IAAY,YACjB,YAAY,WAAW,IAAI,SAAS,EAAE,MAAM,UAAU,CAAC;AAqBpD,IAAM,cACX,CAAC,cACD,OAAO,YACL,aAAa,WAAW,EAAE,MAAM,YAAY,YAAY,SAAS,WAAW,CAAC;AAsD1E,IAAM,eACX,CAAC,cACD,OACE,SACA,UAA0G;AAAA,EACxG,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ;AACV,MAEA,cAAc,WAAW,EAAE,GAAG,QAAQ,GAAG,EAAE,GAAG,SAAS,MAAM,UAAU,CAAC;AAgBrE,IAAM,YAAY,CAAC,cAAsB,OAAOC,UAAiB;AACtE,QAAMC,KAAG,GAAGC,OAAK,WAAWF,KAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACtD,sBAAoB;AACtB;AAoBO,IAAM,gBAAgB,CAAC,cAAsB,OAAO,IAAY,SAAkB,iBAA2B;AAClH,QAAM,eAAe,WAAW,IAAI,SAAS,EAAE,MAAM,WAAW,aAAa,CAAC;AAChF;AAoBO,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;AAmBO,IAAM,mBACX,CAAC,cACD,OAAO,IAAY,MAA6C,YAC9D,kBAAkB,WAAW,IAAI,MAAM,SAAS,EAAE,MAAM,UAAU,CAAC;;;A7B5EvE,IAAO,cAAQ,CAACG,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,kBAAkB,iBAAiBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAM7C,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,IAkBjD,uBAAuB,sBAAsBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAoBvD,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;AAAA;AAAA;AAAA;AAAA;AAAA,IAmBjD,oBAAoB,mBAAmBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAkBjD,WAAW,UAAUC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO/B,WAAW,UAAUC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAe/B,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,IAS5D,sBAAsB,qBAAqBC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAShE,mBAAmB,kBAAkBC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmB1D,kBAAkB,mBAAmBC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmB1D,oBAAoB,mBAAmBC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmB5D,kBAAkB,mBAAmBC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAc1D,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,OAAM,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOtC,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASnC,kCAAkC,iCAAiCC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAe7E,gBAAgB,eAAeC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUzC,iBAAiB,gBAAgBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQ3C,cAAc,aAAaC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQrC,aAAa,YAAYC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWnC;AAAA;AAAA;AAAA;AAAA,IAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAcA,wBAAwB,uBAAuBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQzD,oCAAoC,mCAAmCC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOjF,sBAAsB,qBAAqBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOrD,sBAAsB,qBAAqBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASrD,qBAAqB,oBAAoBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQnD,sBAAsB,qBAAqBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAcrD,WAAW,UAAUC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAM/B,aAAa,YAAYC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQnC,aAAa,YAAYC,OAAKD,OAAM,UAAU,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO/C,UAAU,SAASC,OAAKD,OAAM,UAAU,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOzC,cAAc,aAAaC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAKrC,eAAe,cAAcC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOvC,kBAAkB,iBAAiBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAa7C,gBAAgB,eAAeC,OAAKD,OAAM,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQvD,cAAc,aAAaC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOrC,eAAe,cAAcC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAMvC,kBAAkB,iBAAiBC,OAAKD,OAAM,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAM3D,aAAa,YAAYC,OAAKD,OAAM,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAMjD,iBAAiB,gBAAgBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQ3C,qBAAqB,oBAAoBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASnD,oBAAoB,mBAAmBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQjD,yBAAyB,wBAAwBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAa3D,kBAAkB,iBAAiBC,OAAKD,OAAM,eAAe,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAS9D,0BAA0B,yBAAyBC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQxE,gBAAgB,eAAeC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOzC,iBAAiB,gBAAgBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAM3C,oBAAoB,mBAAmBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAMjD,eAAe,cAAcC,OAAKD,OAAM,eAAe,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOxD,mBAAmB,kBAAkBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQ/C,uBAAuB,sBAAsBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASvD,sBAAsB,qBAAqBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASrD,wBAAwB,uBAAuBC,OAAKD,OAAM,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAcpE,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,IAOjD,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,IAOzC,mBAAmB,kBAAkBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQ/C,kBAAkB,iBAAiBC,OAAKD,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAqB7C,gBAAgB,eAAeC,OAAKD,KAAI,CAAC;AAAA,IACzC,eAAe,cAAcC,OAAKD,KAAI,CAAC;AAAA,IACvC,eAAe,cAAcC,OAAKD,KAAI,CAAC;AAAA,IAEvC,OAAO,MAAMC,OAAKD,KAAI,GAAG;AAAA,MACvB,UAAU,SAASC,OAAKD,KAAI,CAAC;AAAA,MAC7B,YAAY,WAAWC,OAAKD,KAAI,CAAC;AAAA,MACjC,UAAU,SAASC,OAAKD,KAAI,CAAC;AAAA,MAC7B,YAAY,WAAWC,OAAKD,KAAI,CAAC;AAAA,MACjC,aAAa,YAAYC,OAAKD,KAAI,CAAC;AAAA,MACnC,WAAW,UAAUC,OAAKD,OAAM,SAAS,CAAC;AAAA,MAC1C,YAAY,WAAWC,OAAKD,KAAI,CAAC;AAAA,MACjC,aAAa,YAAYC,OAAKD,KAAI,CAAC;AAAA,MACnC,cAAc,aAAaC,OAAKD,KAAI,CAAC;AAAA,MACrC,SAAS,QAAQC,OAAKD,OAAM,OAAO,CAAC;AAAA,MACpC,SAAS,QAAQC,OAAKD,OAAM,OAAO,CAAC;AAAA,IACtC,CAAC;AAAA,EACH;AACF;","names":["join","hydrateOwners","fs","join","globSync","satisfies","validRange","entry","validRange","satisfies","globSync","path","dirname","join","matter","fsSync","satisfies","basename","dirname","file","join","path","resolve","join","path","fs","fs","join","join","path","fs","fs","join","join","path","fs","fs","join","dirname","relative","path","join","fs","dirname","relative","fs","path","join","fsSync","matter","path","fs","join","fsSync","fs","join","extname","path","fs","join","getMessage","extname","dirname","join","fsSync","matter","satisfies","validRange","path","dirname","matter","fsSync","join","path","join","fsSync","fs","matter","path","fsSync","matter","fs","join","fs","fsSync","join","matter","path","fsSync","join","matter","matter","fsSync","join","matter","fsSync","join","fs","path","fs","path","join","fs","join","path","getDomains","getServices","getEvents","getQueries","getCommands","getChannels","getTeams","getUsers","fs","path","getEventCatalogVersion","fs","path","path","dirname","fsSync","fs","matter","dirname","path","fsSync","matter","fs","fs","join","path","fs","join","fs","join","path","fs","join","fs","join","join","path","fs","fs","join","path","fs","join","path","join"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/dsl/utils.ts","../src/dsl/message.ts","../src/dsl/service.ts","../src/dsl/channel.ts","../src/dsl/owner.ts","../src/dsl/domain.ts","../src/dsl/container.ts","../src/dsl/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/messages.ts","../src/custom-docs.ts","../src/teams.ts","../src/users.ts","../src/eventcatalog.ts","../src/snapshots.ts","../src/snapshot-diff.ts","../src/changelogs.ts","../src/entities.ts","../src/containers.ts","../src/data-stores.ts","../src/data-products.ts","../src/diagrams.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { toDSL } from './dsl';\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 addEntityToService,\n serviceHasVersion,\n getSpecificationFilesForService,\n writeVersionedService,\n getServices,\n getServiceByPath,\n isService,\n toService,\n addDataStoreToService,\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 addSubDomainToDomain,\n addEntityToDomain,\n addDataProductToDomain,\n getUbiquitousLanguageFromDomain,\n addMessageToDomain,\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 {\n getConsumersOfSchema,\n getMessageBySchemaPath,\n getProducersAndConsumersForMessage,\n getProducersOfSchema,\n getSchemaForMessage,\n} from './messages';\n\nimport { getResourcePath, getResourceFolderName } from './internal/resources';\n\nimport { writeCustomDoc, getCustomDoc, getCustomDocs, rmCustomDoc } from './custom-docs';\n\nimport { writeTeam, getTeam, getTeams, rmTeamById, getOwnersForResource } from './teams';\n\nimport { writeUser, getUser, getUsers, rmUserById } from './users';\nimport { dumpCatalog, getEventCatalogConfigurationFile } from './eventcatalog';\nimport { createSnapshot, diffSnapshots, listSnapshots } from './snapshots';\nimport { writeChangelog, appendChangelog, getChangelog, rmChangelog } from './changelogs';\nimport { getEntity, getEntities, writeEntity, rmEntity, rmEntityById, versionEntity, entityHasVersion } from './entities';\n\nimport {\n getDataStore,\n getDataStores,\n writeDataStore,\n versionDataStore,\n rmDataStore,\n rmDataStoreById,\n dataStoreHasVersion,\n addFileToDataStore,\n writeDataStoreToService,\n} from './data-stores';\n\nimport {\n getDataProduct,\n getDataProducts,\n writeDataProduct,\n writeDataProductToDomain,\n versionDataProduct,\n rmDataProduct,\n rmDataProductById,\n dataProductHasVersion,\n addFileToDataProduct,\n} from './data-products';\n\nimport {\n getDiagram,\n getDiagrams,\n writeDiagram,\n rmDiagram,\n rmDiagramById,\n versionDiagram,\n diagramHasVersion,\n addFileToDiagram,\n} from './diagrams';\n\n// Export the types\nexport type * from './types';\nexport type * from './snapshot-types';\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 a service from EventCatalog by it's path.\n * @param path - The path to the service to retrieve\n * @returns Service|Undefined\n */\n getServiceByPath: getServiceByPath(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 /**\n * Add a data store to a service by it's id.\n *\n * Optionally specify a version to add the data store to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addDataStoreToService } = utils('/path/to/eventcatalog');\n *\n * // adds a new data store (orders-db) that the InventoryService will write to\n * await addDataStoreToService('InventoryService', 'writesTo', { id: 'orders-db', version: '2.0.0' });\n *\n * ```\n */\n addDataStoreToService: addDataStoreToService(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 * Add an entity to a service by its id.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addEntityToService } = utils('/path/to/eventcatalog');\n *\n * // adds a new entity (User) to the InventoryService\n * await addEntityToService('InventoryService', { id: 'User', version: '1.0.0' });\n *\n * // adds a new entity (Product) to a specific version of the InventoryService\n * await addEntityToService('InventoryService', { id: 'Product', version: '1.0.0' }, '2.0.0');\n *\n * ```\n */\n addEntityToService: addEntityToService(join(path)),\n\n /**\n * Check to see if a service exists by it's path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { isService } = utils('/path/to/eventcatalog');\n *\n * // returns true if the path is a service\n * await isService('/services/InventoryService/index.mdx');\n * ```\n *\n * @param path - The path to the service to check\n * @returns boolean\n */\n isService: isService(join(path)),\n\n /**\n * Converts a file to a service.\n * @param file - The file to convert to a service.\n * @returns The service.\n */\n toService: toService(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 * Adds a given subdomain to a domain\n * @param id - The id of the domain\n * @param subDomain - The id and version of the subdomain to add\n * @param version - (Optional) The version of the domain to add the subdomain to\n * @returns\n */\n addSubDomainToDomain: addSubDomainToDomain(join(path, 'domains')),\n\n /**\n * Adds an entity to a domain\n * @param id - The id of the domain\n * @param entity - The id and version of the entity to add\n * @param version - (Optional) The version of the domain to add the entity to\n * @returns\n */\n addEntityToDomain: addEntityToDomain(join(path, 'domains')),\n\n /**\n * Add an event to a domain by its id.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addEventToDomain } = utils('/path/to/eventcatalog');\n *\n * // adds a new event (OrderCreated) that the Orders domain will send\n * await addEventToDomain('Orders', 'sends', { id: 'OrderCreated', version: '2.0.0' });\n *\n * // adds a new event (PaymentProcessed) that the Orders domain will receive\n * await addEventToDomain('Orders', 'receives', { id: 'PaymentProcessed', version: '2.0.0' });\n *\n * ```\n */\n addEventToDomain: addMessageToDomain(join(path, 'domains')),\n\n /**\n * Add a command to a domain by its id.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addCommandToDomain } = utils('/path/to/eventcatalog');\n *\n * // adds a new command (ProcessOrder) that the Orders domain will send\n * await addCommandToDomain('Orders', 'sends', { id: 'ProcessOrder', version: '2.0.0' });\n *\n * // adds a new command (CancelOrder) that the Orders domain will receive\n * await addCommandToDomain('Orders', 'receives', { id: 'CancelOrder', version: '2.0.0' });\n *\n * ```\n */\n addCommandToDomain: addMessageToDomain(join(path, 'domains')),\n\n /**\n * Add a query to a domain by its id.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addQueryToDomain } = utils('/path/to/eventcatalog');\n *\n * // adds a new query (GetOrderStatus) that the Orders domain will send\n * await addQueryToDomain('Orders', 'sends', { id: 'GetOrderStatus', version: '2.0.0' });\n *\n * // adds a new query (GetInventory) that the Orders domain will receive\n * await addQueryToDomain('Orders', 'receives', { id: 'GetInventory', version: '2.0.0' });\n *\n * ```\n */\n addQueryToDomain: addMessageToDomain(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, 'teams')),\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 * Returns the event catalog configuration file.\n * The event catalog configuration file is the file that contains the configuration for the event catalog.\n *\n * @param directory - The directory of the catalog.\n * @returns A JSON object with the configuration for the event catalog.\n */\n getEventCatalogConfigurationFile: getEventCatalogConfigurationFile(join(path)),\n /**\n * ================================\n * Changelogs\n * ================================\n */\n\n /**\n * Writes a changelog entry to a resource in EventCatalog\n *\n * @param id - The id of the resource to write the changelog to\n * @param changelog - The changelog entry to write\n * @param options - Optional options (version, format)\n *\n */\n writeChangelog: writeChangelog(join(path)),\n /**\n * Appends a changelog entry to an existing changelog for a resource.\n * If no changelog exists, one is created.\n *\n * @param id - The id of the resource to append the changelog to\n * @param changelog - The changelog entry to append\n * @param options - Optional options (version, format)\n *\n */\n appendChangelog: appendChangelog(join(path)),\n /**\n * Returns the changelog for a resource in EventCatalog\n *\n * @param id - The id of the resource to get the changelog for\n * @param options - Optional options (version)\n * @returns Changelog|Undefined\n */\n getChangelog: getChangelog(join(path)),\n /**\n * Removes the changelog for a resource in EventCatalog\n *\n * @param id - The id of the resource to remove the changelog from\n * @param options - Optional options (version)\n *\n */\n rmChangelog: rmChangelog(join(path)),\n\n /**\n * ================================\n * Resources Utils\n * ================================\n */\n\n /**\n * Returns the path to a given resource by id and version\n */\n getResourcePath: getResourcePath,\n\n /**\n * Returns the folder name of a given resource\n */\n getResourceFolderName: getResourceFolderName,\n\n /**\n * ================================\n * General Message Utils\n * ================================\n */\n\n /**\n * Returns a message from EventCatalog by a given schema path.\n *\n * @param path - The path to the message to retrieve\n * @returns Message|Undefined\n */\n getMessageBySchemaPath: getMessageBySchemaPath(join(path)),\n\n /**\n * Returns the producers and consumers (services) for a given message\n * @param id - The id of the message to get the producers and consumers for\n * @param version - Optional version of the message\n * @returns { producers: Service[], consumers: Service[] }\n */\n getProducersAndConsumersForMessage: getProducersAndConsumersForMessage(join(path)),\n\n /**\n * Returns the consumers of a given schema path\n * @param path - The path to the schema to get the consumers for\n * @returns Service[]\n */\n getConsumersOfSchema: getConsumersOfSchema(join(path)),\n\n /**\n * Returns the producers of a given schema path\n * @param path - The path to the schema to get the producers for\n * @returns Service[]\n */\n getProducersOfSchema: getProducersOfSchema(join(path)),\n\n /**\n * Returns the schema for a given message (event, command or query) by its id and version.\n * If no version is given, the latest version is used.\n * @param id - The id of the message to get the schema for\n * @param version - Optional version of the message\n * @returns { schema: string, fileName: string } | undefined\n */\n getSchemaForMessage: getSchemaForMessage(join(path)),\n\n /**\n * Returns the owners for a given resource (e.g domain, service, event, command, query, etc.)\n * @param id - The id of the resource to get the owners for\n * @param version - Optional version of the resource\n * @returns { owners: User[] }\n */\n getOwnersForResource: getOwnersForResource(join(path)),\n\n /**\n * ================================\n * Entities\n * ================================\n */\n\n /**\n * Returns an entity from EventCatalog\n * @param id - The id of the entity to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Entity|Undefined\n */\n getEntity: getEntity(join(path)),\n /**\n * Returns all entities from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Entity[]|Undefined\n */\n getEntities: getEntities(join(path)),\n /**\n * Adds an entity to EventCatalog\n *\n * @param entity - The entity to write\n * @param options - Optional options to write the entity\n *\n */\n writeEntity: writeEntity(join(path, 'entities')),\n /**\n * Remove an entity from EventCatalog (modeled on the standard POSIX rm utility)\n *\n * @param path - The path to your entity, e.g. `/User`\n *\n */\n rmEntity: rmEntity(join(path, 'entities')),\n /**\n * Remove an entity by an entity id\n *\n * @param id - The id of the entity you want to remove\n *\n */\n rmEntityById: rmEntityById(join(path)),\n /**\n * Moves a given entity id to the version directory\n * @param id - The id of the entity to version\n */\n versionEntity: versionEntity(join(path)),\n /**\n * Check to see if an entity version exists\n * @param id - The id of the entity\n * @param version - The version of the entity (supports semver)\n * @returns\n */\n entityHasVersion: entityHasVersion(join(path)),\n\n /**\n * ================================\n * Data Stores\n * ================================\n */\n /**\n * Adds a data store to EventCatalog\n * @param dataStore - The data store to write\n * @param options - Optional options to write the data store\n *\n */\n writeDataStore: writeDataStore(join(path, 'containers')),\n\n /**\n * Returns a data store from EventCatalog\n * @param id - The id of the data store to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Container|Undefined\n */\n getDataStore: getDataStore(join(path)),\n\n /**\n * Returns all data stores from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Container[]|Undefined\n */\n getDataStores: getDataStores(join(path)),\n\n /**\n * Version a data store by its id\n * @param id - The id of the data store to version\n */\n versionDataStore: versionDataStore(join(path, 'containers')),\n\n /**\n * Remove a data store by its path\n * @param path - The path to the data store to remove\n */\n rmDataStore: rmDataStore(join(path, 'containers')),\n\n /**\n * Remove a data store by its id\n * @param id - The id of the data store to remove\n */\n rmDataStoreById: rmDataStoreById(join(path)),\n\n /**\n * Check to see if a data store version exists\n * @param id - The id of the data store\n * @param version - The version of the data store (supports semver)\n * @returns\n */\n dataStoreHasVersion: dataStoreHasVersion(join(path)),\n\n /**\n * Adds a file to a data store by its id\n * @param id - The id of the data store 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 data store to add the file to\n * @returns\n */\n addFileToDataStore: addFileToDataStore(join(path)),\n\n /**\n * Writes a data store to a service by its id\n * @param dataStore - The data store to write\n * @param service - The service to write the data store to\n * @returns\n */\n writeDataStoreToService: writeDataStoreToService(join(path)),\n\n /**\n * ================================\n * Data Products\n * ================================\n */\n /**\n * Adds a data product to EventCatalog\n * @param dataProduct - The data product to write\n * @param options - Optional options to write the data product\n *\n */\n writeDataProduct: writeDataProduct(join(path, 'data-products')),\n\n /**\n * Writes a data product to a domain in EventCatalog\n * @param dataProduct - The data product to write\n * @param domain - The domain to write the data product to\n * @param options - Optional options to write the data product\n *\n */\n writeDataProductToDomain: writeDataProductToDomain(join(path, 'domains')),\n\n /**\n * Returns a data product from EventCatalog\n * @param id - The id of the data product to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns DataProduct|Undefined\n */\n getDataProduct: getDataProduct(join(path)),\n\n /**\n * Returns all data products from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns DataProduct[]|Undefined\n */\n getDataProducts: getDataProducts(join(path)),\n\n /**\n * Version a data product by its id\n * @param id - The id of the data product to version\n */\n versionDataProduct: versionDataProduct(join(path)),\n\n /**\n * Remove a data product by its path\n * @param path - The path to the data product to remove\n */\n rmDataProduct: rmDataProduct(join(path, 'data-products')),\n\n /**\n * Remove a data product by its id\n * @param id - The id of the data product to remove\n * @param version - Optional version of the data product to remove\n */\n rmDataProductById: rmDataProductById(join(path)),\n\n /**\n * Check to see if a data product version exists\n * @param id - The id of the data product\n * @param version - The version of the data product (supports semver)\n * @returns\n */\n dataProductHasVersion: dataProductHasVersion(join(path)),\n\n /**\n * Adds a file to a data product by its id\n * @param id - The id of the data product 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 data product to add the file to\n * @returns\n */\n addFileToDataProduct: addFileToDataProduct(join(path)),\n\n /**\n * Adds a data product to a domain\n * @param id - The id of the domain\n * @param dataProduct - The id and version of the data product to add\n * @param version - (Optional) The version of the domain to add the data product to\n * @returns\n */\n addDataProductToDomain: addDataProductToDomain(join(path, 'domains')),\n\n /**\n * ================================\n * Diagrams\n * ================================\n */\n\n /**\n * Returns a diagram from EventCatalog\n * @param id - The id of the diagram to retrieve\n * @param version - Optional id of the version to get (supports semver)\n * @returns Diagram|Undefined\n */\n getDiagram: getDiagram(join(path)),\n /**\n * Returns all diagrams from EventCatalog\n * @param latestOnly - optional boolean, set to true to get only latest versions\n * @returns Diagram[]|Undefined\n */\n getDiagrams: getDiagrams(join(path)),\n /**\n * Adds a diagram to EventCatalog\n *\n * @param diagram - The diagram to write\n * @param options - Optional options to write the diagram\n *\n */\n writeDiagram: writeDiagram(join(path, 'diagrams')),\n /**\n * Remove a diagram from EventCatalog (modeled on the standard POSIX rm utility)\n *\n * @param path - The path to your diagram, e.g. `/ArchitectureDiagram`\n *\n */\n rmDiagram: rmDiagram(join(path, 'diagrams')),\n /**\n * Remove a diagram by a diagram id\n *\n * @param id - The id of the diagram you want to remove\n *\n */\n rmDiagramById: rmDiagramById(join(path)),\n /**\n * Moves a given diagram id to the version directory\n * @param id - The id of the diagram to version\n */\n versionDiagram: versionDiagram(join(path)),\n /**\n * Check to see if a diagram version exists\n * @param id - The id of the diagram\n * @param version - The version of the diagram (supports semver)\n * @returns\n */\n diagramHasVersion: diagramHasVersion(join(path)),\n /**\n * Adds a file to the given diagram\n * @param id - The id of the diagram 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 diagram to add the file to\n * @returns\n */\n addFileToDiagram: addFileToDiagram(join(path)),\n\n /**\n * ================================\n * DSL\n * ================================\n */\n\n /**\n * Converts catalog resources to EventCatalog DSL (.ec) format strings.\n *\n * @param resource - A resource or array of resources to convert\n * @param options - Options including type ('event'|'command'|'query'|'service'|'domain') and optional hydrate flag\n * @returns A DSL string representation\n *\n * @example\n * ```ts\n * const dsl = await sdk.toDSL(event, { type: 'event' });\n * const dsl = await sdk.toDSL(services, { type: 'service', hydrate: true });\n * ```\n */\n createSnapshot: createSnapshot(join(path)),\n diffSnapshots: diffSnapshots(join(path)),\n listSnapshots: listSnapshots(join(path)),\n\n toDSL: toDSL(join(path), {\n getEvent: getEvent(join(path)),\n getCommand: getCommand(join(path)),\n getQuery: getQuery(join(path)),\n getService: getService(join(path)),\n getServices: getServices(join(path)),\n getDomain: getDomain(join(path, 'domains')),\n getChannel: getChannel(join(path)),\n getChannels: getChannels(join(path)),\n getContainer: getDataStore(join(path)),\n getTeam: getTeam(join(path, 'teams')),\n getUser: getUser(join(path, 'users')),\n }),\n };\n};\n","import { globSync } from 'glob';\nimport { satisfies, validRange } from 'semver';\n\n/**\n * Checks whether a pointer version (which may be a semver range like ^1.0.0, ~1.2.0)\n * matches a concrete message version.\n */\nexport function msgVersionMatches(pointerVersion: string | undefined, messageVersion: string | undefined): boolean {\n if (!pointerVersion) return true;\n if (!messageVersion) return false;\n if (pointerVersion === messageVersion) return true;\n try {\n // Check if pointerVersion is a range that messageVersion satisfies\n if (validRange(pointerVersion)) {\n if (satisfies(messageVersion, pointerVersion)) return true;\n }\n // Check the reverse: messageVersion may be a range that pointerVersion satisfies\n if (validRange(messageVersion)) {\n if (satisfies(pointerVersion, messageVersion)) return true;\n }\n } catch {\n // Invalid semver, fall through\n }\n return false;\n}\n\ninterface BaseResource {\n id: string;\n name: string;\n version: string;\n summary?: string;\n owners?: string[];\n badges?: { content: string; backgroundColor: string; textColor: string }[];\n deprecated?: boolean | { date?: string; message?: string };\n draft?: boolean | { title?: string; message?: string };\n}\n\nexport type MessageTypeIndex = Map<string, MessageType>;\n\ninterface ChannelPointer {\n id: string;\n version?: string;\n parameters?: Record<string, string>;\n}\n\ninterface SendsPointer {\n id: string;\n version?: string;\n to?: ChannelPointer[];\n}\n\ninterface ReceivesPointer {\n id: string;\n version?: string;\n from?: ChannelPointer[];\n}\n\nexport type MessageType = 'event' | 'command' | 'query';\n\nexport function serializeBaseFields(resource: BaseResource, indent: string = ' '): string {\n const lines: string[] = [];\n\n if (resource.version) {\n lines.push(`${indent}version ${resource.version}`);\n }\n\n if (resource.name) {\n lines.push(`${indent}name \"${resource.name}\"`);\n }\n\n if (resource.summary) {\n lines.push(`${indent}summary \"${resource.summary.trim()}\"`);\n }\n\n if (resource.owners && resource.owners.length > 0) {\n for (const owner of resource.owners) {\n lines.push(`${indent}owner ${owner}`);\n }\n }\n\n if (resource.deprecated === true) {\n lines.push(`${indent}deprecated true`);\n }\n\n if (resource.draft === true) {\n lines.push(`${indent}draft true`);\n }\n\n return lines.join('\\n');\n}\n\nexport function buildMessageTypeIndex(catalogDir: string): MessageTypeIndex {\n const index: MessageTypeIndex = new Map();\n const types = ['events', 'commands', 'queries'] as const;\n const typeMap = { events: 'event', commands: 'command', queries: 'query' } as const;\n\n for (const type of types) {\n const matches = globSync(`**/${type}/*/index.{md,mdx}`, { cwd: catalogDir });\n for (const match of matches) {\n const parts = match.replace(/\\\\/g, '/').split('/');\n const typeIdx = parts.lastIndexOf(type);\n if (typeIdx !== -1 && typeIdx + 1 < parts.length) {\n const id = parts[typeIdx + 1];\n if (!index.has(id)) index.set(id, typeMap[type]);\n }\n }\n }\n\n return index;\n}\n\nexport function resolveMessageType(catalogDirOrIndex: string | MessageTypeIndex, id: string): MessageType | undefined {\n if (typeof catalogDirOrIndex !== 'string') {\n return catalogDirOrIndex.get(id);\n }\n // Fallback for backwards compatibility\n if (globSync(`**/events/${id}/index.{md,mdx}`, { cwd: catalogDirOrIndex }).length > 0) return 'event';\n if (globSync(`**/commands/${id}/index.{md,mdx}`, { cwd: catalogDirOrIndex }).length > 0) return 'command';\n if (globSync(`**/queries/${id}/index.{md,mdx}`, { cwd: catalogDirOrIndex }).length > 0) return 'query';\n return undefined;\n}\n\nfunction serializeChannelRef(channel: ChannelPointer): string {\n let ref = channel.id;\n if (channel.version) ref += `@${channel.version}`;\n return ref;\n}\n\nexport function serializeMessagePointers(\n items: (SendsPointer | ReceivesPointer)[],\n direction: 'sends' | 'receives',\n catalogDirOrIndex: string | MessageTypeIndex,\n indent: string = ' '\n): string {\n const lines: string[] = [];\n\n for (const item of items) {\n const msgType = resolveMessageType(catalogDirOrIndex, item.id);\n if (!msgType) continue;\n\n let ref = `${item.id}`;\n if (item.version) ref += `@${item.version}`;\n\n const channels = direction === 'sends' ? (item as SendsPointer).to : (item as ReceivesPointer).from;\n\n const channelKeyword = direction === 'sends' ? 'to' : 'from';\n\n if (channels && channels.length === 1) {\n lines.push(`${indent}${direction} ${msgType} ${ref} ${channelKeyword} ${serializeChannelRef(channels[0])}`);\n } else if (channels && channels.length > 1) {\n const channelRefs = channels.map(serializeChannelRef).join(', ');\n lines.push(`${indent}${direction} ${msgType} ${ref} ${channelKeyword} ${channelRefs}`);\n } else {\n lines.push(`${indent}${direction} ${msgType} ${ref}`);\n }\n }\n\n return lines.join('\\n');\n}\n","import type { Event, Command, Query } from '../types';\nimport { serializeBaseFields, type MessageType } from './utils';\n\nexport function messageToDSL(resource: Event | Command | Query, type: MessageType): string {\n const body = serializeBaseFields(resource);\n\n if (!body) {\n return `${type} ${resource.id}`;\n }\n\n return `${type} ${resource.id} {\\n${body}\\n}`;\n}\n","import type { Service, Event, Command, Query } from '../types';\nimport { serializeBaseFields, serializeMessagePointers, resolveMessageType, buildMessageTypeIndex } from './utils';\nimport type { MessageTypeIndex } from './utils';\nimport { messageToDSL } from './message';\nimport { valid as semverValid } from 'semver';\n\ninterface ServiceToDSLOptions {\n catalogDir: string;\n hydrate?: boolean;\n _seen?: Set<string>;\n _msgIndex?: MessageTypeIndex;\n}\n\nexport async function serviceToDSL(\n resource: Service,\n options: ServiceToDSLOptions,\n getMessageFn?: (id: string, version?: string) => Promise<Event | Command | Query | undefined>\n): Promise<string> {\n const { catalogDir, hydrate = false, _seen = new Set<string>() } = options;\n const msgIndex = options._msgIndex || buildMessageTypeIndex(catalogDir);\n const parts: string[] = [];\n const resolvedVersions = new Map<string, string>();\n\n if (hydrate && getMessageFn) {\n const allMessages = [...(resource.sends || []), ...(resource.receives || [])];\n for (const msg of allMessages) {\n const key = `${msg.id}@${msg.version || 'latest'}`;\n if (_seen.has(key)) continue;\n _seen.add(key);\n\n const msgType = resolveMessageType(msgIndex, msg.id);\n if (!msgType) continue;\n\n const msgResource = await getMessageFn(msg.id, msg.version);\n if (msgResource) {\n parts.push(messageToDSL(msgResource, msgType));\n // Track resolved version so semver ranges can be replaced with concrete versions\n if (msg.version && !semverValid(msg.version) && msgResource.version) {\n resolvedVersions.set(`${msg.id}@${msg.version}`, msgResource.version);\n }\n }\n }\n }\n\n // Replace semver range versions with concrete resolved versions\n const resolvePointers = <T extends { id: string; version?: string }>(pointers: T[]): T[] =>\n pointers.map((p) => {\n if (p.version && !semverValid(p.version)) {\n const resolved = resolvedVersions.get(`${p.id}@${p.version}`);\n if (resolved) return { ...p, version: resolved };\n }\n return p;\n });\n\n const sends = resource.sends ? resolvePointers(resource.sends) : undefined;\n const receives = resource.receives ? resolvePointers(resource.receives) : undefined;\n\n const lines: string[] = [];\n const baseFields = serializeBaseFields(resource);\n if (baseFields) lines.push(baseFields);\n\n if (sends && sends.length > 0) {\n const sendsStr = serializeMessagePointers(sends, 'sends', msgIndex);\n if (sendsStr) lines.push(sendsStr);\n }\n\n if (receives && receives.length > 0) {\n const recvStr = serializeMessagePointers(receives, 'receives', msgIndex);\n if (recvStr) lines.push(recvStr);\n }\n\n if (resource.writesTo && resource.writesTo.length > 0) {\n for (const container of resource.writesTo) {\n let ref = container.id;\n if (container.version) ref += `@${container.version}`;\n lines.push(` writes-to container ${ref}`);\n }\n }\n\n if (resource.readsFrom && resource.readsFrom.length > 0) {\n for (const container of resource.readsFrom) {\n let ref = container.id;\n if (container.version) ref += `@${container.version}`;\n lines.push(` reads-from container ${ref}`);\n }\n }\n\n const body = lines.join('\\n');\n parts.push(`service ${resource.id} {\\n${body}\\n}`);\n\n return parts.join('\\n\\n');\n}\n","import type { Channel } from '../types';\n\nexport function channelToDSL(resource: Channel): string {\n const lines: string[] = [];\n\n if (resource.version) {\n lines.push(` version ${resource.version}`);\n }\n\n if (resource.name) {\n lines.push(` name \"${resource.name}\"`);\n }\n\n if (resource.address) {\n lines.push(` address \"${resource.address}\"`);\n }\n\n if (resource.protocols && resource.protocols.length > 0) {\n for (const protocol of resource.protocols) {\n lines.push(` protocol \"${protocol}\"`);\n }\n }\n\n if (resource.summary) {\n lines.push(` summary \"${resource.summary.trim()}\"`);\n }\n\n if (resource.routes && resource.routes.length > 0) {\n for (const route of resource.routes) {\n let ref = route.id;\n if (route.version) ref += `@${route.version}`;\n lines.push(` route ${ref}`);\n }\n }\n\n if (!lines.length) {\n return `channel ${resource.id}`;\n }\n\n return `channel ${resource.id} {\\n${lines.join('\\n')}\\n}`;\n}\n","import type { Team, User } from '../types';\n\nexport function teamToDSL(team: Team): string {\n const lines: string[] = [];\n\n if (team.name) lines.push(` name \"${team.name}\"`);\n if (team.avatarUrl) lines.push(` avatar \"${team.avatarUrl}\"`);\n if (team.role) lines.push(` role \"${team.role}\"`);\n if (team.summary) lines.push(` summary \"${team.summary}\"`);\n if (team.email) lines.push(` email \"${team.email}\"`);\n if (team.slackDirectMessageUrl) lines.push(` slack \"${team.slackDirectMessageUrl}\"`);\n\n return `team ${team.id} {\\n${lines.join('\\n')}\\n}`;\n}\n\nexport function userToDSL(user: User): string {\n const lines: string[] = [];\n\n if (user.name) lines.push(` name \"${user.name}\"`);\n if (user.avatarUrl) lines.push(` avatar \"${user.avatarUrl}\"`);\n if (user.role) lines.push(` role \"${user.role}\"`);\n if (user.email) lines.push(` email \"${user.email}\"`);\n if (user.slackDirectMessageUrl) lines.push(` slack \"${user.slackDirectMessageUrl}\"`);\n\n return `user ${user.id} {\\n${lines.join('\\n')}\\n}`;\n}\n","import type { Domain, Service, Event, Command, Query, Channel, Team, User } from '../types';\nimport { serializeBaseFields, serializeMessagePointers, resolveMessageType, buildMessageTypeIndex } from './utils';\nimport type { MessageTypeIndex } from './utils';\nimport { serviceToDSL } from './service';\nimport { messageToDSL } from './message';\nimport { channelToDSL } from './channel';\nimport { teamToDSL, userToDSL } from './owner';\n\ninterface DomainToDSLOptions {\n catalogDir: string;\n hydrate?: boolean;\n _seen?: Set<string>;\n _msgIndex?: MessageTypeIndex;\n}\n\nexport interface DomainResolvers {\n getService?: (id: string, version?: string) => Promise<Service | undefined>;\n getDomain?: (id: string, version?: string) => Promise<Domain | undefined>;\n getMessage?: (id: string, version?: string) => Promise<Event | Command | Query | undefined>;\n getChannel?: (id: string, version?: string) => Promise<Channel | undefined>;\n getTeam?: (id: string) => Promise<Team | undefined>;\n getUser?: (id: string) => Promise<User | undefined>;\n}\n\nasync function hydrateOwners(owners: string[] | undefined, resolvers: DomainResolvers, seen: Set<string>, parts: string[]) {\n if (!owners || !resolvers.getTeam || !resolvers.getUser) return;\n for (const ownerId of owners) {\n const key = `owner:${ownerId}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const team = await resolvers.getTeam(ownerId);\n if (team) {\n parts.push(teamToDSL(team));\n continue;\n }\n\n const user = await resolvers.getUser(ownerId);\n if (user) {\n parts.push(userToDSL(user));\n }\n }\n}\n\nasync function hydrateChannelsFromMessages(\n messages: {\n id: string;\n version?: string;\n to?: { id: string; version?: string }[];\n from?: { id: string; version?: string }[];\n }[],\n resolvers: DomainResolvers,\n seen: Set<string>,\n parts: string[]\n) {\n if (!resolvers.getChannel) return;\n for (const msg of messages) {\n const channels = (msg as any).to || (msg as any).from;\n if (!channels) continue;\n for (const ch of channels) {\n const key = `channel:${ch.id}@${ch.version || 'latest'}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const channel = await resolvers.getChannel(ch.id, ch.version);\n if (channel) {\n parts.push(channelToDSL(channel));\n }\n }\n }\n}\n\nasync function buildDomainBody(\n resource: Domain,\n options: DomainToDSLOptions,\n resolvers: DomainResolvers | undefined,\n keyword: 'domain' | 'subdomain'\n): Promise<{ topLevelParts: string[]; block: string }> {\n const { catalogDir, hydrate = false, _seen = new Set<string>() } = options;\n const msgIndex = options._msgIndex || buildMessageTypeIndex(catalogDir);\n const topLevelParts: string[] = [];\n\n if (hydrate && resolvers) {\n // Hydrate services (and their owners, channels, messages)\n if (resource.services && resource.services.length > 0 && resolvers.getService) {\n for (const svcRef of resource.services) {\n const svcKey = `service:${svcRef.id}@${svcRef.version || 'latest'}`;\n if (_seen.has(svcKey)) continue;\n _seen.add(svcKey);\n\n const svc = await resolvers.getService(svcRef.id, svcRef.version);\n if (svc) {\n // Hydrate service owners\n await hydrateOwners(svc.owners, resolvers, _seen, topLevelParts);\n // Hydrate service channels\n const svcMessages = [...(svc.sends || []), ...(svc.receives || [])];\n await hydrateChannelsFromMessages(svcMessages, resolvers, _seen, topLevelParts);\n // Hydrate service (includes message hydration)\n const svcDsl = await serviceToDSL(svc, { catalogDir, hydrate: true, _seen, _msgIndex: msgIndex }, resolvers.getMessage);\n topLevelParts.push(svcDsl);\n }\n }\n }\n\n // Hydrate domain-level channels\n const domainMessages = [...(resource.sends || []), ...(resource.receives || [])];\n await hydrateChannelsFromMessages(domainMessages, resolvers, _seen, topLevelParts);\n\n // Hydrate domain-level messages\n if (resolvers.getMessage) {\n for (const msg of domainMessages) {\n const key = `${msg.id}@${msg.version || 'latest'}`;\n if (_seen.has(key)) continue;\n _seen.add(key);\n\n const msgType = resolveMessageType(msgIndex, msg.id);\n if (!msgType) continue;\n\n const msgResource = await resolvers.getMessage(msg.id, msg.version);\n if (msgResource) {\n topLevelParts.push(messageToDSL(msgResource, msgType));\n }\n }\n }\n }\n\n const lines: string[] = [];\n const baseFields = serializeBaseFields(resource);\n if (baseFields) lines.push(baseFields);\n\n // Service references\n if (resource.services && resource.services.length > 0) {\n for (const svc of resource.services) {\n let ref = svc.id;\n if (svc.version) ref += `@${svc.version}`;\n lines.push(` service ${ref}`);\n }\n }\n\n if (resource.sends && resource.sends.length > 0) {\n const sendsStr = serializeMessagePointers(resource.sends, 'sends', msgIndex);\n if (sendsStr) lines.push(sendsStr);\n }\n\n if (resource.receives && resource.receives.length > 0) {\n const recvStr = serializeMessagePointers(resource.receives, 'receives', msgIndex);\n if (recvStr) lines.push(recvStr);\n }\n\n // Subdomain blocks (inline)\n if (resource.domains && resource.domains.length > 0) {\n if (hydrate && resolvers?.getDomain) {\n for (const subRef of resource.domains) {\n const subKey = `domain:${subRef.id}@${subRef.version || 'latest'}`;\n if (_seen.has(subKey)) continue;\n _seen.add(subKey);\n\n const subDomain = await resolvers.getDomain(subRef.id, subRef.version);\n if (subDomain) {\n // Hydrate subdomain owners at top level\n await hydrateOwners(subDomain.owners, resolvers, _seen, topLevelParts);\n // Recursively build subdomain\n const sub = await buildDomainBody(\n subDomain,\n { catalogDir, hydrate, _seen, _msgIndex: msgIndex },\n resolvers,\n 'subdomain'\n );\n topLevelParts.push(...sub.topLevelParts);\n // Indent the subdomain block to nest inside the parent\n const indented = sub.block\n .split('\\n')\n .map((line) => ` ${line}`)\n .join('\\n');\n lines.push(indented);\n }\n }\n } else {\n // Non-hydrated: just output references\n for (const sub of resource.domains) {\n let ref = sub.id;\n if (sub.version) ref += `@${sub.version}`;\n lines.push(` subdomain ${ref}`);\n }\n }\n }\n\n const body = lines.join('\\n');\n const block = `${keyword} ${resource.id} {\\n${body}\\n}`;\n\n return { topLevelParts, block };\n}\n\nexport async function domainToDSL(resource: Domain, options: DomainToDSLOptions, resolvers?: DomainResolvers): Promise<string> {\n const { catalogDir, hydrate = false, _seen = new Set<string>() } = options;\n const msgIndex = options._msgIndex || buildMessageTypeIndex(catalogDir);\n\n const result = await buildDomainBody(resource, { catalogDir, hydrate, _seen, _msgIndex: msgIndex }, resolvers, 'domain');\n const parts = [...result.topLevelParts, result.block];\n\n return parts.join('\\n\\n');\n}\n","import type { Container } from '../types';\nimport { serializeBaseFields } from './utils';\n\nexport function containerToDSL(resource: Container): string {\n const lines: string[] = [];\n const baseFields = serializeBaseFields(resource);\n if (baseFields) lines.push(baseFields);\n\n if (resource.container_type) {\n lines.push(` container-type ${resource.container_type}`);\n }\n\n if (resource.technology) {\n lines.push(` technology \"${resource.technology}\"`);\n }\n\n if (resource.authoritative === true) {\n lines.push(` authoritative true`);\n }\n\n if (resource.access_mode) {\n lines.push(` access-mode ${resource.access_mode}`);\n }\n\n if (resource.classification) {\n lines.push(` classification ${resource.classification}`);\n }\n\n if (resource.residency) {\n lines.push(` residency \"${resource.residency}\"`);\n }\n\n if (resource.retention) {\n lines.push(` retention \"${resource.retention}\"`);\n }\n\n const body = lines.join('\\n');\n return `container ${resource.id} {\\n${body}\\n}`;\n}\n","import type { Event, Command, Query, Service, Domain, Team, User, Channel, Container } from '../types';\nimport { messageToDSL } from './message';\nimport { serviceToDSL } from './service';\nimport { domainToDSL } from './domain';\nimport { teamToDSL, userToDSL } from './owner';\nimport { channelToDSL } from './channel';\nimport { containerToDSL } from './container';\nimport { buildMessageTypeIndex, resolveMessageType, msgVersionMatches } from './utils';\nimport type { MessageType, MessageTypeIndex } from './utils';\n\ntype ResourceType = 'event' | 'command' | 'query' | 'service' | 'domain';\n\nexport interface ToDSLOptions {\n type: ResourceType;\n hydrate?: boolean;\n}\n\ntype AnyResource = Event | Command | Query | Service | Domain;\n\nexport interface ResourceResolvers {\n getEvent: (id: string, version?: string) => Promise<Event | undefined>;\n getCommand: (id: string, version?: string) => Promise<Command | undefined>;\n getQuery: (id: string, version?: string) => Promise<Query | undefined>;\n getService: (id: string, version?: string) => Promise<Service | undefined>;\n getServices: (options?: { latestOnly?: boolean }) => Promise<Service[]>;\n getDomain: (id: string, version?: string) => Promise<Domain | undefined>;\n getChannel: (id: string, version?: string) => Promise<Channel | undefined>;\n getChannels: (options?: { latestOnly?: boolean }) => Promise<Channel[]>;\n getContainer: (id: string, version?: string) => Promise<Container | undefined>;\n getTeam: (id: string) => Promise<Team | undefined>;\n getUser: (id: string) => Promise<User | undefined>;\n}\n\nfunction getMessage(resolvers: ResourceResolvers, msgIndex: MessageTypeIndex) {\n return async (id: string, version?: string) => {\n const msgType = resolveMessageType(msgIndex, id);\n if (!msgType) return undefined;\n switch (msgType) {\n case 'event':\n return resolvers.getEvent(id, version);\n case 'command':\n return resolvers.getCommand(id, version);\n case 'query':\n return resolvers.getQuery(id, version);\n }\n };\n}\n\nasync function hydrateChannel(\n channelId: string,\n channelVersion: string | undefined,\n resolvers: ResourceResolvers,\n seen: Set<string>,\n parts: string[]\n) {\n const key = `channel:${channelId}@${channelVersion || 'latest'}`;\n if (seen.has(key)) return;\n seen.add(key);\n\n const channel = await resolvers.getChannel(channelId, channelVersion);\n if (!channel) return;\n\n // Hydrate any channels this channel routes to (downstream)\n if (channel.routes && channel.routes.length > 0) {\n for (const route of channel.routes) {\n await hydrateChannel(route.id, route.version, resolvers, seen, parts);\n }\n }\n\n // Hydrate any channels that route TO this channel (upstream)\n const allChannels = (await resolvers.getChannels({ latestOnly: false })) || [];\n const targetVersion = channelVersion || channel.version;\n for (const upstream of allChannels) {\n if (!upstream.routes) continue;\n const routesToThis = upstream.routes.some((route) => {\n if (route.id !== channelId) return false;\n if (!route.version) {\n // Unversioned routes point to latest, so only match when hydrating latest.\n return !channelVersion;\n }\n return msgVersionMatches(route.version, targetVersion);\n });\n if (routesToThis) {\n await hydrateChannel(upstream.id, upstream.version, resolvers, seen, parts);\n }\n }\n\n parts.push(channelToDSL(channel));\n}\n\nasync function hydrateChannels(resource: Service | Domain, resolvers: ResourceResolvers, seen: Set<string>, parts: string[]) {\n const allMessages = [...((resource as Service).sends || []), ...((resource as Service).receives || [])];\n for (const msg of allMessages) {\n const channels = 'to' in msg ? (msg as any).to : 'from' in msg ? (msg as any).from : undefined;\n if (!channels) continue;\n for (const ch of channels) {\n await hydrateChannel(ch.id, ch.version, resolvers, seen, parts);\n }\n }\n}\n\nasync function hydrateContainers(resource: Service, resolvers: ResourceResolvers, seen: Set<string>, parts: string[]) {\n const allContainers = [...(resource.writesTo || []), ...(resource.readsFrom || [])];\n for (const ref of allContainers) {\n const key = `container:${ref.id}@${ref.version || 'latest'}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const container = await resolvers.getContainer(ref.id, ref.version);\n if (!container) continue;\n\n parts.push(containerToDSL(container));\n }\n}\n\nasync function hydrateOwners(owners: string[] | undefined, resolvers: ResourceResolvers, seen: Set<string>, parts: string[]) {\n if (!owners) return;\n for (const ownerId of owners) {\n const key = `owner:${ownerId}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const team = await resolvers.getTeam(ownerId);\n if (team) {\n parts.push(teamToDSL(team));\n continue;\n }\n\n const user = await resolvers.getUser(ownerId);\n if (user) {\n parts.push(userToDSL(user));\n }\n }\n}\n\nasync function hydrateMessageServices(\n messageId: string,\n messageVersion: string | undefined,\n resolvers: ResourceResolvers,\n seen: Set<string>,\n parts: string[],\n catalogDir: string,\n msgIndex: MessageTypeIndex\n) {\n const services = (await resolvers.getServices({ latestOnly: false })) || [];\n for (const service of services) {\n const key = `service:${service.id}@${service.version || 'latest'}`;\n if (seen.has(key)) continue;\n\n const referencesMessage = [...(service.sends || []), ...(service.receives || [])].some(\n (msg) => msg.id === messageId && msgVersionMatches(msg.version, messageVersion)\n );\n\n if (referencesMessage) {\n seen.add(key);\n const matchMsg = (msg: { id: string; version?: string }) =>\n msg.id === messageId && msgVersionMatches(msg.version, messageVersion);\n const resolvePointerVersion = <T extends { id: string; version?: string }>(msg: T): T => {\n if (msg.id === messageId && msg.version && msg.version !== messageVersion && messageVersion) {\n return { ...msg, version: messageVersion };\n }\n return msg;\n };\n const filtered: Service = {\n ...service,\n sends: service.sends?.filter(matchMsg).map(resolvePointerVersion),\n receives: service.receives?.filter(matchMsg).map(resolvePointerVersion),\n };\n await hydrateChannels(filtered, resolvers, seen, parts);\n parts.push(await serviceToDSL(filtered, { catalogDir, hydrate: false, _seen: new Set(seen), _msgIndex: msgIndex }));\n }\n }\n}\n\nasync function hydrateRelatedServices(\n messages: { id: string; version?: string }[],\n direction: 'sends' | 'receives',\n resolvers: ResourceResolvers,\n seen: Set<string>,\n parts: string[],\n catalogDir: string,\n msgIndex: MessageTypeIndex\n) {\n if (!messages.length) return;\n\n const referencesHydratedMessage = (msg: { id: string; version?: string }) =>\n messages.some((input) => msg.id === input.id && msgVersionMatches(msg.version, input.version));\n\n const services = (await resolvers.getServices({ latestOnly: false })) || [];\n for (const service of services) {\n const key = `service:${service.id}@${service.version || 'latest'}`;\n if (seen.has(key)) continue;\n\n if (direction === 'sends') {\n const matchedPointers = (service.sends || []).filter(referencesHydratedMessage);\n if (matchedPointers.length > 0) {\n seen.add(key);\n const filtered: Service = {\n ...service,\n sends: matchedPointers,\n receives: undefined,\n };\n await hydrateChannels(filtered, resolvers, seen, parts);\n parts.push(await serviceToDSL(filtered, { catalogDir, hydrate: false, _seen: new Set(seen), _msgIndex: msgIndex }));\n }\n } else {\n const matchedPointers = (service.receives || []).filter(referencesHydratedMessage);\n if (matchedPointers.length > 0) {\n seen.add(key);\n const filtered: Service = {\n ...service,\n sends: undefined,\n receives: matchedPointers,\n };\n await hydrateChannels(filtered, resolvers, seen, parts);\n parts.push(await serviceToDSL(filtered, { catalogDir, hydrate: false, _seen: new Set(seen), _msgIndex: msgIndex }));\n }\n }\n }\n}\n\nexport const toDSL =\n (catalogDir: string, resolvers: ResourceResolvers) =>\n async (resource: AnyResource | AnyResource[], options: ToDSLOptions): Promise<string> => {\n const resources = Array.isArray(resource) ? resource : [resource];\n const seen = new Set<string>();\n const parts: string[] = [];\n const msgIndex = buildMessageTypeIndex(catalogDir);\n\n for (const res of resources) {\n const key = `${options.type}:${res.id}@${res.version || 'latest'}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n switch (options.type) {\n case 'event':\n case 'command':\n case 'query':\n if (options.hydrate) {\n await hydrateOwners(res.owners, resolvers, seen, parts);\n await hydrateMessageServices(res.id, res.version, resolvers, seen, parts, catalogDir, msgIndex);\n }\n parts.push(messageToDSL(res as Event | Command | Query, options.type as MessageType));\n break;\n case 'service':\n if (options.hydrate) {\n await hydrateOwners(res.owners, resolvers, seen, parts);\n await hydrateChannels(res as Service, resolvers, seen, parts);\n await hydrateContainers(res as Service, resolvers, seen, parts);\n }\n parts.push(\n await serviceToDSL(\n res as Service,\n { catalogDir, hydrate: options.hydrate, _seen: seen, _msgIndex: msgIndex },\n getMessage(resolvers, msgIndex)\n )\n );\n if (options.hydrate) {\n const svc = res as Service;\n // For messages this service sends: find services that receive them (downstream consumers)\n await hydrateRelatedServices(svc.sends || [], 'receives', resolvers, seen, parts, catalogDir, msgIndex);\n // For messages this service receives: find services that send them (upstream producers)\n await hydrateRelatedServices(svc.receives || [], 'sends', resolvers, seen, parts, catalogDir, msgIndex);\n }\n break;\n case 'domain':\n if (options.hydrate) {\n await hydrateOwners(res.owners, resolvers, seen, parts);\n }\n parts.push(\n await domainToDSL(\n res as Domain,\n { catalogDir, hydrate: options.hydrate, _seen: seen, _msgIndex: msgIndex },\n {\n getService: resolvers.getService,\n getDomain: resolvers.getDomain,\n getMessage: getMessage(resolvers, msgIndex),\n getChannel: resolvers.getChannel,\n getTeam: resolvers.getTeam,\n getUser: resolvers.getUser,\n }\n )\n );\n if (options.hydrate) {\n const domain = res as Domain;\n const allSends: { id: string; version?: string }[] = [];\n const allReceives: { id: string; version?: string }[] = [];\n\n if (domain.services?.length) {\n for (const svcRef of domain.services) {\n const svc = await resolvers.getService(svcRef.id, svcRef.version);\n if (svc) {\n allSends.push(...(svc.sends || []));\n allReceives.push(...(svc.receives || []));\n }\n }\n }\n\n // Downstream: services that receive what domain services send\n await hydrateRelatedServices(allSends, 'receives', resolvers, seen, parts, catalogDir, msgIndex);\n // Upstream: services that send what domain services receive\n await hydrateRelatedServices(allReceives, 'sends', resolvers, seen, parts, catalogDir, msgIndex);\n }\n break;\n }\n }\n\n return parts.join('\\n\\n');\n };\n","import fs from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { findFileById, invalidateFileCache } 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 * // Get the event with the schema attached\n * const event = await getEvent('InventoryAdjusted', '0.0.1', { attachSchema: true });\n * ```\n */\nexport const getEvent =\n (directory: string) =>\n async (id: string, version?: string, options?: { attachSchema?: boolean }): Promise<Event> =>\n getResource(directory, id, version, { type: 'event', ...options }) 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 * // Get all events with the schema attached\n * const events = await getEvents({ attachSchema: true });\n * ```\n */\nexport const getEvents =\n (directory: string) =>\n async (options?: { latestOnly?: boolean; attachSchema?: 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'; override?: boolean } = { path: '', format: 'mdx', override: false }\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 invalidateFileCache();\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) =>\n async (id: string, file: { content: string; fileName: string }, version?: string, options?: { path?: string }) =>\n addFileToResource(directory, id, file, version, options);\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 { addFileToEvent } = 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 file to the latest InventoryAdjusted event\n * await addFileToEvent('InventoryAdjusted', { schema, fileName: 'schema.json' });\n *\n * // adds a file to a specific version of the InventoryAdjusted event\n * await addFileToEvent('InventoryAdjusted', { schema, fileName: 'schema.json' }, '0.0.1');\n *\n * ```\n */\nexport const addSchemaToEvent =\n (directory: string) =>\n async (id: string, schema: { schema: string; fileName: string }, version?: string, options?: { path?: string }) => {\n await addFileToEvent(directory)(id, { content: schema.schema, fileName: schema.fileName }, version, options);\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, normalize, sep as pathSeparator, resolve, basename, relative } from 'node:path';\nimport matter from 'gray-matter';\nimport { satisfies, validRange, valid } from 'semver';\n\n// In-memory file index cache. Auto-built on first read, invalidated on writes.\ninterface FileIndexEntry {\n path: string;\n id: string;\n version: string;\n isVersioned: boolean;\n}\n\nlet _fileIndexCache: Map<string, FileIndexEntry[]> | null = null;\nlet _fileIndexCatalogDir: string | null = null;\nlet _matterCache: Map<string, matter.GrayMatterFile<string>> | null = null;\nlet _filePathToIdCache: Map<string, string> | null = null;\nlet _fileIndexMtimeMs: number = 0;\n\nfunction toCanonicalPath(inputPath: string): string {\n return normalize(resolve(inputPath));\n}\n\nfunction buildFileCache(catalogDir: string): void {\n const canonicalCatalogDir = toCanonicalPath(catalogDir);\n const files = globSync('**/index.{md,mdx}', {\n cwd: canonicalCatalogDir,\n ignore: ['node_modules/**'],\n absolute: true,\n nodir: true,\n }).map(normalize);\n\n const index = new Map<string, FileIndexEntry[]>();\n const matterResults = new Map<string, matter.GrayMatterFile<string>>();\n const pathToId = new Map<string, string>();\n\n for (const file of files) {\n const content = fsSync.readFileSync(file, 'utf-8');\n const parsed = matter(content);\n matterResults.set(file, parsed);\n\n const id = parsed.data.id;\n if (!id) continue;\n\n const resourceId = String(id);\n const version = parsed.data.version || '';\n const isVersioned = file.includes('versioned');\n const entry: FileIndexEntry = { path: file, id: resourceId, version: String(version), isVersioned };\n pathToId.set(file, resourceId);\n\n const existing = index.get(resourceId);\n if (existing) {\n existing.push(entry);\n } else {\n index.set(resourceId, [entry]);\n }\n }\n\n _fileIndexCache = index;\n _fileIndexCatalogDir = canonicalCatalogDir;\n _matterCache = matterResults;\n _filePathToIdCache = pathToId;\n try {\n _fileIndexMtimeMs = fsSync.statSync(canonicalCatalogDir).mtimeMs;\n } catch {\n _fileIndexMtimeMs = 0;\n }\n}\n\nfunction ensureFileCache(catalogDir: string): void {\n const canonicalCatalogDir = toCanonicalPath(catalogDir);\n if (!_fileIndexCache || _fileIndexCatalogDir !== canonicalCatalogDir) {\n buildFileCache(catalogDir);\n return;\n }\n // Check if catalog dir was recreated (e.g. tests wiping and recreating)\n try {\n const currentMtime = fsSync.statSync(canonicalCatalogDir).mtimeMs;\n if (currentMtime !== _fileIndexMtimeMs) {\n buildFileCache(catalogDir);\n }\n } catch {\n buildFileCache(catalogDir);\n }\n}\n\n/** Invalidate the file cache. Call after any write/rm/version operation. */\nexport function invalidateFileCache(): void {\n _fileIndexCache = null;\n _fileIndexCatalogDir = null;\n _matterCache = null;\n _filePathToIdCache = null;\n}\n\n/**\n * Incrementally updates the in-memory file index for a single file write.\n * No-ops when cache is disabled or points at a different catalog.\n */\nexport function upsertFileCacheEntry(catalogDir: string, filePath: string, rawContent: string): void {\n const canonicalCatalogDir = toCanonicalPath(catalogDir);\n if (!_fileIndexCache || !_matterCache || !_filePathToIdCache || _fileIndexCatalogDir !== canonicalCatalogDir) {\n return;\n }\n\n const normalizedPath = toCanonicalPath(filePath);\n const parsed = matter(rawContent);\n\n // Remove stale entry for this file path (if it existed under another id/version).\n const previousId = _filePathToIdCache.get(normalizedPath);\n if (previousId) {\n const previousEntries = _fileIndexCache.get(previousId) || [];\n const nextEntries = previousEntries.filter((entry) => entry.path !== normalizedPath);\n if (nextEntries.length === 0) {\n _fileIndexCache.delete(previousId);\n } else {\n _fileIndexCache.set(previousId, nextEntries);\n }\n _filePathToIdCache.delete(normalizedPath);\n }\n\n _matterCache.set(normalizedPath, parsed);\n\n const id = parsed.data.id;\n if (!id) {\n _filePathToIdCache.delete(normalizedPath);\n return;\n }\n\n const resourceId = String(id);\n const entry: FileIndexEntry = {\n path: normalizedPath,\n id: resourceId,\n version: String(parsed.data.version || ''),\n isVersioned: normalizedPath.includes(`${pathSeparator}versioned${pathSeparator}`),\n };\n\n const entries = _fileIndexCache.get(resourceId) || [];\n entries.push(entry);\n _fileIndexCache.set(resourceId, entries);\n _filePathToIdCache.set(normalizedPath, resourceId);\n\n try {\n _fileIndexMtimeMs = fsSync.statSync(canonicalCatalogDir).mtimeMs;\n } catch {\n // Ignore mtime refresh failures; cache will self-heal on next ensureFileCache call.\n }\n}\n\n// Keep these as aliases for backwards compat with CLI export code\nexport const enableFileCache = buildFileCache;\nexport const disableFileCache = invalidateFileCache;\n\n/**\n * Returns cached matter.read result if available, otherwise reads from disk.\n */\nexport function cachedMatterRead(filePath: string): matter.GrayMatterFile<string> {\n if (_matterCache) {\n const cached = _matterCache.get(filePath);\n if (cached) return cached;\n }\n return matter.read(filePath);\n}\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 ensureFileCache(catalogDir);\n const entries = _fileIndexCache!.get(id);\n if (!entries) return false;\n return entries.some((e) => e.version === version);\n};\n\nexport const findFileById = async (catalogDir: string, id: string, version?: string): Promise<string | undefined> => {\n ensureFileCache(catalogDir);\n\n const entries = _fileIndexCache!.get(id);\n if (!entries || entries.length === 0) return undefined;\n\n const latestEntry = entries.find((e) => !e.isVersioned);\n\n if (!version || version === 'latest') {\n return latestEntry?.path;\n }\n\n // Exact version match\n const exactMatch = entries.find((e) => e.version === version);\n if (exactMatch) return exactMatch.path;\n\n // Semver range match\n const semverRange = validRange(version);\n if (semverRange) {\n const match = entries.find((e) => {\n try {\n return satisfies(e.version, semverRange);\n } catch {\n return false;\n }\n });\n return match?.path;\n }\n\n return undefined;\n};\n\nexport const getFiles = async (pattern: string, ignore: string | string[] = '') => {\n try {\n // 1. Normalize the input pattern to handle mixed separators potentially\n const normalizedInputPattern = normalize(pattern);\n\n // 2. Determine the absolute base directory (cwd for glob)\n // Resolve ensures it's absolute. Handles cases with/without globstar.\n const absoluteBaseDir = resolve(\n normalizedInputPattern.includes('**') ? normalizedInputPattern.split('**')[0] : dirname(normalizedInputPattern)\n );\n\n // 3. Determine the pattern part relative to the absolute base directory\n // We extract the part of the normalized pattern that comes *after* the absoluteBaseDir\n let relativePattern = relative(absoluteBaseDir, normalizedInputPattern);\n\n // On Windows, relative() might return empty string if paths are identical,\n // or might need normalization if the original pattern didn't have `**`\n // Example: pattern = 'dir/file.md', absoluteBaseDir='.../dir', normalized='...\\dir\\file.md'\n // relative() -> 'file.md'\n // Example: pattern = 'dir/**/file.md', absoluteBaseDir='.../dir', normalized='...\\dir\\**\\file.md'\n // relative() -> '**\\file.md'\n // Convert separators in the relative pattern to forward slashes for glob\n relativePattern = relativePattern.replace(/\\\\/g, '/');\n\n const ignoreList = Array.isArray(ignore) ? ignore : [ignore];\n\n const files = globSync(relativePattern, {\n cwd: absoluteBaseDir,\n ignore: ['node_modules/**', ...ignoreList],\n absolute: true,\n nodir: true,\n });\n\n // 5. Normalize results for consistency before returning\n return files.map(normalize);\n } catch (error: any) {\n // Add more diagnostic info to the error\n const absoluteBaseDirForError = resolve(\n normalize(pattern).includes('**') ? normalize(pattern).split('**')[0] : dirname(normalize(pattern))\n );\n const relativePatternForError = relative(absoluteBaseDirForError, normalize(pattern)).replace(/\\\\/g, '/');\n throw new Error(\n `Error finding files for pattern \"${pattern}\" (using cwd: \"${absoluteBaseDirForError}\", globPattern: \"${relativePatternForError}\"): ${error.message}`\n );\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 // Escape the id to avoid regex issues\n const escapedId = id.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const idRegex = new RegExp(`^id:\\\\s*(['\"]|>-)?\\\\s*${escapedId}['\"]?\\\\s*$`, 'm');\n\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 {\n copyDir,\n findFileById,\n getFiles,\n searchFilesForId,\n versionExists,\n cachedMatterRead,\n invalidateFileCache,\n upsertFileCacheEntry,\n} 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';\nimport { basename } from 'node:path';\nimport path from 'node:path';\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 // Handle both forward and back slashes for cross-platform compatibility (Windows uses \\, Unix uses /)\n const sourceDirectory = dirname(file).replace(/[/\\\\]versioned[/\\\\][^/\\\\]+[/\\\\]/, path.sep);\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 const ignoreListToCopy = ['events', 'commands', 'queries', 'versioned'];\n\n // Copy the event to the versioned directory\n await copyDir(catalogDir, sourceDirectory, targetDirectory, (src) => {\n // get the folder name\n const folderName = basename(src);\n\n if (ignoreListToCopy.includes(folderName)) {\n return false;\n }\n return true;\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 // Dont remove anything in the ignore list\n if (ignoreListToCopy.includes(file)) {\n return;\n }\n if (file !== 'versioned') {\n fsSync.rmSync(join(sourceDirectory, file), { recursive: true });\n }\n })\n );\n });\n\n invalidateFileCache();\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 upsertFileCacheEntry(catalogDir, 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; attachSchema?: boolean },\n filePath?: string\n): Promise<Resource | undefined> => {\n const attachSchema = options?.attachSchema || false;\n const file = filePath || (id ? await findFileById(catalogDir, id, version) : undefined);\n if (!file || !fsSync.existsSync(file)) return;\n\n const { data, content } = cachedMatterRead(file);\n\n if (attachSchema && data?.schemaPath) {\n const resourceDirectory = dirname(file);\n const pathToSchema = join(resourceDirectory, data.schemaPath);\n if (fsSync.existsSync(pathToSchema)) {\n const schema = fsSync.readFileSync(pathToSchema, 'utf8');\n // Try to parse the schema\n try {\n data.schema = JSON.parse(schema);\n } catch (error) {\n data.schema = schema;\n }\n }\n }\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 getResourceFolderName = async (catalogDir: string, id: string, version?: string) => {\n const paths = await getResourcePath(catalogDir, id, version);\n if (!paths) return;\n return paths?.directory.split(path.sep).filter(Boolean).pop();\n};\n\nexport const toResource = async (catalogDir: string, rawContents: string) => {\n const { data, content } = matter(rawContents);\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n};\n\nexport const getResources = async (\n catalogDir: string,\n {\n type,\n latestOnly = false,\n ignore = [],\n pattern = '',\n attachSchema = false,\n }: { type: string; pattern?: string; latestOnly?: boolean; ignore?: string[]; attachSchema?: boolean }\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 } = cachedMatterRead(file);\n\n // Attach the schema if the attachSchema option is set to true\n if (attachSchema && data?.schemaPath) {\n const resourceDirectory = dirname(file);\n const pathToSchema = join(resourceDirectory, data.schemaPath);\n if (fsSync.existsSync(pathToSchema)) {\n const schema = fsSync.readFileSync(pathToSchema, 'utf8');\n // Try to parse the schema\n try {\n data.schema = JSON.parse(schema);\n } catch (error) {\n data.schema = schema;\n }\n }\n }\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 // Verify file is actually removed\n await waitForFileRemoval(file);\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 // Verify directory is actually removed\n await waitForFileRemoval(directory);\n })\n );\n }\n\n invalidateFileCache();\n};\n\n// Helper function to ensure file/directory is completely removed\nconst waitForFileRemoval = async (path: string, maxRetries: number = 50, delay: number = 10): Promise<void> => {\n for (let i = 0; i < maxRetries; i++) {\n try {\n await fs.access(path);\n // If access succeeds, file still exists, wait and retry\n await new Promise((resolve) => setTimeout(resolve, delay));\n } catch (error) {\n // If access fails, file is removed\n return;\n }\n }\n // If we reach here, file still exists after all retries\n throw new Error(`File/directory ${path} was not removed after ${maxRetries} attempts`);\n};\n\nexport const addFileToResource = async (\n catalogDir: string,\n id: string,\n file: { content: string; fileName: string },\n version?: string,\n options?: { path?: string }\n) => {\n let pathToResource: string | undefined;\n\n if (options?.path) {\n pathToResource = join(catalogDir, options.path, 'index.mdx');\n } else {\n // Fall back to global lookup (existing behavior)\n pathToResource = await findFileById(catalogDir, id, version);\n }\n\n if (!pathToResource) throw new Error('Cannot find directory to write file to');\n\n // Create the directory if it doesn't exist\n fsSync.mkdirSync(path.dirname(pathToResource), { recursive: true });\n\n let fileContent = file.content.trim();\n\n try {\n const json = JSON.parse(fileContent);\n fileContent = JSON.stringify(json, null, 2);\n } catch (error) {\n // Just silently fail if the file is not valid JSON\n // Write it as it is\n }\n\n fsSync.writeFileSync(join(dirname(pathToResource), file.fileName), fileContent);\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\nexport const isLatestVersion = async (catalogDir: string, id: string, version?: string) => {\n const resource = await getResource(catalogDir, id, version);\n if (!resource) return false;\n\n const pathToResource = await getResourcePath(catalogDir, id, version);\n\n return !pathToResource?.relativePath.replace(/\\\\/g, '/').includes('/versioned/');\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, invalidateFileCache } 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 * // Gets the command with the schema attached\n * const command = await getCommand('UpdateInventory', '0.0.1', { attachSchema: true });\n * ```\n */\nexport const getCommand =\n (directory: string) =>\n async (id: string, version?: string, options?: { attachSchema?: boolean }): Promise<Command> =>\n getResource(directory, id, version, { type: 'command', ...options }) 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 * // Gets all commands with the schema attached\n * const commands = await getCommands({ attachSchema: true });\n * ```\n */\nexport const getCommands =\n (directory: string) =>\n async (options?: { latestOnly?: boolean; attachSchema?: 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'; override?: boolean } = { path: '', format: 'mdx', override: false }\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 invalidateFileCache();\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) =>\n async (id: string, file: { content: string; fileName: string }, version?: string, options?: { path?: string }) =>\n addFileToResource(directory, id, file, version, options);\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) =>\n async (id: string, schema: { schema: string; fileName: string }, version?: string, options?: { path?: string }) => {\n await addFileToCommand(directory)(id, { content: schema.schema, fileName: schema.fileName }, version, options);\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, invalidateFileCache } 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 * // Gets the query with the schema attached\n * const event = await getQuery('GetOrder', '0.0.1', { attachSchema: true });\n * ```\n */\nexport const getQuery =\n (directory: string) =>\n async (id: string, version?: string, options?: { attachSchema?: boolean }): Promise<Query> =>\n getResource(directory, id, version, { type: 'query', ...options }) 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 * // Gets all queries with the schema attached\n * const queries = await getQueries({ attachSchema: true });\n * ```\n */\nexport const getQueries =\n (directory: string) =>\n async (options?: { latestOnly?: boolean; attachSchema?: 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'; override?: boolean } = { path: '', format: 'mdx', override: false }\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 invalidateFileCache();\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) =>\n async (id: string, file: { content: string; fileName: string }, version?: string, options?: { path?: string }) =>\n addFileToResource(directory, id, file, version, options);\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) =>\n async (id: string, schema: { schema: string; fileName: string }, version?: string, options?: { path?: string }) => {\n await addFileToQuery(directory)(id, { content: schema.schema, fileName: schema.fileName }, version, options);\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, relative } from 'node:path';\nimport {\n addFileToResource,\n getFileFromResource,\n getResource,\n rmResourceById,\n versionResource,\n writeResource,\n getVersionedDirectory,\n getResources,\n getResourcePath,\n toResource,\n} from './internal/resources';\nimport { findFileById, invalidateFileCache, 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 a service from EventCatalog by it's path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getServiceByPath } = utils('/path/to/eventcatalog');\n *\n * // Returns a service from the catalog by it's path\n * const service = await getServiceByPath('/services/InventoryService/index.mdx');\n * ```\n */\nexport const getServiceByPath = (directory: string) => async (path: string) => {\n const service = await getResource(directory, undefined, undefined, { type: 'service' }, path);\n return service as Service;\n};\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: [\n '**/events/**',\n '**/commands/**',\n '**/queries/**',\n '**/entities/**',\n '**/channels/**',\n '**/containers/**',\n '**/data-products/**',\n '**/data-stores/**',\n '**/flows/**',\n '**/subdomains/**/entities/**',\n ],\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 as { id: string; version: string }[]);\n }\n\n if (Array.isArray(service.receives)) {\n resource.receives = uniqueVersions(service.receives as { id: string; version: string }[]);\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'; override?: boolean } = { path: '', format: 'mdx', override: false }\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 invalidateFileCache();\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 await rmResourceById(directory, id, version, { type: 'service', persistFiles });\n};\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 let specificationFiles;\n\n if (Array.isArray(serviceSpecifications)) {\n specificationFiles = serviceSpecifications.map((spec) => ({ key: spec.type, path: spec.path }));\n } else {\n specificationFiles = Object.keys(serviceSpecifications).map((spec) => ({\n key: spec,\n path: serviceSpecifications[spec as keyof Specifications] as string,\n }));\n }\n\n const getSpecs = specificationFiles.map(async ({ key, path: fileName }) => {\n if (!fileName) {\n throw new Error(`Specification file name for ${fileName} is undefined`);\n }\n const rawFile = await getFileFromResource(directory, id, { fileName }, version);\n\n return { key, 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, true);\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\n/**\n * Check to see if the path is a service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { isService } = utils('/path/to/eventcatalog');\n *\n * // returns true if the path is a service\n * await isService('/services/InventoryService/index.mdx');\n * ```\n */\nexport const isService = (directory: string) => async (path: string) => {\n const service = await getServiceByPath(directory)(path);\n // Get relative path from root directory\n const relativePath = relative(directory, path);\n\n // Split into path segments using regex to handle both / and \\\n const segments = relativePath.split(/[/\\\\]+/);\n\n // needs to workf or windows too\n return !!service && segments.includes('services');\n};\n\n/**\n * Takes a given raw file and converts it to a service.\n *\n * @param directory - The directory to convert the file to a service.\n * @returns The service.\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { toService } = utils('/path/to/eventcatalog');\n *\n * // Read the file from somewhere\n * const file = fs.readFileSync('/path/to/services/InventoryService/index.mdx', 'utf8');\n *\n * // Converts the raw file to a service\n * await toService(file);\n * ```\n */\nexport const toService = (directory: string) => async (file: string) => toResource(directory, file) as Promise<Service>;\n\n/**\n * Add an entity to a service by its id.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addEntityToService } = utils('/path/to/eventcatalog');\n *\n * // adds a new entity (User) to the InventoryService\n * await addEntityToService('InventoryService', { id: 'User', version: '1.0.0' });\n *\n * // adds a new entity (Product) to a specific version of the InventoryService\n * await addEntityToService('InventoryService', { id: 'Product', version: '1.0.0' }, '2.0.0');\n *\n * ```\n */\nexport const addEntityToService =\n (directory: string) => async (id: string, entity: { 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 (service.entities === undefined) {\n service.entities = [];\n }\n\n // Check if the entity is already in the list\n for (let i = 0; i < service.entities.length; i++) {\n if (service.entities[i].id === entity.id && service.entities[i].version === entity.version) {\n return;\n }\n }\n\n service.entities.push({ id: entity.id, version: entity.version });\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, true);\n await writeService(pathToResource)(service, { format: extension === '.md' ? 'md' : 'mdx' });\n };\n\n/**\n * Add a data store to a service by it's id.\n *\n * Optionally specify a version to add the data store to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds an data store to the service\n * const { addDataStoreToService } = utils('/path/to/eventcatalog');\n *\n * // Adds a new data store (orders-db) that the InventoryService will write to\n * await addDataStoreToService('InventoryService', 'writesTo', { id: 'orders-db', version: '2.0.0' });\n *\n * * // Adds a new data store (OrderComplete) that the InventoryService will read from\n * await addDataStoreToService('InventoryService', 'readsFrom', { id: 'orders-db', version: '1.0.0' });\n *\n * ```\n */\n\nexport const addDataStoreToService =\n (directory: string) =>\n async (id: string, operation: 'writesTo' | 'readsFrom', dataStore: { 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 (operation === 'writesTo') {\n if (service.writesTo === undefined) {\n service.writesTo = [];\n }\n\n // We first check if the data store is already in the list\n for (let i = 0; i < service.writesTo.length; i++) {\n if (service.writesTo[i].id === dataStore.id && service.writesTo[i].version === dataStore.version) {\n return;\n }\n }\n\n service.writesTo.push({ id: dataStore.id, version: dataStore.version });\n } else if (operation === 'readsFrom') {\n if (service.readsFrom === undefined) {\n service.readsFrom = [];\n }\n\n // We first check if the data store is already in the list\n for (let i = 0; i < service.readsFrom.length; i++) {\n if (service.readsFrom[i].id === dataStore.id && service.readsFrom[i].version === dataStore.version) {\n return;\n }\n }\n service.readsFrom.push({ id: dataStore.id, version: dataStore.version });\n } else {\n throw new Error(`Operation ${operation} is invalid, only 'writesTo' and 'readsFrom' 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, true);\n await writeService(pathToResource)(service, { format: extension === '.md' ? 'md' : 'mdx' });\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, invalidateFileCache, 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/**', '**/entities/**'],\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 as { id: string; version: string }[]);\n }\n\n if (Array.isArray(domain.domains)) {\n resource.domains = uniqueVersions(domain.domains as { id: string; version: string }[]);\n }\n\n if (Array.isArray(domain.sends)) {\n resource.sends = uniqueVersions(domain.sends as { id: string; version: string }[]);\n }\n\n if (Array.isArray(domain.receives)) {\n resource.receives = uniqueVersions(domain.receives as { id: string; version: string }[]);\n }\n\n if (Array.isArray(domain.dataProducts)) {\n resource.dataProducts = uniqueVersions(domain.dataProducts as { id: string; version: string }[]);\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 invalidateFileCache();\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\n/**\n * Add a subdomain to a domain by it's id.\n * Optionally specify a version to add the subdomain to a specific version of the domain\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds a subdomain to the given domain\n * const { addSubDomainToDomain } = utils('/path/to/eventcatalog');\n *\n * // Adds a subdomain (Payment Domain) to the domain (Orders)\n * await addSubDomainToDomain('Orders', { service: 'Payment Domain', version: '2.0.0' });\n * // Adds a subdomain (Inventory Domain) to the domain (Orders) with a specific version\n * await addSubDomainToDomain('Orders', { service: 'Inventory Domain', version: '2.0.0' }, '1.0.0');\n * ```\n */\n\nexport const addSubDomainToDomain =\n (directory: string) => async (id: string, subDomain: { 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.domains === undefined) {\n domain.domains = [];\n }\n\n const subDomainExistsInList = domain.domains.some((s) => s.id === subDomain.id && s.version === subDomain.version);\n\n if (subDomainExistsInList) {\n return;\n }\n\n // Add service to the list\n domain.domains.push(subDomain);\n\n await rmDomainById(directory)(id, version, true);\n await writeDomain(directory)(domain, { format: extension === '.md' ? 'md' : 'mdx' });\n };\n\n/**\n * Add an entity to a domain by its id.\n * Optionally specify a version to add the entity to a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds an entity to the domain\n * const { addEntityToDomain } = utils('/path/to/eventcatalog');\n *\n * // Adds an entity (User) to the domain (Orders)\n * await addEntityToDomain('Orders', { id: 'User', version: '1.0.0' });\n * // Adds an entity (Product) to the domain (Orders) with a specific version\n * await addEntityToDomain('Orders', { id: 'Product', version: '2.0.0' }, '1.0.0');\n * ```\n */\nexport const addEntityToDomain =\n (directory: string) => async (id: string, entity: { 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.entities === undefined) {\n domain.entities = [];\n }\n\n const entityExistsInList = domain.entities.some((e) => e.id === entity.id && e.version === entity.version);\n\n if (entityExistsInList) {\n return;\n }\n\n // Add entity to the list\n domain.entities.push(entity);\n\n await rmDomainById(directory)(id, version, true);\n await writeDomain(directory)(domain, { format: extension === '.md' ? 'md' : 'mdx' });\n };\n\n/**\n * Add a data product to a domain by its id.\n * Optionally specify a version to add the data product to a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds a data product to the domain\n * const { addDataProductToDomain } = utils('/path/to/eventcatalog');\n *\n * // Adds a data product (CustomerDataProduct) to the domain (Orders)\n * await addDataProductToDomain('Orders', { id: 'CustomerDataProduct', version: '1.0.0' });\n * // Adds a data product (SalesDataProduct) to the domain (Orders) with a specific version\n * await addDataProductToDomain('Orders', { id: 'SalesDataProduct', version: '2.0.0' }, '1.0.0');\n * ```\n */\nexport const addDataProductToDomain =\n (directory: string) => async (id: string, dataProduct: { 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.dataProducts === undefined) {\n domain.dataProducts = [];\n }\n\n const dataProductExistsInList = domain.dataProducts.some(\n (dp) => dp.id === dataProduct.id && dp.version === dataProduct.version\n );\n\n if (dataProductExistsInList) {\n return;\n }\n\n // Add data product to the list\n domain.dataProducts.push(dataProduct);\n\n await rmDomainById(directory)(id, version, true);\n await writeDomain(directory)(domain, { format: extension === '.md' ? 'md' : 'mdx' });\n };\n\n/**\n * Add an event/command/query to a domain by its id.\n *\n * Optionally specify a version to add the message to a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds an event to the domain\n * const { addEventToDomain, addCommandToDomain, addQueryToDomain } = utils('/path/to/eventcatalog');\n *\n * // Adds a new event (OrderCreated) that the Orders domain will send\n * await addEventToDomain('Orders', 'sends', { id: 'OrderCreated', version: '2.0.0' });\n *\n * // Adds a new event (PaymentProcessed) that the Orders domain will receive\n * await addEventToDomain('Orders', 'receives', { id: 'PaymentProcessed', version: '1.0.0' });\n *\n * // Adds a new command (ProcessOrder) that the Orders domain will receive\n * await addCommandToDomain('Orders', 'receives', { id: 'ProcessOrder', version: '1.0.0' });\n *\n * // Adds a message to a specific version of the domain\n * await addEventToDomain('Orders', 'sends', { id: 'OrderShipped', version: '1.0.0' }, '2.0.0');\n * ```\n */\nexport const addMessageToDomain =\n (directory: string) => async (id: string, direction: string, message: { id: string; version: string }, version?: string) => {\n let domain: Domain = await getDomain(directory)(id, version);\n const domainPath = await getResourcePath(directory, id, version);\n const extension = path.extname(domainPath?.fullPath || '');\n\n if (direction === 'sends') {\n if (domain.sends === undefined) {\n domain.sends = [];\n }\n // Check if the message is already in the list\n for (let i = 0; i < domain.sends.length; i++) {\n if (domain.sends[i].id === message.id && domain.sends[i].version === message.version) {\n return;\n }\n }\n domain.sends.push({ id: message.id, version: message.version });\n } else if (direction === 'receives') {\n if (domain.receives === undefined) {\n domain.receives = [];\n }\n // Check if the message is already in the list\n for (let i = 0; i < domain.receives.length; i++) {\n if (domain.receives[i].id === message.id && domain.receives[i].version === message.version) {\n return;\n }\n }\n domain.receives.push({ id: message.id, version: message.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 domain ${id} in the catalog`);\n }\n\n // Get where the domain was located, make sure it goes back there (handles subdomains)\n // Use lastIndexOf to find the last /domains/ in the path (for nested domains)\n const normalizedPath = existingResource.replace(/\\\\/g, '/');\n const lastDomainsIndex = normalizedPath.lastIndexOf('/domains/');\n const pathToResource = existingResource.substring(0, lastDomainsIndex + '/domains'.length);\n\n await rmDomainById(directory)(id, version, true);\n await writeDomain(pathToResource)(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, invalidateFileCache } 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 invalidateFileCache();\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 { dirname, join } from 'node:path';\nimport fsSync from 'node:fs';\nimport type { Message, Service } from './types';\nimport matter from 'gray-matter';\nimport { getResource, getResourcePath, isLatestVersion } from './internal/resources';\nimport { findFileById, getFiles } from './internal/utils';\nimport { getServices } from './services';\nimport { satisfies, validRange } from 'semver';\n\n/**\n * Returns a message from EventCatalog by a given schema path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getMessageBySchemaPath } = utils('/path/to/eventcatalog');\n *\n * // Get the message by the schema path\n * const message = await getMessageBySchemaPath('/path/to/eventcatalog/messages/InventoryAdjusted/schema.json');\n * const message = await getMessageBySchemaPath('/path/to/eventcatalog/messages/InventoryAdjusted/schema.avro');\n * ```\n */\nexport const getMessageBySchemaPath =\n (directory: string) =>\n async (path: string, options?: { attachSchema?: boolean }): Promise<Message> => {\n const pathToMessage = dirname(path);\n try {\n const files = await getFiles(`${directory}/${pathToMessage}/index.{md,mdx}`);\n\n if (!files || files.length === 0) {\n throw new Error(`No message definition file (index.md or index.mdx) found in directory: ${pathToMessage}`);\n }\n const messageFile = files[0];\n\n const { data } = matter.read(messageFile);\n const { id, version } = data;\n\n if (!id || !version) {\n throw new Error(`Message definition file at ${messageFile} is missing 'id' or 'version' in its frontmatter.`);\n }\n\n const message = await getResource(directory, id, version, { type: 'message', ...options });\n\n if (!message) {\n throw new Error(`Message resource with id '${id}' and version '${version}' not found, as referenced in ${messageFile}.`);\n }\n return message as Message;\n } catch (error) {\n // console.error(`Failed to get message for schema path ${path}. Error processing directory ${pathToMessage}:`, error);\n if (error instanceof Error) {\n // Prepend more context to the existing error message\n error.message = `Failed to retrieve message from ${pathToMessage}: ${error.message}`;\n throw error;\n }\n throw new Error(`Failed to retrieve message from ${pathToMessage} due to an unknown error.`);\n }\n };\n\n/**\n * Returns the producers and consumers (services) for a given message.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getProducersAndConsumersForMessage } = utils('/path/to/eventcatalog');\n *\n * // Returns the producers and consumers (services) for a given message\n * const { producers, consumers } = await getProducersAndConsumersForMessage('InventoryAdjusted', '0.0.1');\n */\nexport const getProducersAndConsumersForMessage =\n (directory: string) =>\n async (\n id: string,\n version?: string,\n options?: { latestOnly?: boolean }\n ): Promise<{ producers: Service[]; consumers: Service[] }> => {\n const services = await getServices(directory)({ latestOnly: options?.latestOnly ?? true });\n const message = (await getResource(directory, id, version, { type: 'message' })) as Message;\n const isMessageLatestVersion = await isLatestVersion(directory, id, version);\n\n if (!message) {\n throw new Error(`Message resource with id '${id}' and version '${version}' not found.`);\n }\n\n const producers: Service[] = [];\n const consumers: Service[] = [];\n\n for (const service of services) {\n const servicePublishesMessage = service.sends?.some((_message) => {\n if (_message.version) {\n const isServiceUsingSemverRange = validRange(_message.version);\n if (isServiceUsingSemverRange) {\n return _message.id === message.id && satisfies(message.version, _message.version);\n } else {\n return _message.id === message.id && message.version === _message.version;\n }\n }\n if (isMessageLatestVersion && _message.id === message.id) {\n return true;\n }\n return false;\n });\n const serviceSubscribesToMessage = service.receives?.some((_message) => {\n if (_message.version) {\n const isServiceUsingSemverRange = validRange(_message.version);\n if (isServiceUsingSemverRange) {\n return _message.id === message.id && satisfies(message.version, _message.version);\n } else {\n return _message.id === message.id && message.version === _message.version;\n }\n }\n if (isMessageLatestVersion && _message.id === message.id) {\n return true;\n }\n return false;\n });\n\n if (servicePublishesMessage) {\n producers.push(service);\n }\n if (serviceSubscribesToMessage) {\n consumers.push(service);\n }\n }\n\n return { producers, consumers };\n };\n\n/**\n * Returns the consumers of a given schema path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getConsumersOfSchema } = utils('/path/to/eventcatalog');\n *\n * // Returns the consumers of a given schema path\n * const consumers = await getConsumersOfSchema('events/InventoryAdjusted/schema.json');\n */\nexport const getConsumersOfSchema = (directory: string) => async (path: string) => {\n try {\n const message = await getMessageBySchemaPath(directory)(path);\n const { consumers } = await getProducersAndConsumersForMessage(directory)(message.id, message.version);\n return consumers;\n } catch (error) {\n return [];\n }\n};\n\n/**\n * Returns the producers of a given schema path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getProducersOfSchema } = utils('/path/to/eventcatalog');\n *\n * // Returns the producers of a given schema path\n * const producers = await getProducersOfSchema('events/InventoryAdjusted/schema.json');\n */\nexport const getProducersOfSchema = (directory: string) => async (path: string) => {\n try {\n const message = await getMessageBySchemaPath(directory)(path);\n const { producers } = await getProducersAndConsumersForMessage(directory)(message.id, message.version);\n return producers;\n } catch (error) {\n return [];\n }\n};\n\n/**\n * Returns the schema for a given message (event, command or query) by its id and version.\n *\n * If no version is given, the latest version is used.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getSchemaForMessage } = utils('/path/to/eventcatalog');\n *\n * // Get the schema for the latest version of the message\n * const schema = await getSchemaForMessage('InventoryAdjusted');\n *\n * // Get the schema for a specific version\n * const schema = await getSchemaForMessage('InventoryAdjusted', '0.0.1');\n * ```\n */\nexport const getSchemaForMessage =\n (directory: string) =>\n async (id: string, version?: string): Promise<{ schema: string; fileName: string } | undefined> => {\n const file = await findFileById(directory, id, version);\n if (!file || !fsSync.existsSync(file)) return undefined;\n\n const { data } = matter.read(file);\n\n if (!data.schemaPath) return undefined;\n\n const resourceDirectory = dirname(file);\n const pathToSchema = join(resourceDirectory, data.schemaPath);\n\n if (!fsSync.existsSync(pathToSchema)) return undefined;\n\n const schema = fsSync.readFileSync(pathToSchema, 'utf8');\n\n return {\n schema,\n fileName: data.schemaPath,\n };\n };\n","import path, { join } from 'node:path';\nimport { invalidateFileCache, 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 invalidateFileCache();\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 invalidateFileCache();\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, invalidateFileCache } from './internal/utils';\nimport { getResource } from './internal/resources';\nimport path from 'node:path';\nimport { getUser, getUsers } from './users';\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}/*.{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 invalidateFileCache();\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 invalidateFileCache();\n};\n\n/**\n * Returns the owners for a given resource (e.g domain, service, event, command, query, etc.)\n * @param id - The id of the resource to get the owners for\n * @param version - Optional version of the resource\n * @returns { owners: User[] }\n */\nexport const getOwnersForResource = (catalogDir: string) => async (id: string, version?: string) => {\n const resource = await getResource(catalogDir, id, version);\n let owners: Team[] = [];\n if (!resource) return [];\n\n if (!resource.owners) return [];\n\n // First check if the owner is a team\n for (const owner of resource.owners) {\n const team = await getTeam(path.join(catalogDir, 'teams'))(owner);\n if (team) {\n owners.push(team);\n } else {\n // If the owner is not a team, check if it's a user\n const user = await getUser(path.join(catalogDir, 'users'))(owner);\n if (user) {\n owners.push(user);\n }\n }\n }\n\n return owners;\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, invalidateFileCache } 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 invalidateFileCache();\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 invalidateFileCache();\n};\n","import type { EventCatalog } from './types';\nimport fs from 'fs';\nimport path, { join } from 'node:path';\nimport utils from './index';\nimport { getResourcePath } from './internal/resources';\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/**\n * Returns the event catalog configuration file.\n * The event catalog configuration file is the file that contains the configuration for the event catalog.\n *\n * @param directory - The directory of the catalog.\n * @returns A JSON object with the configuration for the event catalog.\n */\nexport const getEventCatalogConfigurationFile = (directory: string) => async (): Promise<any> => {\n // Read package.json in the catalogDir\n try {\n const path = join(directory, 'eventcatalog.config.js');\n // Dynamically import the ES module\n const configModule = await import(path);\n return configModule.default;\n } catch (error) {\n console.error('Error getting event catalog configuration file', error);\n return null;\n }\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<EventCatalog> => {\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 fs from 'node:fs';\nimport path from 'node:path';\nimport { execSync } from 'node:child_process';\nimport { compare } from 'semver';\nimport type { CatalogSnapshot, SnapshotOptions, SnapshotResult, SnapshotMeta, SnapshotDiff } from './snapshot-types';\nimport utils from './index';\nimport { computeResourceDiff, computeRelationshipDiff } from './snapshot-diff';\n\nconst SNAPSHOT_VERSION = '1.0.0';\n\nconst getEventCatalogVersion = (catalogDir: string): string => {\n try {\n const packageJson = fs.readFileSync(path.join(catalogDir, 'package.json'), 'utf8');\n const packageJsonObject = JSON.parse(packageJson);\n return packageJsonObject['dependencies']?.['@eventcatalog/core'] ?? 'unknown';\n } catch {\n return 'unknown';\n }\n};\n\nconst pickCoreFields = (resource: any): any => {\n const picked: any = { id: resource.id, version: resource.version, name: resource.name };\n if (resource.sends) picked.sends = resource.sends;\n if (resource.receives) picked.receives = resource.receives;\n if (resource.deprecated) picked.deprecated = resource.deprecated;\n if (resource.owners) picked.owners = resource.owners;\n return picked;\n};\n\nconst deduplicateByLatestVersion = (resources: any[]): any[] => {\n const seen = new Map<string, any>();\n for (const r of resources) {\n const existing = seen.get(r.id);\n if (!existing || compare(r.version, existing.version) > 0) {\n seen.set(r.id, r);\n }\n }\n return Array.from(seen.values());\n};\n\nconst stripToCore = (resources: any[] | undefined): any[] => {\n if (!resources || resources.length === 0) return [];\n return deduplicateByLatestVersion(resources).map(pickCoreFields);\n};\n\nconst detectGitInfo = (catalogDir: string): { branch: string; commit: string; dirty: boolean } | undefined => {\n try {\n const opts = { cwd: catalogDir, encoding: 'utf8' as const, stdio: 'pipe' as const };\n const branch = execSync('git rev-parse --abbrev-ref HEAD', opts).trim();\n const commit = execSync('git rev-parse --short HEAD', opts).trim();\n const status = execSync('git status --porcelain', opts).trim();\n return { branch, commit, dirty: status.length > 0 };\n } catch {\n return undefined;\n }\n};\n\nexport const createSnapshot = (directory: string) => {\n // Note: sdk is created lazily inside the inner function to avoid circular\n // dependency issues (index.ts imports snapshots.ts and vice versa).\n return async (options?: SnapshotOptions): Promise<SnapshotResult> => {\n const { label, outputDir, git } = options || {};\n const sdk = utils(directory);\n\n // Fetch all resources in parallel\n const [domains, services, events, commands, queries, channels] = await Promise.all([\n sdk.getDomains(),\n sdk.getServices(),\n sdk.getEvents(),\n sdk.getCommands(),\n sdk.getQueries(),\n sdk.getChannels(),\n ]);\n\n // Strip to core fields only (id, version, name, sends, receives, deprecated)\n const snapshotDomains = stripToCore(domains);\n const snapshotServices = stripToCore(services);\n const snapshotEvents = stripToCore(events);\n const snapshotCommands = stripToCore(commands);\n const snapshotQueries = stripToCore(queries);\n const snapshotChannels = stripToCore(channels);\n\n const snapshotLabel = label || new Date().toISOString().replace(/[:.]/g, '-');\n const gitInfo = git || detectGitInfo(directory);\n\n const snapshot: CatalogSnapshot = {\n snapshotVersion: SNAPSHOT_VERSION,\n catalogVersion: getEventCatalogVersion(directory),\n label: snapshotLabel,\n createdAt: new Date().toISOString(),\n ...(gitInfo ? { git: gitInfo } : {}),\n resources: {\n domains: snapshotDomains,\n services: snapshotServices,\n messages: {\n events: snapshotEvents,\n commands: snapshotCommands,\n queries: snapshotQueries,\n },\n channels: snapshotChannels,\n },\n };\n\n // Write to disk\n const snapshotsDir = outputDir || path.join(directory, '.snapshots');\n fs.mkdirSync(snapshotsDir, { recursive: true });\n const fileName = `${snapshotLabel}.snapshot.json`;\n const filePath = path.join(snapshotsDir, fileName);\n fs.writeFileSync(filePath, JSON.stringify(snapshot));\n\n return { filePath, snapshot };\n };\n};\n\nexport const diffSnapshots =\n (directory: string) =>\n async (snapshotAPath: string, snapshotBPath: string): Promise<SnapshotDiff> => {\n const snapshotA: CatalogSnapshot = JSON.parse(fs.readFileSync(snapshotAPath, 'utf-8'));\n const snapshotB: CatalogSnapshot = JSON.parse(fs.readFileSync(snapshotBPath, 'utf-8'));\n\n const resourceChanges = computeResourceDiff(snapshotA, snapshotB);\n const relationshipChanges = computeRelationshipDiff(snapshotA, snapshotB);\n\n const resourceCounts = { added: 0, removed: 0, modified: 0, versioned: 0 };\n for (const r of resourceChanges) resourceCounts[r.changeType]++;\n const relCounts = { added: 0, removed: 0 };\n for (const r of relationshipChanges) relCounts[r.changeType]++;\n\n return {\n snapshotA: { label: snapshotA.label, createdAt: snapshotA.createdAt },\n snapshotB: { label: snapshotB.label, createdAt: snapshotB.createdAt },\n summary: {\n totalChanges: resourceChanges.length + relationshipChanges.length,\n resourcesAdded: resourceCounts.added,\n resourcesRemoved: resourceCounts.removed,\n resourcesModified: resourceCounts.modified,\n resourcesVersioned: resourceCounts.versioned,\n relationshipsAdded: relCounts.added,\n relationshipsRemoved: relCounts.removed,\n },\n resources: resourceChanges,\n relationships: relationshipChanges,\n };\n };\n\nexport const listSnapshots = (directory: string) => async (): Promise<SnapshotMeta[]> => {\n const snapshotsDir = path.join(directory, '.snapshots');\n if (!fs.existsSync(snapshotsDir)) return [];\n\n const files = fs.readdirSync(snapshotsDir).filter((f) => f.endsWith('.snapshot.json'));\n const snapshots: SnapshotMeta[] = [];\n\n for (const file of files) {\n try {\n const filePath = path.join(snapshotsDir, file);\n const content: CatalogSnapshot = JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n snapshots.push({\n label: content.label,\n createdAt: content.createdAt,\n filePath,\n ...(content.git ? { git: content.git } : {}),\n });\n } catch {\n // skip invalid files\n }\n }\n\n return snapshots.sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n};\n","import type { CatalogSnapshot, ResourceChange, SnapshotResourceType, RelationshipChange } from './snapshot-types';\n\n/**\n * Stable JSON stringify with sorted keys for deep comparison.\n * Recurses into nested objects and arrays to ensure key order doesn't affect output.\n */\nconst stableStringify = (value: unknown): string => {\n if (value === null || value === undefined || typeof value !== 'object') {\n return JSON.stringify(value);\n }\n if (Array.isArray(value)) {\n return '[' + value.map(stableStringify).join(',') + ']';\n }\n const sorted = Object.keys(value as Record<string, unknown>)\n .sort()\n .map((key) => JSON.stringify(key) + ':' + stableStringify((value as Record<string, unknown>)[key]));\n return '{' + sorted.join(',') + '}';\n};\n\ntype FlatResource = {\n resourceId: string;\n version: string;\n type: SnapshotResourceType;\n data: Record<string, unknown>;\n};\n\nconst flattenResources = (snapshot: CatalogSnapshot): FlatResource[] => {\n const resources: FlatResource[] = [];\n\n const addResources = (items: Record<string, unknown>[], type: SnapshotResourceType) => {\n for (const item of items) {\n resources.push({\n resourceId: item.id as string,\n version: item.version as string,\n type,\n data: item,\n });\n }\n };\n\n addResources(snapshot.resources.domains, 'domain');\n addResources(snapshot.resources.services, 'service');\n addResources(snapshot.resources.messages.events, 'event');\n addResources(snapshot.resources.messages.commands, 'command');\n addResources(snapshot.resources.messages.queries, 'query');\n addResources(snapshot.resources.channels, 'channel');\n\n return resources;\n};\n\n// Fields to exclude from comparison\nconst EXCLUDED_FIELDS = new Set(['markdown', '_eventcatalog']);\n\nconst getComparableFields = (data: Record<string, unknown>): Record<string, unknown> => {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (!EXCLUDED_FIELDS.has(key)) {\n result[key] = value;\n }\n }\n return result;\n};\n\nconst findChangedFields = (dataA: Record<string, unknown>, dataB: Record<string, unknown>): string[] => {\n const fieldsA = getComparableFields(dataA);\n const fieldsB = getComparableFields(dataB);\n const allKeys = new Set([...Object.keys(fieldsA), ...Object.keys(fieldsB)]);\n const changed: string[] = [];\n\n for (const key of allKeys) {\n if (stableStringify(fieldsA[key] ?? null) !== stableStringify(fieldsB[key] ?? null)) {\n changed.push(key);\n }\n }\n\n return changed;\n};\n\nconst resourceKey = (r: FlatResource): string => `${r.resourceId}@${r.version}`;\nconst idTypeKey = (r: FlatResource): string => `${r.resourceId}:${r.type}`;\n\nexport const computeResourceDiff = (snapshotA: CatalogSnapshot, snapshotB: CatalogSnapshot): ResourceChange[] => {\n const resourcesA = flattenResources(snapshotA);\n const resourcesB = flattenResources(snapshotB);\n\n // Build both maps in a single pass per array\n const mapA = new Map<string, FlatResource>();\n const byIdA = new Map<string, FlatResource>();\n for (const r of resourcesA) {\n mapA.set(resourceKey(r), r);\n byIdA.set(idTypeKey(r), r);\n }\n\n const mapB = new Map<string, FlatResource>();\n const byIdB = new Map<string, FlatResource>();\n for (const r of resourcesB) {\n mapB.set(resourceKey(r), r);\n byIdB.set(idTypeKey(r), r);\n }\n\n const changes: ResourceChange[] = [];\n const handledIds = new Set<string>();\n\n // Find added resources (in B but not A)\n for (const resource of resourcesB) {\n const key = resourceKey(resource);\n if (!mapA.has(key)) {\n const idKey = idTypeKey(resource);\n const oldResource = byIdA.get(idKey);\n if (oldResource && oldResource.version !== resource.version && !handledIds.has(idKey)) {\n // Version bump: same id, different version\n const changedFields = findChangedFields(oldResource.data, resource.data);\n changes.push({\n resourceId: resource.resourceId,\n version: resource.version,\n type: resource.type,\n changeType: 'versioned',\n previousVersion: oldResource.version,\n newVersion: resource.version,\n changedFields: changedFields.length > 0 ? changedFields : undefined,\n });\n handledIds.add(idKey);\n } else if (!handledIds.has(idKey)) {\n changes.push({\n resourceId: resource.resourceId,\n version: resource.version,\n type: resource.type,\n changeType: 'added',\n });\n }\n }\n }\n\n // Find removed resources (in A but not B)\n for (const resource of resourcesA) {\n const key = resourceKey(resource);\n if (!mapB.has(key)) {\n const idKey = idTypeKey(resource);\n if (!handledIds.has(idKey)) {\n changes.push({\n resourceId: resource.resourceId,\n version: resource.version,\n type: resource.type,\n changeType: 'removed',\n });\n }\n }\n }\n\n // Find modified resources (in both, but fields differ)\n for (const resourceB of resourcesB) {\n const key = resourceKey(resourceB);\n const resourceA = mapA.get(key);\n if (resourceA) {\n const changedFields = findChangedFields(resourceA.data, resourceB.data);\n if (changedFields.length > 0) {\n changes.push({\n resourceId: resourceB.resourceId,\n version: resourceB.version,\n type: resourceB.type,\n changeType: 'modified',\n changedFields,\n });\n }\n }\n }\n\n return changes;\n};\n\ntype ServicePointer = { id: string; version?: string };\n\nconst getRelationshipKey = (\n serviceId: string,\n resourceId: string,\n resourceVersion: string | undefined,\n direction: string\n): string => {\n return `${serviceId}:${direction}:${resourceId}@${resourceVersion || 'latest'}`;\n};\n\ntype RelationshipInfo = Omit<RelationshipChange, 'changeType'>;\n\nconst extractRelationships = (snapshot: CatalogSnapshot): Map<string, RelationshipInfo> => {\n const relationships = new Map<string, RelationshipInfo>();\n\n for (const service of snapshot.resources.services) {\n for (const direction of ['sends', 'receives'] as const) {\n const pointers: ServicePointer[] = (service as Record<string, any>)[direction] || [];\n for (const pointer of pointers) {\n const key = getRelationshipKey(service.id as string, pointer.id, pointer.version, direction);\n relationships.set(key, {\n serviceId: service.id as string,\n serviceVersion: service.version as string,\n resourceId: pointer.id,\n resourceVersion: pointer.version,\n direction,\n });\n }\n }\n }\n\n return relationships;\n};\n\nexport const computeRelationshipDiff = (snapshotA: CatalogSnapshot, snapshotB: CatalogSnapshot): RelationshipChange[] => {\n const relsA = extractRelationships(snapshotA);\n const relsB = extractRelationships(snapshotB);\n\n const changes: RelationshipChange[] = [];\n\n // Relationships in B but not in A = added\n for (const [key, rel] of relsB) {\n if (!relsA.has(key)) {\n changes.push({ ...rel, changeType: 'added' });\n }\n }\n\n // Relationships in A but not in B = removed\n for (const [key, rel] of relsA) {\n if (!relsB.has(key)) {\n changes.push({ ...rel, changeType: 'removed' });\n }\n }\n\n return changes;\n};\n","import path, { dirname } from 'node:path';\nimport fsSync from 'node:fs';\nimport fs from 'node:fs/promises';\nimport matter from 'gray-matter';\nimport { findFileById, invalidateFileCache } from './internal/utils';\nimport type { Changelog } from './types';\n\n/**\n * Writes a changelog entry to a resource in EventCatalog.\n *\n * The changelog file (`changelog.mdx`) is written to the same directory as the resource's `index.mdx`.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeChangelog } = utils('/path/to/eventcatalog');\n *\n * // Write a changelog to a resource\n * await writeChangelog('OrderCreated', {\n * createdAt: '2024-08-01',\n * markdown: '### Added support for JSON Schema\\n\\nOrderCreated now supports JSON Draft 7.',\n * badges: [{ content: '⭐️ JSON Schema', backgroundColor: 'purple', textColor: 'purple' }],\n * });\n *\n * // Write a changelog to a specific version\n * await writeChangelog('OrderCreated', {\n * createdAt: '2024-08-01',\n * markdown: '### Breaking change\\n\\nRemoved `gender` field from schema.',\n * }, { version: '1.0.0' });\n * ```\n */\nexport const writeChangelog =\n (catalogDir: string) =>\n async (id: string, changelog: Changelog, options: { version?: string; format?: 'md' | 'mdx' } = {}): Promise<void> => {\n const { version, format = 'mdx' } = options;\n\n const resourceFile = await findFileById(catalogDir, id, version);\n if (!resourceFile) {\n throw new Error(`No resource found with id: ${id}${version ? ` and version: ${version}` : ''}`);\n }\n\n const resourceDir = dirname(resourceFile);\n const changelogPath = path.join(resourceDir, `changelog.${format}`);\n\n const { markdown, ...frontmatter } = changelog;\n\n // Ensure createdAt is serialized correctly for gray-matter\n const fm: Record<string, any> = { ...frontmatter };\n if (fm.createdAt instanceof Date) {\n fm.createdAt = fm.createdAt;\n }\n\n // Remove undefined/empty values from frontmatter\n if (!fm.badges || fm.badges.length === 0) {\n delete fm.badges;\n }\n\n fsSync.mkdirSync(resourceDir, { recursive: true });\n const document = matter.stringify(markdown.trim(), fm);\n fsSync.writeFileSync(changelogPath, document);\n invalidateFileCache();\n };\n\n/**\n * Appends a changelog entry to an existing changelog for a resource.\n * If no changelog exists, one is created.\n *\n * New entries are prepended to the top of the existing content, separated by `---`.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { appendChangelog } = utils('/path/to/eventcatalog');\n *\n * // Append to an existing changelog (or create if none exists)\n * await appendChangelog('OrderCreated', {\n * createdAt: '2024-09-01',\n * markdown: '### New field added\\n\\nAdded `priority` field.',\n * });\n *\n * // Append to a specific version's changelog\n * await appendChangelog('OrderCreated', {\n * createdAt: '2024-09-01',\n * markdown: '### Bugfix\\n\\nFixed validation.',\n * }, { version: '1.0.0' });\n * ```\n */\nexport const appendChangelog =\n (catalogDir: string) =>\n async (id: string, changelog: Changelog, options: { version?: string; format?: 'md' | 'mdx' } = {}): Promise<void> => {\n const { version, format = 'mdx' } = options;\n\n const resourceFile = await findFileById(catalogDir, id, version);\n if (!resourceFile) {\n throw new Error(`No resource found with id: ${id}${version ? ` and version: ${version}` : ''}`);\n }\n\n const resourceDir = dirname(resourceFile);\n\n // Find existing changelog file\n const mdxPath = path.join(resourceDir, 'changelog.mdx');\n const mdPath = path.join(resourceDir, 'changelog.md');\n const existingPath = fsSync.existsSync(mdxPath) ? mdxPath : fsSync.existsSync(mdPath) ? mdPath : undefined;\n\n if (!existingPath) {\n // No existing changelog — delegate to writeChangelog\n return writeChangelog(catalogDir)(id, changelog, options);\n }\n\n const existing = matter.read(existingPath);\n const existingContent = existing.content.trim();\n\n // Build the new entry markdown\n const newEntry = changelog.markdown.trim();\n\n // Prepend new entry, separated by ---\n const combined = `${newEntry}\\n\\n---\\n\\n${existingContent}`;\n\n // Merge frontmatter: use the new createdAt, merge badges\n const fm: Record<string, any> = { ...existing.data };\n fm.createdAt = changelog.createdAt;\n\n if (changelog.badges && changelog.badges.length > 0) {\n fm.badges = changelog.badges;\n } else {\n delete fm.badges;\n }\n\n const document = matter.stringify(combined, fm);\n fsSync.writeFileSync(existingPath, document);\n invalidateFileCache();\n };\n\n/**\n * Returns the changelog for a resource in EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getChangelog } = utils('/path/to/eventcatalog');\n *\n * // Get the changelog for a resource\n * const changelog = await getChangelog('OrderCreated');\n *\n * // Get the changelog for a specific version\n * const changelog = await getChangelog('OrderCreated', { version: '1.0.0' });\n * ```\n */\nexport const getChangelog =\n (catalogDir: string) =>\n async (id: string, options: { version?: string } = {}): Promise<Changelog | undefined> => {\n const { version } = options;\n\n const resourceFile = await findFileById(catalogDir, id, version);\n if (!resourceFile) return undefined;\n\n const resourceDir = dirname(resourceFile);\n\n // Try .mdx first, then .md\n const mdxPath = path.join(resourceDir, 'changelog.mdx');\n const mdPath = path.join(resourceDir, 'changelog.md');\n\n const changelogPath = fsSync.existsSync(mdxPath) ? mdxPath : fsSync.existsSync(mdPath) ? mdPath : undefined;\n\n if (!changelogPath) return undefined;\n\n const { data, content } = matter.read(changelogPath);\n return { ...data, markdown: content.trim() } as Changelog;\n };\n\n/**\n * Removes the changelog for a resource in EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmChangelog } = utils('/path/to/eventcatalog');\n *\n * // Remove the changelog for a resource\n * await rmChangelog('OrderCreated');\n *\n * // Remove the changelog for a specific version\n * await rmChangelog('OrderCreated', { version: '1.0.0' });\n * ```\n */\nexport const rmChangelog =\n (catalogDir: string) =>\n async (id: string, options: { version?: string } = {}): Promise<void> => {\n const { version } = options;\n\n const resourceFile = await findFileById(catalogDir, id, version);\n if (!resourceFile) {\n throw new Error(`No resource found with id: ${id}${version ? ` and version: ${version}` : ''}`);\n }\n\n const resourceDir = dirname(resourceFile);\n\n const mdxPath = path.join(resourceDir, 'changelog.mdx');\n const mdPath = path.join(resourceDir, 'changelog.md');\n\n if (fsSync.existsSync(mdxPath)) {\n await fs.rm(mdxPath);\n }\n if (fsSync.existsSync(mdPath)) {\n await fs.rm(mdPath);\n }\n\n invalidateFileCache();\n };\n","import fs from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { findFileById, invalidateFileCache } from './internal/utils';\nimport type { Entity } from './types';\nimport { getResource, getResources, rmResourceById, versionResource, writeResource } from './internal/resources';\n\n/**\n * Returns an entity from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the entity\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getEntity } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the entity\n * const entity = await getEntity('User');\n *\n * // Gets a version of the entity\n * const entity = await getEntity('User', '0.0.1');\n *\n * ```\n */\nexport const getEntity =\n (directory: string) =>\n async (id: string, version?: string): Promise<Entity> =>\n getResource(directory, id, version, { type: 'entity' }) as Promise<Entity>;\n\n/**\n * Returns all entities from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the entities.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getEntities } = utils('/path/to/eventcatalog');\n *\n * // Gets all entities (and versions) from the catalog\n * const entities = await getEntities();\n *\n * // Gets all entities (only latest version) from the catalog\n * const entities = await getEntities({ latestOnly: true });\n *\n * ```\n */\nexport const getEntities =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Entity[]> =>\n getResources(directory, { type: 'entities', latestOnly: options?.latestOnly }) as Promise<Entity[]>;\n\n/**\n * Write an entity to EventCatalog.\n *\n * You can optionally override the path of the entity.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeEntity } = utils('/path/to/eventcatalog');\n *\n * // Write an entity to the catalog\n * // Entity would be written to entities/User\n * await writeEntity({\n * id: 'User',\n * name: 'User',\n * version: '0.0.1',\n * summary: 'User entity',\n * markdown: '# User entity',\n * });\n *\n * // Write an entity to the catalog but override the path\n * // Entity would be written to entities/Account/User\n * await writeEntity({\n * id: 'User',\n * name: 'User',\n * version: '0.0.1',\n * summary: 'User entity',\n * markdown: '# User entity',\n * }, { path: \"/Account/User\"});\n *\n * // Write an entity to the catalog and override the existing content (if there is any)\n * await writeEntity({\n * id: 'User',\n * name: 'User',\n * version: '0.0.1',\n * summary: 'User entity',\n * markdown: '# User entity',\n * }, { override: true });\n *\n * // Write an entity to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeEntity({\n * id: 'User',\n * name: 'User',\n * version: '0.0.1',\n * summary: 'User entity',\n * markdown: '# User entity',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeEntity =\n (directory: string) =>\n async (\n entity: Entity,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...entity }, { ...options, type: 'entity' });\n\n/**\n * Delete an entity at its given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmEntity } = utils('/path/to/eventcatalog');\n *\n * // removes an entity at the given path (entities dir is appended to the given path)\n * // Removes the entity at entities/User\n * await rmEntity('/User');\n * ```\n */\nexport const rmEntity = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n invalidateFileCache();\n};\n\n/**\n * Delete an entity by its id.\n *\n * Optionally specify a version to delete a specific version of the entity.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmEntityById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest User entity\n * await rmEntityById('User');\n *\n * // deletes a specific version of the User entity\n * await rmEntityById('User', '0.0.1');\n * ```\n */\nexport const rmEntityById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) => {\n await rmResourceById(directory, id, version, { type: 'entity', persistFiles });\n};\n\n/**\n * Version an entity by its id.\n *\n * Takes the latest entity and moves it to a versioned directory.\n * All files with this entity are also versioned (e.g /entities/User/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionEntity } = utils('/path/to/eventcatalog');\n *\n * // moves the latest User entity to a versioned directory\n * // the version within that entity is used as the version number.\n * await versionEntity('User');\n *\n * ```\n */\nexport const versionEntity = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Check to see if the catalog has a version for the given entity.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { entityHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given entity and version (supports semver)\n * await entityHasVersion('User', '0.0.1');\n * await entityHasVersion('User', 'latest');\n * await entityHasVersion('User', '0.0.x');\n *\n * ```\n */\nexport const entityHasVersion = (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, invalidateFileCache } from './internal/utils';\nimport type { Container } 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 container (e.g. data store) from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the container\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getContainer } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the container\n * const container = await getContainer('User');\n *\n * // Gets a version of the entity\n * const container = await getContainer('User', '0.0.1');\n *\n * ```\n */\nexport const getContainer =\n (directory: string) =>\n async (id: string, version?: string): Promise<Container> =>\n getResource(directory, id, version, { type: 'container' }) as Promise<Container>;\n\n/**\n * Returns all containers (e.g. data stores) from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the containers.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getContainers } = utils('/path/to/eventcatalog');\n *\n * // Gets all containers (and versions) from the catalog\n * const containers = await getContainers();\n *\n * // Gets all entities (only latest version) from the catalog\n * const containers = await getContainers({ latestOnly: true });\n *\n * ```\n */\nexport const getContainers =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Container[]> =>\n getResources(directory, { type: 'containers', latestOnly: options?.latestOnly }) as Promise<Container[]>;\n\n/**\n * Write a container (e.g. data store) to EventCatalog.\n */\nexport const writeContainer =\n (directory: string) =>\n async (\n data: Container,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...data }, { ...options, type: 'container' });\n\n/**\n * Version an container (e.g. data store) by its id.\n *\n * Takes the latest container and moves it to a versioned directory.\n * All files with this container are also versioned (e.g /containers/orders-db/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionContainer } = utils('/path/to/eventcatalog');\n *\n * // moves the latest orders-db container to a versioned directory\n * // the version within that container is used as the version number.\n * await versionContainer('orders-db');\n *\n * ```\n */\nexport const versionContainer = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Delete an container (e.g. data store) at its given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmContainer } = utils('/path/to/eventcatalog');\n *\n * // removes an container at the given path (containers dir is appended to the given path)\n * // Removes the container at containers/orders-db\n * await rmContainer('/orders-db');\n * ```\n */\nexport const rmContainer = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n invalidateFileCache();\n};\n\n/**\n * Delete an container (e.g. data store) by its id.\n *\n * Optionally specify a version to delete a specific version of the container.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmContainerById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest orders-db container\n * await rmContainerById('orders-db');\n *\n * // deletes a specific version of the orders-db container\n * await rmContainerById('orders-db', '0.0.1');\n * ```\n */\nexport const rmContainerById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) => {\n await rmResourceById(directory, id, version, { type: 'container', persistFiles });\n};\n\n/**\n * Check to see if the catalog has a version for the given container (e.g. data store).\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { containerHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given entity and version (supports semver)\n * await containerHasVersion('orders-db', '0.0.1');\n * await containerHasVersion('orders-db', 'latest');\n * await containerHasVersion('orders-db', '0.0.x');\n *\n * ```\n */\nexport const containerHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n\n/**\n * Add a file to a container (e.g. data store) by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the container.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToContainer } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest InventoryAdjusted event\n * await addFileToContainer('InventoryAdjusted', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the InventoryAdjusted event\n * await addFileToContainer('InventoryAdjusted', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToContainer =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Write an data store (e.g. data store) to a service in EventCatalog.\n *\n * You can optionally override the path of the data store.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeContainerToService } = utils('/path/to/eventcatalog');\n *\n * // Write a container to a given service in the catalog\n * // Container would be written to services/Inventory/containers/orders-db\n * await writeContainerToService({\n * id: 'orders-db',\n * name: 'Orders DB',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * container_type: 'database',\n * }, { id: 'Inventory' });\n * ```\n */\nexport const writeContainerToService =\n (directory: string) =>\n async (\n container: Container,\n service: { id: string; version?: string },\n options: { path?: string; format?: 'md' | 'mdx'; override?: boolean } = { path: '', format: 'mdx', override: false }\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 pathForContainer =\n service.version && service.version !== 'latest'\n ? `${resourcePath.directory}/versioned/${service.version}/containers`\n : `${resourcePath.directory}/containers`;\n pathForContainer = join(pathForContainer, container.id);\n await writeResource(directory, { ...container }, { ...options, path: pathForContainer, type: 'container' });\n };\n","import * as Containers from './containers';\n\n/**\n * Returns a data store (e.g. database, cache, etc.) from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the data store\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getContainer } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the data store\n * const container = await getDataStore('orders-db');\n *\n * // Gets a version of the entity\n * const container = await getDataStore('orders-db', '0.0.1');\n *\n * ```\n */\nexport const getDataStore = Containers.getContainer;\n\n/**\n * Returns all data stores (e.g. databases, caches, etc.) from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the data stores.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getDataStores } = utils('/path/to/eventcatalog');\n *\n * // Gets all data stores (and versions) from the catalog\n * const containers = await getDataStores();\n *\n * // Gets all data stores (only latest version) from the catalog\n * const containers = await getDataStores({ latestOnly: true });\n *\n * ```\n */\nexport const getDataStores = Containers.getContainers;\n\n/**\n * Write a data store (e.g. database, cache, etc.) to EventCatalog.\n */\nexport const writeDataStore = Containers.writeContainer;\n\n/**\n * Version an data store (e.g. database, cache, etc.) by its id.\n *\n * Takes the latest data store and moves it to a versioned directory.\n * All files with this data store are also versioned (e.g /containers/orders-db/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionDataStore } = utils('/path/to/eventcatalog');\n *\n * // moves the latest orders-db data store to a versioned directory\n * // the version within that data store is used as the version number.\n * await versionDataStore('orders-db');\n *\n * ```\n */\nexport const versionDataStore = Containers.versionContainer;\n\n/**\n * Delete an data store (e.g. database, cache, etc.) at its given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDataStore } = utils('/path/to/eventcatalog');\n *\n * // removes an data store at the given path (containers dir is appended to the given path)\n * // Removes the data store at containers/orders-db\n * await rmDataStore('/orders-db');\n * ```\n */\nexport const rmDataStore = Containers.rmContainer;\n\n/**\n * Delete an data store (e.g. database, cache, etc.) by its id.\n *\n * Optionally specify a version to delete a specific version of the data store.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDataStoreById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest orders-db data store\n * await rmDataStoreById('orders-db');\n *\n * // deletes a specific version of the orders-db data store\n * await rmDataStoreById('orders-db', '0.0.1');\n * ```\n */\nexport const rmDataStoreById = Containers.rmContainerById;\n\n/**\n * Check to see if the catalog has a version for the given data store (e.g. database, cache, etc.).\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { dataStoreHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given data store and version (supports semver)\n * await dataStoreHasVersion('orders-db', '0.0.1');\n * await dataStoreHasVersion('orders-db', 'latest');\n * await dataStoreHasVersion('orders-db', '0.0.x');\n *\n * ```\n */\nexport const dataStoreHasVersion = Containers.containerHasVersion;\n\n/**\n * Add a file to a data store (e.g. database, cache, etc.) by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the data store.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToDataStore } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest InventoryAdjusted data store\n * await addFileToDataStore('InventoryAdjusted', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the InventoryAdjusted data store\n * await addFileToDataStore('InventoryAdjusted', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToDataStore = Containers.addFileToContainer;\n\n/**\n * Write an data store (e.g. database, cache, etc.) to a service in EventCatalog.\n *\n * You can optionally override the path of the data store.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeDataStoreToService } = utils('/path/to/eventcatalog');\n *\n * // Write a data store to a given service in the catalog\n * // Data store would be written to services/Inventory/containers/orders-db\n * await writeDataStoreToService({\n * id: 'orders-db',\n * name: 'Orders DB',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * container_type: 'database',\n * }, { id: 'Inventory' });\n * ```\n */\nexport const writeDataStoreToService = Containers.writeContainerToService;\n","import fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { findFileById, invalidateFileCache } from './internal/utils';\nimport type { DataProduct } from './types';\nimport {\n addFileToResource,\n getResource,\n getResources,\n rmResourceById,\n versionResource,\n writeResource,\n} from './internal/resources';\n\n/**\n * Returns a data product from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the data product\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getDataProduct } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the data product\n * const dataProduct = await getDataProduct('CustomerDataProduct');\n *\n * // Gets a version of the data product\n * const dataProduct = await getDataProduct('CustomerDataProduct', '0.0.1');\n *\n * ```\n */\nexport const getDataProduct =\n (directory: string) =>\n async (id: string, version?: string): Promise<DataProduct> =>\n getResource(directory, id, version, { type: 'data-product' }) as Promise<DataProduct>;\n\n/**\n * Returns all data products from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the data products.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getDataProducts } = utils('/path/to/eventcatalog');\n *\n * // Gets all data products (and versions) from the catalog\n * const dataProducts = await getDataProducts();\n *\n * // Gets all data products (only latest version) from the catalog\n * const dataProducts = await getDataProducts({ latestOnly: true });\n *\n * ```\n */\nexport const getDataProducts =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<DataProduct[]> =>\n getResources(directory, { type: 'data-products', latestOnly: options?.latestOnly }) as Promise<DataProduct[]>;\n\n/**\n * Write a data product to EventCatalog.\n *\n * You can optionally override the path of the data product.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeDataProduct } = utils('/path/to/eventcatalog');\n *\n * // Write a data product to the catalog\n * // Data product would be written to data-products/CustomerDataProduct\n * await writeDataProduct({\n * id: 'CustomerDataProduct',\n * name: 'Customer Data Product',\n * version: '0.0.1',\n * summary: 'Customer data product',\n * markdown: '# Customer data product',\n * });\n *\n * // Write a data product to the catalog but override the path\n * // Data product would be written to data-products/Account/CustomerDataProduct\n * await writeDataProduct({\n * id: 'CustomerDataProduct',\n * name: 'Customer Data Product',\n * version: '0.0.1',\n * summary: 'Customer data product',\n * markdown: '# Customer data product',\n * }, { path: \"/Account/CustomerDataProduct\"});\n *\n * // Write a data product to the catalog and override the existing content (if there is any)\n * await writeDataProduct({\n * id: 'CustomerDataProduct',\n * name: 'Customer Data Product',\n * version: '0.0.1',\n * summary: 'Customer data product',\n * markdown: '# Customer data product',\n * }, { override: true });\n *\n * // Write a data product to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeDataProduct({\n * id: 'CustomerDataProduct',\n * name: 'Customer Data Product',\n * version: '0.0.1',\n * summary: 'Customer data product',\n * markdown: '# Customer data product',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeDataProduct =\n (directory: string) =>\n async (\n dataProduct: DataProduct,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...dataProduct }, { ...options, type: 'data-product' });\n\n/**\n * Write a data product to a domain in EventCatalog.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeDataProductToDomain } = utils('/path/to/eventcatalog');\n *\n * // Write a data product to a domain\n * // Data product would be written to domains/Shopping/data-products/CustomerDataProduct\n * await writeDataProductToDomain({\n * id: 'CustomerDataProduct',\n * name: 'Customer Data Product',\n * version: '0.0.1',\n * summary: 'Customer data product',\n * markdown: '# Customer data product',\n * }, { id: 'Shopping' });\n * ```\n */\nexport const writeDataProductToDomain =\n (directory: string) =>\n async (\n dataProduct: DataProduct,\n domain: { id: string; version?: string },\n options: { path?: string; format?: 'md' | 'mdx'; override?: boolean } = { path: '', format: 'mdx', override: false }\n ) => {\n let pathForDataProduct =\n domain.version && domain.version !== 'latest'\n ? `/${domain.id}/versioned/${domain.version}/data-products`\n : `/${domain.id}/data-products`;\n pathForDataProduct = join(pathForDataProduct, dataProduct.id);\n\n await writeResource(directory, { ...dataProduct }, { ...options, path: pathForDataProduct, type: 'data-product' });\n };\n\n/**\n * Delete a data product at its given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDataProduct } = utils('/path/to/eventcatalog');\n *\n * // removes a data product at the given path (data-products dir is appended to the given path)\n * // Removes the data product at data-products/CustomerDataProduct\n * await rmDataProduct('/CustomerDataProduct');\n * ```\n */\nexport const rmDataProduct = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n invalidateFileCache();\n};\n\n/**\n * Delete a data product by its id.\n *\n * Optionally specify a version to delete a specific version of the data product.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDataProductById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest CustomerDataProduct data product\n * await rmDataProductById('CustomerDataProduct');\n *\n * // deletes a specific version of the CustomerDataProduct data product\n * await rmDataProductById('CustomerDataProduct', '0.0.1');\n * ```\n */\nexport const rmDataProductById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) => {\n await rmResourceById(directory, id, version, { type: 'data-product', persistFiles });\n};\n\n/**\n * Version a data product by its id.\n *\n * Takes the latest data product and moves it to a versioned directory.\n * All files with this data product are also versioned (e.g /data-products/CustomerDataProduct/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionDataProduct } = utils('/path/to/eventcatalog');\n *\n * // moves the latest CustomerDataProduct data product to a versioned directory\n * // the version within that data product is used as the version number.\n * await versionDataProduct('CustomerDataProduct');\n *\n * ```\n */\nexport const versionDataProduct = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Check to see if the catalog has a version for the given data product.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { dataProductHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given data product and version (supports semver)\n * await dataProductHasVersion('CustomerDataProduct', '0.0.1');\n * await dataProductHasVersion('CustomerDataProduct', 'latest');\n * await dataProductHasVersion('CustomerDataProduct', '0.0.x');\n *\n * ```\n */\nexport const dataProductHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n\n/**\n * Add a file to a data product by its id.\n *\n * Optionally specify a version to add a file to a specific version of the data product.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToDataProduct } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest CustomerDataProduct data product\n * await addFileToDataProduct('CustomerDataProduct', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the CustomerDataProduct data product\n * await addFileToDataProduct('CustomerDataProduct', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToDataProduct =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n","import fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { findFileById, invalidateFileCache } from './internal/utils';\nimport type { Diagram } from './types';\nimport {\n getResource,\n getResources,\n rmResourceById,\n versionResource,\n writeResource,\n addFileToResource,\n} from './internal/resources';\n\n/**\n * Returns a diagram from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the diagram\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getDiagram } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the diagram\n * const diagram = await getDiagram('ArchitectureDiagram');\n *\n * // Gets a version of the diagram\n * const diagram = await getDiagram('ArchitectureDiagram', '0.0.1');\n *\n * ```\n */\nexport const getDiagram =\n (directory: string) =>\n async (id: string, version?: string): Promise<Diagram> =>\n getResource(directory, id, version, { type: 'diagram' }) as Promise<Diagram>;\n\n/**\n * Returns all diagrams from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the diagrams.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getDiagrams } = utils('/path/to/eventcatalog');\n *\n * // Gets all diagrams (and versions) from the catalog\n * const diagrams = await getDiagrams();\n *\n * // Gets all diagrams (only latest version) from the catalog\n * const diagrams = await getDiagrams({ latestOnly: true });\n *\n * ```\n */\nexport const getDiagrams =\n (directory: string) =>\n async (options?: { latestOnly?: boolean }): Promise<Diagram[]> =>\n getResources(directory, { type: 'diagrams', latestOnly: options?.latestOnly }) as Promise<Diagram[]>;\n\n/**\n * Write a diagram to EventCatalog.\n *\n * You can optionally override the path of the diagram.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeDiagram } = utils('/path/to/eventcatalog');\n *\n * // Write a diagram to the catalog\n * // Diagram would be written to diagrams/ArchitectureDiagram\n * await writeDiagram({\n * id: 'ArchitectureDiagram',\n * name: 'Architecture Diagram',\n * version: '0.0.1',\n * summary: 'Architecture diagram',\n * markdown: '# Architecture Diagram',\n * });\n *\n * // Write a diagram to the catalog but override the path\n * // Diagram would be written to diagrams/System/ArchitectureDiagram\n * await writeDiagram({\n * id: 'ArchitectureDiagram',\n * name: 'Architecture Diagram',\n * version: '0.0.1',\n * summary: 'Architecture diagram',\n * markdown: '# Architecture Diagram',\n * }, { path: \"/System/ArchitectureDiagram\"});\n *\n * // Write a diagram to the catalog and override the existing content (if there is any)\n * await writeDiagram({\n * id: 'ArchitectureDiagram',\n * name: 'Architecture Diagram',\n * version: '0.0.1',\n * summary: 'Architecture diagram',\n * markdown: '# Architecture Diagram',\n * }, { override: true });\n *\n * // Write a diagram to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeDiagram({\n * id: 'ArchitectureDiagram',\n * name: 'Architecture Diagram',\n * version: '0.0.1',\n * summary: 'Architecture diagram',\n * markdown: '# Architecture Diagram',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeDiagram =\n (directory: string) =>\n async (\n diagram: Diagram,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...diagram }, { ...options, type: 'diagram' });\n\n/**\n * Delete a diagram at its given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDiagram } = utils('/path/to/eventcatalog');\n *\n * // removes a diagram at the given path (diagrams dir is appended to the given path)\n * // Removes the diagram at diagrams/ArchitectureDiagram\n * await rmDiagram('/ArchitectureDiagram');\n * ```\n */\nexport const rmDiagram = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n invalidateFileCache();\n};\n\n/**\n * Delete a diagram by its id.\n *\n * Optionally specify a version to delete a specific version of the diagram.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDiagramById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest ArchitectureDiagram diagram\n * await rmDiagramById('ArchitectureDiagram');\n *\n * // deletes a specific version of the ArchitectureDiagram diagram\n * await rmDiagramById('ArchitectureDiagram', '0.0.1');\n * ```\n */\nexport const rmDiagramById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) => {\n await rmResourceById(directory, id, version, { type: 'diagram', persistFiles });\n};\n\n/**\n * Version a diagram by its id.\n *\n * Takes the latest diagram and moves it to a versioned directory.\n * All files with this diagram are also versioned (e.g /diagrams/ArchitectureDiagram/diagram.png)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionDiagram } = utils('/path/to/eventcatalog');\n *\n * // moves the latest ArchitectureDiagram diagram to a versioned directory\n * // the version within that diagram is used as the version number.\n * await versionDiagram('ArchitectureDiagram');\n *\n * ```\n */\nexport const versionDiagram = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Check to see if the catalog has a version for the given diagram.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { diagramHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given diagram and version (supports semver)\n * await diagramHasVersion('ArchitectureDiagram', '0.0.1');\n * await diagramHasVersion('ArchitectureDiagram', 'latest');\n * await diagramHasVersion('ArchitectureDiagram', '0.0.x');\n *\n * ```\n */\nexport const diagramHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n\n/**\n * Adds a file to the given diagram.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToDiagram } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the diagram\n * await addFileToDiagram('ArchitectureDiagram', { content: '...', fileName: 'diagram.png' });\n *\n * // adds a file to a specific version of the diagram\n * await addFileToDiagram('ArchitectureDiagram', { content: '...', fileName: 'diagram.png' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToDiagram =\n (directory: string) =>\n async (id: string, file: { content: string; fileName: string }, version?: string): Promise<void> =>\n addFileToResource(directory, id, file, version, { type: 'diagram' });\n"],"mappings":"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","names":["join","hydrateOwners","fs","join","globSync","satisfies","validRange","entry","validRange","satisfies","globSync","path","dirname","join","matter","fsSync","satisfies","basename","dirname","file","join","path","resolve","join","path","fs","fs","join","join","path","fs","fs","join","join","path","fs","fs","join","dirname","relative","path","join","fs","dirname","relative","fs","path","join","fsSync","matter","path","fs","join","fsSync","fs","join","extname","path","fs","join","getMessage","extname","dirname","join","fsSync","matter","satisfies","validRange","path","dirname","matter","fsSync","join","path","join","fsSync","fs","matter","path","fsSync","matter","fs","join","fs","fsSync","join","matter","path","fsSync","join","matter","matter","fsSync","join","matter","fsSync","join","fs","path","fs","path","join","fs","join","path","getDomains","getServices","getEvents","getQueries","getCommands","getChannels","getTeams","getUsers","fs","path","getEventCatalogVersion","fs","path","path","dirname","fsSync","fs","matter","dirname","path","fsSync","matter","fs","fs","join","path","fs","join","fs","join","path","fs","join","fs","join","join","path","fs","fs","join","path","fs","join","path","join"]}
|