@eventcatalog/sdk 0.1.1 → 0.1.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/events.ts","../src/internal/utils.ts","../src/internal/resources.ts","../src/commands.ts","../src/services.ts","../src/domains.ts"],"sourcesContent":["import { join } from 'node:path';\nimport {\n rmEvent,\n rmEventById,\n writeEvent,\n versionEvent,\n getEvent,\n addFileToEvent,\n addSchemaToEvent,\n eventHasVersion,\n} from './events';\nimport {\n rmCommand,\n rmCommandById,\n writeCommand,\n versionCommand,\n getCommand,\n addFileToCommand,\n addSchemaToCommand,\n commandHasVersion,\n} from './commands';\nimport {\n writeService,\n getService,\n versionService,\n rmService,\n rmServiceById,\n addFileToService,\n addMessageToService,\n serviceHasVersion,\n} from './services';\nimport {\n writeDomain,\n getDomain,\n versionDomain,\n rmDomain,\n rmDomainById,\n addFileToDomain,\n domainHasVersion,\n addServiceToDomain,\n} from './domains';\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, 'events')),\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 * 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, 'events')),\n /**\n * Moves a given event id to the version directory\n * @param directory\n */\n versionEvent: versionEvent(join(path, 'events')),\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, 'events')),\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, 'events')),\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, 'events')),\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, 'commands')),\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 * 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, 'commands')),\n /**\n * Moves a given command id to the version directory\n * @param directory\n */\n versionCommand: versionCommand(join(path, 'commands')),\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, 'commands')),\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, 'commands')),\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, 'commands')),\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 * 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, 'services')),\n /**\n * Moves a given service id to the version directory\n * @param directory\n */\n versionService: versionService(join(path, 'services')),\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, 'services')),\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, 'services')),\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, 'services')),\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 * 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 * 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 * 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, 'services')),\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, 'services')),\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, 'domains')),\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","import matter from 'gray-matter';\nimport fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { dirname } from 'node:path';\nimport { copyDir, findFileById, getFiles, searchFilesForId, versionExists } from './internal/utils';\nimport type { Event } from './types';\nimport { addFileToResource, getResource, rmResourceById, versionResource, writeResource } from './internal/resources';\n\n/**\n * Returns an event from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the event\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getEvent } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the event\n * const event = await getEvent('InventoryAdjusted');\n *\n * // Gets a version of the event\n * const event = await getEvent('InventoryAdjusted', '0.0.1');\n * ```\n */\nexport const getEvent =\n (directory: string) =>\n async (id: string, version?: string): Promise<Event> =>\n getResource(directory, id, version, { type: 'event' }) as Promise<Event>;\n\n/**\n * 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 */\nexport const writeEvent =\n (directory: string) =>\n async (event: Event, options: { path: string } = { path: '' }) =>\n writeResource(directory, { ...event }, { ...options, type: 'event' });\n\n/**\n * Delete an event at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmEvent } = utils('/path/to/eventcatalog');\n *\n * // removes an event at the given path (events dir is appended to the given path)\n * // Removes the event at events/InventoryAdjusted\n * await rmEvent('/InventoryAdjusted');\n * ```\n */\nexport const rmEvent = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete an event by it's id.\n *\n * Optionally specify a version to delete a specific version of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmEventById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryAdjusted event\n * await rmEventById('InventoryAdjusted');\n *\n * // deletes a specific version of the InventoryAdjusted event\n * await rmEventById('InventoryAdjusted', '0.0.1');\n * ```\n */\nexport const rmEventById = (directory: string) => async (id: string, version?: string) =>\n rmResourceById(directory, id, version, { type: 'event' });\n\n/**\n * Version an event by it's id.\n *\n * Takes the latest event and moves it to a versioned directory.\n * All files with this event are also versioned (e.g /events/InventoryAdjusted/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionEvent } = utils('/path/to/eventcatalog');\n *\n * // moves the latest InventoryAdjusted event to a versioned directory\n * // the version within that event is used as the version number.\n * await versionEvent('InventoryAdjusted');\n *\n * ```\n */\nexport const versionEvent = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Add a file to an event by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToEvent } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest InventoryAdjusted event\n * await addFileToEvent('InventoryAdjusted', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the InventoryAdjusted event\n * await addFileToEvent('InventoryAdjusted', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToEvent =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Add a schema to an event by it's id.\n *\n * Optionally specify a version to add a schema to a specific version of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addSchemaToEvent } = utils('/path/to/eventcatalog');\n *\n * // JSON schema example\n * const schema = {\n * \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n * \"type\": \"object\",\n * \"properties\": {\n * \"name\": {\n * \"type\": \"string\"\n * },\n * \"age\": {\n * \"type\": \"number\"\n * }\n * },\n * \"required\": [\"name\", \"age\"]\n * };\n *\n * // adds a schema to the latest InventoryAdjusted event\n * await addSchemaToEvent('InventoryAdjusted', { schema, fileName: 'schema.json' });\n *\n * // adds a file to a specific version of the InventoryAdjusted event\n * await addSchemaToEvent('InventoryAdjusted', { schema, fileName: 'schema.json' }, '0.0.1');\n *\n * ```\n */\nexport const addSchemaToEvent =\n (directory: string) => async (id: string, schema: { schema: string; fileName: string }, version?: string) => {\n await addFileToEvent(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);\n };\n\n/**\n * Check to see if the catalog has a version for the given event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { eventHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await eventHasVersion('InventoryAdjusted', '0.0.1');\n * await eventHasVersion('InventoryAdjusted', 'latest');\n * await eventHasVersion('InventoryAdjusted', '0.0.x');*\n *\n * ```\n */\nexport const eventHasVersion = (directory: string) => async (id: string, version: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import { glob } from 'glob';\nimport fs from 'node:fs/promises';\nimport { copy, CopyFilterAsync, CopyFilterSync } from 'fs-extra';\nimport { join } from 'node:path';\nimport matter from 'gray-matter';\nimport { satisfies, validRange } from 'semver';\n\n/**\n * Returns true if a given version of a resource id exists in the catalog\n */\nexport const versionExists = async (catalogDir: string, id: string, version: string) => {\n const files = await getFiles(`${catalogDir}/**/index.md`);\n const matchedFiles = (await searchFilesForId(files, id, version)) || [];\n return matchedFiles.length > 0;\n};\n\nexport const findFileById = async (catalogDir: string, id: string, version?: string): Promise<string | undefined> => {\n const files = await getFiles(`${catalogDir}/**/index.md`);\n const matchedFiles = (await searchFilesForId(files, id)) || [];\n const latestVersion = matchedFiles.find((path) => !path.includes('versioned'));\n\n // If no version is provided, return the latest version\n if (!version) {\n return latestVersion;\n }\n\n // map files into gray matter to get versions\n const parsedFiles = matchedFiles.map((path) => {\n const { data } = matter.read(path);\n return { ...data, path };\n }) as any[];\n\n const semverRange = validRange(version);\n\n if (semverRange) {\n const match = parsedFiles.filter((c) => satisfies(c.version, semverRange));\n return match.length > 0 ? match[0].path : undefined;\n }\n\n // Order by version\n const sorted = parsedFiles.sort((a, b) => {\n return a.version.localeCompare(b.version);\n });\n\n // latest version\n const match = sorted.length > 0 ? [sorted[sorted.length - 1]] : [];\n\n if (match.length > 0) {\n return match[0].path;\n }\n};\n\nexport const getFiles = async (pattern: string) => {\n try {\n const files = await glob(pattern, { ignore: 'node_modules/**' });\n return files;\n } catch (error) {\n throw new Error(`Error finding files: ${error}`);\n }\n};\n\nexport const searchFilesForId = async (files: string[], id: string, version?: string) => {\n const idRegex = new RegExp(`^id:\\\\s*['\"]?${id}['\"]?\\\\s*$`, 'm');\n const versionRegex = new RegExp(`^version:\\\\s*['\"]?${version}['\"]?\\\\s*$`, 'm');\n\n const matches = await Promise.all(\n files.map(async (file) => {\n const content = await fs.readFile(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\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 await fs.mkdir(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 await fs.rm(tmpDirectory, { recursive: true });\n};\n","import { dirname, join } from 'path';\nimport { copyDir, findFileById, getFiles, searchFilesForId, versionExists } from './utils';\nimport matter from 'gray-matter';\nimport fs from 'node:fs/promises';\nimport { Message, Service } from '../types';\n\ntype Resource = Service | Message;\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`);\n const matchedFiles = await searchFilesForId(files, id);\n\n if (matchedFiles.length === 0) {\n throw new Error(`No event found with id: ${id}`);\n }\n\n // Event that is in the route of the project\n const file = matchedFiles[0];\n const sourceDirectory = dirname(file);\n const { data: { version = '0.0.1' } = {} } = matter.read(file);\n const targetDirectory = join(sourceDirectory, 'versioned', version);\n\n await fs.mkdir(targetDirectory, { recursive: true });\n\n // Copy the event to the versioned directory\n await copyDir(catalogDir, sourceDirectory, targetDirectory, (src) => {\n return !src.includes('versioned');\n });\n\n // Remove all the files in the root of the resource as they have now been versioned\n await fs.readdir(sourceDirectory).then(async (resourceFiles) => {\n await Promise.all(\n resourceFiles.map(async (file) => {\n if (file !== 'versioned') {\n await fs.rm(join(sourceDirectory, file), { recursive: true });\n }\n })\n );\n });\n};\n\nexport const writeResource = async (\n catalogDir: string,\n resource: Resource,\n options: { path: string; type: string } = { path: '', type: '' }\n) => {\n // Get the path\n const path = options.path || `/${resource.id}`;\n const exists = await versionExists(catalogDir, resource.id, resource.version);\n\n if (exists) {\n throw new Error(`Failed to write ${options.type} as the version ${resource.version} already exists`);\n }\n\n const { markdown, ...frontmatter } = resource;\n const document = matter.stringify(markdown.trim(), frontmatter);\n await fs.mkdir(join(catalogDir, path), { recursive: true });\n await fs.writeFile(join(catalogDir, path, 'index.md'), document);\n};\n\nexport const getResource = async (\n catalogDir: string,\n id: string,\n version?: string,\n options?: { type: string }\n): Promise<Resource | undefined> => {\n const file = await findFileById(catalogDir, id, version);\n if (!file) return;\n\n const { data, content } = matter.read(file);\n\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n};\n\nexport const rmResourceById = async (catalogDir: string, id: string, version?: string, options?: { type: string }) => {\n const files = await getFiles(`${catalogDir}/**/index.md`);\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 await Promise.all(matchedFiles.map((file) => fs.rm(file)));\n};\n\nexport const addFileToResource = async (\n catalogDir: string,\n id: string,\n file: { content: string; fileName: string },\n version?: string\n) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory to write file to');\n\n await fs.writeFile(join(dirname(pathToResource), file.fileName), file.content);\n};\n","import fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { Command } from './types';\nimport { addFileToResource, getResource, rmResourceById, versionResource, writeResource } from './internal/resources';\nimport { findFileById } from './internal/utils';\n\n/**\n * Returns a command from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the command\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getCommand } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the command\n * const command = await getCommand('UpdateInventory');\n *\n * // Gets a version of the command\n * const command = await getCommand('UpdateInventory', '0.0.1');\n * ```\n */\nexport const getCommand =\n (directory: string) =>\n async (id: string, version?: string): Promise<Command> =>\n getResource(directory, id, version, { type: 'command' }) as Promise<Command>;\n\n/**\n * 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 */\nexport const writeCommand =\n (directory: string) =>\n async (command: Command, options: { path: string } = { path: '' }) =>\n writeResource(directory, { ...command }, { ...options, type: 'command' });\n\n/**\n * Delete a command at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmCommand } = utils('/path/to/eventcatalog');\n *\n * // removes a command at the given path (commands dir is appended to the given path)\n * // Removes the command at commands/UpdateInventory\n * await rmCommand('/UpdateInventory');\n * ```\n */\nexport const rmCommand = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a command by it's id.\n *\n * Optionally specify a version to delete a specific version of the command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmCommandById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest UpdateInventory command\n * await rmCommandById('UpdateInventory');\n *\n * // deletes a specific version of the UpdateInventory command\n * await rmCommandById('UpdateInventory', '0.0.1');\n * ```\n */\nexport const rmCommandById = (directory: string) => async (id: string, version?: string) =>\n rmResourceById(directory, id, version, { type: 'command' });\n\n/**\n * Version a command by it's id.\n *\n * Takes the latest command and moves it to a versioned directory.\n * All files with this command are also versioned (e.g /commands/UpdateInventory/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionCommand } = utils('/path/to/eventcatalog');\n *\n * // moves the latest UpdateInventory command to a versioned directory\n * // the version within that command is used as the version number.\n * await versionCommand('UpdateInventory');\n *\n * ```\n */\nexport const versionCommand = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Add a file to a command by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToCommand } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest UpdateInventory command\n * await addFileToCommand('UpdateInventory', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the UpdateInventory command\n * await addFileToCommand('UpdateInventory', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToCommand =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Add a schema to a command by it's id.\n *\n * Optionally specify a version to add a schema to a specific version of the command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addSchemaToCommand } = utils('/path/to/eventcatalog');\n *\n * // JSON schema example\n * const schema = {\n * \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n * \"type\": \"object\",\n * \"properties\": {\n * \"name\": {\n * \"type\": \"string\"\n * },\n * \"age\": {\n * \"type\": \"number\"\n * }\n * },\n * \"required\": [\"name\", \"age\"]\n * };\n *\n * // adds a schema to the latest UpdateInventory command\n * await addSchemaToCommand('UpdateInventory', { schema, fileName: 'schema.json' });\n *\n * // adds a file to a specific version of the UpdateInventory command\n * await addSchemaToCommand('UpdateInventory', { schema, fileName: 'schema.json' }, '0.0.1');\n *\n * ```\n */\nexport const addSchemaToCommand =\n (directory: string) => async (id: string, schema: { schema: string; fileName: string }, version?: string) => {\n await addFileToCommand(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);\n };\n\n/**\n * Check to see if the catalog has a version for the given command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { commandHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await commandHasVersion('InventoryAdjusted', '0.0.1');\n * await commandHasVersion('InventoryAdjusted', 'latest');\n * await commandHasVersion('InventoryAdjusted', '0.0.x');*\n *\n * ```\n */\nexport const commandHasVersion = (directory: string) => async (id: string, version: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import type { Service } from './types';\nimport fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { addFileToResource, getResource, rmResourceById, versionResource, writeResource } from './internal/resources';\nimport { findFileById } 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 * 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 { writeService } = utils('/path/to/eventcatalog');\n *\n * // Write a service\n * // Event 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 an event to the catalog but override the path\n * // Event 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 */\nexport const writeService =\n (directory: string) =>\n async (service: Service, options: { path: string } = { path: '' }) =>\n writeResource(directory, { ...service }, { ...options, type: 'service' });\n\n/**\n * Version a service by it's id.\n *\n * Takes the latest service and moves it to a versioned directory.\n * All files with this service are also versioned. (e.g /services/InventoryService/openapi.yml)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionService } = utils('/path/to/eventcatalog');\n *\n * // moves the latest InventoryService service to a versioned directory\n * // the version within that service is used as the version number.\n * await versionService('InventoryService');\n *\n * ```\n */\nexport const versionService = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Delete a service at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmService } = utils('/path/to/eventcatalog');\n *\n * // Removes the service at services/InventoryService\n * await rmService('/InventoryService');\n * ```\n */\nexport const rmService = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a service by it's id.\n *\n * Optionally specify a version to delete a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmServiceById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryService event\n * await rmServiceById('InventoryService');\n *\n * // deletes a specific version of the InventoryService event\n * await rmServiceById('InventoryService', '0.0.1');\n * ```\n */\nexport const rmServiceById = (directory: string) => async (id: string, version?: string) =>\n rmResourceById(directory, id, version, { type: 'service' });\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 * Add an event/command to a service by it's id.\n *\n * Optionally specify a version to add the event to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds an event to the service or command to the service\n * const { addEventToService, addCommandToService } = utils('/path/to/eventcatalog');\n *\n * // Adds a new event (InventoryUpdatedEvent) that the InventoryService will send\n * await addEventToService('InventoryService', 'sends', { event: 'InventoryUpdatedEvent', version: '2.0.0' });\n * * // Adds a new event (OrderComplete) that the InventoryService will receive\n * await addEventToService('InventoryService', 'receives', { event: 'OrderComplete', version: '1.0.0' });\n *\n * // Adds a new command (UpdateInventoryCommand) that the InventoryService will send\n * await addCommandToService('InventoryService', 'sends', { command: 'UpdateInventoryCommand', version: '2.0.0' });\n * // Adds a new command (VerifyInventory) that the InventoryService will receive\n * await addCommandToService('InventoryService', 'receives', { command: 'VerifyInventory', version: '1.0.0' });\n *\n * ```\n */\n\nexport const addMessageToService =\n (directory: string) => async (id: string, direction: string, event: { id: string; version: string }, version?: string) => {\n let service: Service = await getService(directory)(id, version);\n\n if (direction === 'sends') {\n if (service.sends === undefined) {\n service.sends = [];\n }\n // We first check if the event is already in the list\n for (let i = 0; i < service.sends.length; i++) {\n if (service.sends[i].id === event.id && service.sends[i].version === event.version) {\n return;\n }\n }\n service.sends.push({ id: event.id, version: event.version });\n } else if (direction === 'receives') {\n if (service.receives === undefined) {\n service.receives = [];\n }\n // We first check if the event is already in the list\n for (let i = 0; i < service.receives.length; i++) {\n if (service.receives[i].id === event.id && service.receives[i].version === event.version) {\n return;\n }\n }\n service.receives.push({ id: event.id, version: event.version });\n } else {\n throw new Error(`Direction ${direction} is invalid, only 'receives' and 'sends' are supported`);\n }\n\n await rmServiceById(directory)(id, version);\n await writeService(directory)(service);\n };\n\n/**\n * Check to see if the catalog has a version for the given service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { serviceHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await serviceHasVersion('InventoryService', '0.0.1');\n * await serviceHasVersion('InventoryService', 'latest');\n * await serviceHasVersion('InventoryService', '0.0.x');*\n *\n * ```\n */\nexport const serviceHasVersion = (directory: string) => async (id: string, version: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import type { Domain } from './types';\nimport fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { addFileToResource, getResource, rmResourceById, versionResource, writeResource } from './internal/resources';\nimport { findFileById } from './internal/utils';\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 * 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 * // Event 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 * // Event 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 */\nexport const writeDomain =\n (directory: string) =>\n async (domain: Domain, options: { path: string } = { path: '' }) =>\n writeResource(directory, { ...domain }, { ...options, type: 'domain' });\n\n/**\n * Version a domain by it's id.\n *\n * Takes the latest domain and moves it to a versioned directory.\n * All files with this domain are also versioned. (e.g /domains/Payment/openapi.yml)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionDomain } = utils('/path/to/eventcatalog');\n *\n * // moves the latest Payment domain to a versioned directory\n * // the version within that domain is used as the version number.\n * await versionDomain('Payment');\n *\n * ```\n */\nexport const versionDomain = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Delete a domain at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDomain } = utils('/path/to/eventcatalog');\n *\n * // Removes the domain at domains/Payment\n * await rmDomain('/Payment');\n * ```\n */\nexport const rmDomain = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a domain by it's id.\n *\n * Optionally specify a version to delete a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDomainById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest Payment event\n * await rmDomainById('Payment');\n *\n * // deletes a specific version of the Payment event\n * await rmDomainById('Payment', '0.0.1');\n * ```\n */\nexport const rmDomainById = (directory: string) => async (id: string, version?: string) =>\n rmResourceById(directory, id, version, { type: 'domain' });\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 * 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 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 a service to the domain\n * const { addServiceToDomain } = utils('/path/to/eventcatalog');\n *\n * // Adds a service (Orders Service) to the domain (Orders)\n * await addServiceToDomain('Orders', { service: 'Order Service', version: '2.0.0' });\n * // Adds a service (Orders Service) to the domain (Orders) with a specific version\n * await addServiceToDomain('Orders', { service: 'Order Service', version: '2.0.0' }, '1.0.0');\n * ```\n */\n\nexport const addServiceToDomain =\n (directory: string) => async (id: string, service: { id: string; version: string }, version?: string) => {\n let domain: Domain = await getDomain(directory)(id, version);\n\n if (domain.services === undefined) {\n domain.services = [];\n }\n\n const eventExistsInList = domain.services.some((s) => s.id === service.id && s.version === service.version);\n\n if (eventExistsInList) {\n return;\n }\n\n // Add service to the list\n domain.services.push(service);\n\n await rmDomainById(directory)(id, version);\n await writeDomain(directory)(domain);\n };\n"],"mappings":"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","names":["join","fs","join","match","join","matter","fs","join","file","fs","join","fs","join","fs","join","fs","join","fs","join","fs","join","fs","join","join"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/events.ts","../src/internal/utils.ts","../src/internal/resources.ts","../src/commands.ts","../src/services.ts","../src/domains.ts"],"sourcesContent":["import { join } from 'node:path';\nimport {\n rmEvent,\n rmEventById,\n writeEvent,\n versionEvent,\n getEvent,\n addFileToEvent,\n addSchemaToEvent,\n eventHasVersion,\n} from './events';\nimport {\n rmCommand,\n rmCommandById,\n writeCommand,\n versionCommand,\n getCommand,\n addFileToCommand,\n addSchemaToCommand,\n commandHasVersion,\n} from './commands';\nimport {\n writeService,\n getService,\n versionService,\n rmService,\n rmServiceById,\n addFileToService,\n addMessageToService,\n serviceHasVersion,\n getSpecificationFilesForService,\n} from './services';\nimport {\n writeDomain,\n getDomain,\n versionDomain,\n rmDomain,\n rmDomainById,\n addFileToDomain,\n domainHasVersion,\n addServiceToDomain,\n} from './domains';\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, 'events')),\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 * 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, 'events')),\n /**\n * Moves a given event id to the version directory\n * @param directory\n */\n versionEvent: versionEvent(join(path, 'events')),\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, 'events')),\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, 'events')),\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, 'events')),\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, 'commands')),\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 * 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, 'commands')),\n /**\n * Moves a given command id to the version directory\n * @param directory\n */\n versionCommand: versionCommand(join(path, 'commands')),\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, 'commands')),\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, 'commands')),\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, 'commands')),\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 * 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, 'services')),\n /**\n * Moves a given service id to the version directory\n * @param directory\n */\n versionService: versionService(join(path, 'services')),\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, 'services')),\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, 'services')),\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, 'services')),\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, 'services')),\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 * 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 * 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 * 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, 'services')),\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, 'services')),\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, 'domains')),\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","import matter from 'gray-matter';\nimport fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { dirname } from 'node:path';\nimport { copyDir, findFileById, getFiles, searchFilesForId, versionExists } from './internal/utils';\nimport type { Event } from './types';\nimport { addFileToResource, getResource, rmResourceById, versionResource, writeResource } from './internal/resources';\n\n/**\n * Returns an event from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the event\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getEvent } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the event\n * const event = await getEvent('InventoryAdjusted');\n *\n * // Gets a version of the event\n * const event = await getEvent('InventoryAdjusted', '0.0.1');\n * ```\n */\nexport const getEvent =\n (directory: string) =>\n async (id: string, version?: string): Promise<Event> =>\n getResource(directory, id, version, { type: 'event' }) as Promise<Event>;\n\n/**\n * 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 */\nexport const writeEvent =\n (directory: string) =>\n async (event: Event, options: { path: string } = { path: '' }) =>\n writeResource(directory, { ...event }, { ...options, type: 'event' });\n\n/**\n * Delete an event at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmEvent } = utils('/path/to/eventcatalog');\n *\n * // removes an event at the given path (events dir is appended to the given path)\n * // Removes the event at events/InventoryAdjusted\n * await rmEvent('/InventoryAdjusted');\n * ```\n */\nexport const rmEvent = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete an event by it's id.\n *\n * Optionally specify a version to delete a specific version of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmEventById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryAdjusted event\n * await rmEventById('InventoryAdjusted');\n *\n * // deletes a specific version of the InventoryAdjusted event\n * await rmEventById('InventoryAdjusted', '0.0.1');\n * ```\n */\nexport const rmEventById = (directory: string) => async (id: string, version?: string) =>\n rmResourceById(directory, id, version, { type: 'event' });\n\n/**\n * Version an event by it's id.\n *\n * Takes the latest event and moves it to a versioned directory.\n * All files with this event are also versioned (e.g /events/InventoryAdjusted/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionEvent } = utils('/path/to/eventcatalog');\n *\n * // moves the latest InventoryAdjusted event to a versioned directory\n * // the version within that event is used as the version number.\n * await versionEvent('InventoryAdjusted');\n *\n * ```\n */\nexport const versionEvent = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Add a file to an event by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToEvent } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest InventoryAdjusted event\n * await addFileToEvent('InventoryAdjusted', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the InventoryAdjusted event\n * await addFileToEvent('InventoryAdjusted', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToEvent =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Add a schema to an event by it's id.\n *\n * Optionally specify a version to add a schema to a specific version of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addSchemaToEvent } = utils('/path/to/eventcatalog');\n *\n * // JSON schema example\n * const schema = {\n * \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n * \"type\": \"object\",\n * \"properties\": {\n * \"name\": {\n * \"type\": \"string\"\n * },\n * \"age\": {\n * \"type\": \"number\"\n * }\n * },\n * \"required\": [\"name\", \"age\"]\n * };\n *\n * // adds a schema to the latest InventoryAdjusted event\n * await addSchemaToEvent('InventoryAdjusted', { schema, fileName: 'schema.json' });\n *\n * // adds a file to a specific version of the InventoryAdjusted event\n * await addSchemaToEvent('InventoryAdjusted', { schema, fileName: 'schema.json' }, '0.0.1');\n *\n * ```\n */\nexport const addSchemaToEvent =\n (directory: string) => async (id: string, schema: { schema: string; fileName: string }, version?: string) => {\n await addFileToEvent(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);\n };\n\n/**\n * Check to see if the catalog has a version for the given event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { eventHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await eventHasVersion('InventoryAdjusted', '0.0.1');\n * await eventHasVersion('InventoryAdjusted', 'latest');\n * await eventHasVersion('InventoryAdjusted', '0.0.x');*\n *\n * ```\n */\nexport const eventHasVersion = (directory: string) => async (id: string, version: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import { glob } from 'glob';\nimport fs from 'node:fs/promises';\nimport { copy, CopyFilterAsync, CopyFilterSync } from 'fs-extra';\nimport { join } from 'node:path';\nimport matter from 'gray-matter';\nimport { satisfies, validRange } from 'semver';\n\n/**\n * Returns true if a given version of a resource id exists in the catalog\n */\nexport const versionExists = async (catalogDir: string, id: string, version: string) => {\n const files = await getFiles(`${catalogDir}/**/index.md`);\n const matchedFiles = (await searchFilesForId(files, id, version)) || [];\n return matchedFiles.length > 0;\n};\n\nexport const findFileById = async (catalogDir: string, id: string, version?: string): Promise<string | undefined> => {\n const files = await getFiles(`${catalogDir}/**/index.md`);\n const matchedFiles = (await searchFilesForId(files, id)) || [];\n const latestVersion = matchedFiles.find((path) => !path.includes('versioned'));\n\n // If no version is provided, return the latest version\n if (!version) {\n return latestVersion;\n }\n\n // map files into gray matter to get versions\n const parsedFiles = matchedFiles.map((path) => {\n const { data } = matter.read(path);\n return { ...data, path };\n }) as any[];\n\n const semverRange = validRange(version);\n\n if (semverRange) {\n const match = parsedFiles.filter((c) => satisfies(c.version, semverRange));\n return match.length > 0 ? match[0].path : undefined;\n }\n\n // Order by version\n const sorted = parsedFiles.sort((a, b) => {\n return a.version.localeCompare(b.version);\n });\n\n // latest version\n const match = sorted.length > 0 ? [sorted[sorted.length - 1]] : [];\n\n if (match.length > 0) {\n return match[0].path;\n }\n};\n\nexport const getFiles = async (pattern: string) => {\n try {\n const files = await glob(pattern, { ignore: 'node_modules/**' });\n return files;\n } catch (error) {\n throw new Error(`Error finding files: ${error}`);\n }\n};\n\nexport const searchFilesForId = async (files: string[], id: string, version?: string) => {\n const idRegex = new RegExp(`^id:\\\\s*(['\"]|>-)?\\\\s*${id}['\"]?\\\\s*$`, 'm');\n const versionRegex = new RegExp(`^version:\\\\s*['\"]?${version}['\"]?\\\\s*$`, 'm');\n\n const matches = await Promise.all(\n files.map(async (file) => {\n const content = await fs.readFile(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\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 await fs.mkdir(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 await fs.rm(tmpDirectory, { recursive: true });\n};\n","import { dirname, join } from 'path';\nimport { copyDir, findFileById, getFiles, searchFilesForId, versionExists } from './utils';\nimport matter from 'gray-matter';\nimport fs from 'node:fs/promises';\nimport { Message, Service } from '../types';\n\ntype Resource = Service | Message;\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`);\n const matchedFiles = await searchFilesForId(files, id);\n\n if (matchedFiles.length === 0) {\n throw new Error(`No event found with id: ${id}`);\n }\n\n // Event that is in the route of the project\n const file = matchedFiles[0];\n const sourceDirectory = dirname(file);\n const { data: { version = '0.0.1' } = {} } = matter.read(file);\n const targetDirectory = join(sourceDirectory, 'versioned', version);\n\n await fs.mkdir(targetDirectory, { recursive: true });\n\n // Copy the event to the versioned directory\n await copyDir(catalogDir, sourceDirectory, targetDirectory, (src) => {\n return !src.includes('versioned');\n });\n\n // Remove all the files in the root of the resource as they have now been versioned\n await fs.readdir(sourceDirectory).then(async (resourceFiles) => {\n await Promise.all(\n resourceFiles.map(async (file) => {\n if (file !== 'versioned') {\n await fs.rm(join(sourceDirectory, file), { recursive: true });\n }\n })\n );\n });\n};\n\nexport const writeResource = async (\n catalogDir: string,\n resource: Resource,\n options: { path: string; type: string } = { path: '', type: '' }\n) => {\n // Get the path\n const path = options.path || `/${resource.id}`;\n const exists = await versionExists(catalogDir, resource.id, resource.version);\n\n if (exists) {\n throw new Error(`Failed to write ${options.type} as the version ${resource.version} already exists`);\n }\n\n const { markdown, ...frontmatter } = resource;\n const document = matter.stringify(markdown.trim(), frontmatter);\n await fs.mkdir(join(catalogDir, path), { recursive: true });\n await fs.writeFile(join(catalogDir, path, 'index.md'), document);\n};\n\nexport const getResource = async (\n catalogDir: string,\n id: string,\n version?: string,\n options?: { type: string }\n): Promise<Resource | undefined> => {\n const file = await findFileById(catalogDir, id, version);\n if (!file) return;\n\n const { data, content } = matter.read(file);\n\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n};\n\nexport const rmResourceById = async (catalogDir: string, id: string, version?: string, options?: { type: string }) => {\n const files = await getFiles(`${catalogDir}/**/index.md`);\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 await Promise.all(matchedFiles.map((file) => fs.rm(file)));\n};\n\nexport const addFileToResource = async (\n catalogDir: string,\n id: string,\n file: { content: string; fileName: string },\n version?: string\n) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory to write file to');\n\n await fs.writeFile(join(dirname(pathToResource), file.fileName), file.content);\n};\n\nexport const getFileFromResource = async (catalogDir: string, id: string, file: { fileName: string }, version?: string) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory of resource');\n\n const exists = await fs\n .access(join(dirname(pathToResource), file.fileName))\n .then(() => true)\n .catch(() => false);\n if (!exists) throw new Error(`File ${file.fileName} does not exist in resource ${id} v(${version})`);\n\n return fs.readFile(join(dirname(pathToResource), file.fileName), 'utf-8');\n};\n","import fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { Command } from './types';\nimport { addFileToResource, getResource, rmResourceById, versionResource, writeResource } from './internal/resources';\nimport { findFileById } from './internal/utils';\n\n/**\n * Returns a command from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the command\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getCommand } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the command\n * const command = await getCommand('UpdateInventory');\n *\n * // Gets a version of the command\n * const command = await getCommand('UpdateInventory', '0.0.1');\n * ```\n */\nexport const getCommand =\n (directory: string) =>\n async (id: string, version?: string): Promise<Command> =>\n getResource(directory, id, version, { type: 'command' }) as Promise<Command>;\n\n/**\n * 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 */\nexport const writeCommand =\n (directory: string) =>\n async (command: Command, options: { path: string } = { path: '' }) =>\n writeResource(directory, { ...command }, { ...options, type: 'command' });\n\n/**\n * Delete a command at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmCommand } = utils('/path/to/eventcatalog');\n *\n * // removes a command at the given path (commands dir is appended to the given path)\n * // Removes the command at commands/UpdateInventory\n * await rmCommand('/UpdateInventory');\n * ```\n */\nexport const rmCommand = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a command by it's id.\n *\n * Optionally specify a version to delete a specific version of the command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmCommandById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest UpdateInventory command\n * await rmCommandById('UpdateInventory');\n *\n * // deletes a specific version of the UpdateInventory command\n * await rmCommandById('UpdateInventory', '0.0.1');\n * ```\n */\nexport const rmCommandById = (directory: string) => async (id: string, version?: string) =>\n rmResourceById(directory, id, version, { type: 'command' });\n\n/**\n * Version a command by it's id.\n *\n * Takes the latest command and moves it to a versioned directory.\n * All files with this command are also versioned (e.g /commands/UpdateInventory/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionCommand } = utils('/path/to/eventcatalog');\n *\n * // moves the latest UpdateInventory command to a versioned directory\n * // the version within that command is used as the version number.\n * await versionCommand('UpdateInventory');\n *\n * ```\n */\nexport const versionCommand = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Add a file to a command by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToCommand } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest UpdateInventory command\n * await addFileToCommand('UpdateInventory', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the UpdateInventory command\n * await addFileToCommand('UpdateInventory', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToCommand =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Add a schema to a command by it's id.\n *\n * Optionally specify a version to add a schema to a specific version of the command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addSchemaToCommand } = utils('/path/to/eventcatalog');\n *\n * // JSON schema example\n * const schema = {\n * \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n * \"type\": \"object\",\n * \"properties\": {\n * \"name\": {\n * \"type\": \"string\"\n * },\n * \"age\": {\n * \"type\": \"number\"\n * }\n * },\n * \"required\": [\"name\", \"age\"]\n * };\n *\n * // adds a schema to the latest UpdateInventory command\n * await addSchemaToCommand('UpdateInventory', { schema, fileName: 'schema.json' });\n *\n * // adds a file to a specific version of the UpdateInventory command\n * await addSchemaToCommand('UpdateInventory', { schema, fileName: 'schema.json' }, '0.0.1');\n *\n * ```\n */\nexport const addSchemaToCommand =\n (directory: string) => async (id: string, schema: { schema: string; fileName: string }, version?: string) => {\n await addFileToCommand(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);\n };\n\n/**\n * Check to see if the catalog has a version for the given command.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { commandHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await commandHasVersion('InventoryAdjusted', '0.0.1');\n * await commandHasVersion('InventoryAdjusted', 'latest');\n * await commandHasVersion('InventoryAdjusted', '0.0.x');*\n *\n * ```\n */\nexport const commandHasVersion = (directory: string) => async (id: string, version: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import type { Service, Specifications } from './types';\nimport fs from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport {\n addFileToResource,\n getFileFromResource,\n getResource,\n rmResourceById,\n versionResource,\n writeResource,\n} from './internal/resources';\nimport { findFileById } 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 * 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 { writeService } = utils('/path/to/eventcatalog');\n *\n * // Write a service\n * // Event 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 an event to the catalog but override the path\n * // Event 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 */\nexport const writeService =\n (directory: string) =>\n async (service: Service, options: { path: string } = { path: '' }) =>\n writeResource(directory, { ...service }, { ...options, type: 'service' });\n\n/**\n * Version a service by it's id.\n *\n * Takes the latest service and moves it to a versioned directory.\n * All files with this service are also versioned. (e.g /services/InventoryService/openapi.yml)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionService } = utils('/path/to/eventcatalog');\n *\n * // moves the latest InventoryService service to a versioned directory\n * // the version within that service is used as the version number.\n * await versionService('InventoryService');\n *\n * ```\n */\nexport const versionService = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Delete a service at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmService } = utils('/path/to/eventcatalog');\n *\n * // Removes the service at services/InventoryService\n * await rmService('/InventoryService');\n * ```\n */\nexport const rmService = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a service by it's id.\n *\n * Optionally specify a version to delete a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmServiceById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryService event\n * await rmServiceById('InventoryService');\n *\n * // deletes a specific version of the InventoryService event\n * await rmServiceById('InventoryService', '0.0.1');\n * ```\n */\nexport const rmServiceById = (directory: string) => async (id: string, version?: string) =>\n rmResourceById(directory, id, version, { type: 'service' });\n\n/**\n * Add a file to a service by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToService } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest InventoryService event\n * await addFileToService('InventoryService', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the InventoryService event\n * await addFileToService('InventoryService', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\n\nexport const addFileToService =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Returns specification files for a service\n *\n * Optionally specify a version to of the service\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getSpecificationFilesForService } = utils('/path/to/eventcatalog');\n *\n * // returns a list of specification files for a service\n * await getSpecificationFilesForService('InventoryService', '0.0.1');\n *\n * ```\n */\n\nexport const getSpecificationFilesForService = (directory: string) => async (id: string, version?: string) => {\n let service: Service = await getService(directory)(id, version);\n const filePathToService = await findFileById(directory, id, version);\n\n if (!filePathToService) throw new Error('Cannot find directory of service');\n\n let specs = [] as any;\n if (service.specifications) {\n const serviceSpecifications = service.specifications;\n const specificationFiles = Object.keys(serviceSpecifications);\n\n const getSpecs = specificationFiles.map(async (specFile) => {\n const fileName = serviceSpecifications[specFile as keyof Specifications];\n\n if (!fileName) {\n throw new Error(`Specification file name for ${specFile} is undefined`);\n }\n const rawFile = await getFileFromResource(directory, id, { fileName }, version);\n\n return { [specFile]: { content: rawFile, fileName: fileName, path: join(dirname(filePathToService), fileName) } };\n });\n\n specs = await Promise.all(getSpecs);\n }\n return specs;\n};\n\n/**\n * Add an event/command to a service by it's id.\n *\n * Optionally specify a version to add the event to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds an event to the service or command to the service\n * const { addEventToService, addCommandToService } = utils('/path/to/eventcatalog');\n *\n * // Adds a new event (InventoryUpdatedEvent) that the InventoryService will send\n * await addEventToService('InventoryService', 'sends', { event: 'InventoryUpdatedEvent', version: '2.0.0' });\n * * // Adds a new event (OrderComplete) that the InventoryService will receive\n * await addEventToService('InventoryService', 'receives', { event: 'OrderComplete', version: '1.0.0' });\n *\n * // Adds a new command (UpdateInventoryCommand) that the InventoryService will send\n * await addCommandToService('InventoryService', 'sends', { command: 'UpdateInventoryCommand', version: '2.0.0' });\n * // Adds a new command (VerifyInventory) that the InventoryService will receive\n * await addCommandToService('InventoryService', 'receives', { command: 'VerifyInventory', version: '1.0.0' });\n *\n * ```\n */\n\nexport const addMessageToService =\n (directory: string) => async (id: string, direction: string, event: { id: string; version: string }, version?: string) => {\n let service: Service = await getService(directory)(id, version);\n\n if (direction === 'sends') {\n if (service.sends === undefined) {\n service.sends = [];\n }\n // We first check if the event is already in the list\n for (let i = 0; i < service.sends.length; i++) {\n if (service.sends[i].id === event.id && service.sends[i].version === event.version) {\n return;\n }\n }\n service.sends.push({ id: event.id, version: event.version });\n } else if (direction === 'receives') {\n if (service.receives === undefined) {\n service.receives = [];\n }\n // We first check if the event is already in the list\n for (let i = 0; i < service.receives.length; i++) {\n if (service.receives[i].id === event.id && service.receives[i].version === event.version) {\n return;\n }\n }\n service.receives.push({ id: event.id, version: event.version });\n } else {\n throw new Error(`Direction ${direction} is invalid, only 'receives' and 'sends' are supported`);\n }\n\n await rmServiceById(directory)(id, version);\n await writeService(directory)(service);\n };\n\n/**\n * Check to see if the catalog has a version for the given service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { serviceHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await serviceHasVersion('InventoryService', '0.0.1');\n * await serviceHasVersion('InventoryService', 'latest');\n * await serviceHasVersion('InventoryService', '0.0.x');*\n *\n * ```\n */\nexport const serviceHasVersion = (directory: string) => async (id: string, version: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import type { Domain } from './types';\nimport fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { addFileToResource, getResource, rmResourceById, versionResource, writeResource } from './internal/resources';\nimport { findFileById } from './internal/utils';\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 * 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 * // Event 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 * // Event 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 */\nexport const writeDomain =\n (directory: string) =>\n async (domain: Domain, options: { path: string } = { path: '' }) =>\n writeResource(directory, { ...domain }, { ...options, type: 'domain' });\n\n/**\n * Version a domain by it's id.\n *\n * Takes the latest domain and moves it to a versioned directory.\n * All files with this domain are also versioned. (e.g /domains/Payment/openapi.yml)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionDomain } = utils('/path/to/eventcatalog');\n *\n * // moves the latest Payment domain to a versioned directory\n * // the version within that domain is used as the version number.\n * await versionDomain('Payment');\n *\n * ```\n */\nexport const versionDomain = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Delete a domain at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDomain } = utils('/path/to/eventcatalog');\n *\n * // Removes the domain at domains/Payment\n * await rmDomain('/Payment');\n * ```\n */\nexport const rmDomain = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a domain by it's id.\n *\n * Optionally specify a version to delete a specific version of the domain.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmDomainById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest Payment event\n * await rmDomainById('Payment');\n *\n * // deletes a specific version of the Payment event\n * await rmDomainById('Payment', '0.0.1');\n * ```\n */\nexport const rmDomainById = (directory: string) => async (id: string, version?: string) =>\n rmResourceById(directory, id, version, { type: 'domain' });\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 * 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 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 a service to the domain\n * const { addServiceToDomain } = utils('/path/to/eventcatalog');\n *\n * // Adds a service (Orders Service) to the domain (Orders)\n * await addServiceToDomain('Orders', { service: 'Order Service', version: '2.0.0' });\n * // Adds a service (Orders Service) to the domain (Orders) with a specific version\n * await addServiceToDomain('Orders', { service: 'Order Service', version: '2.0.0' }, '1.0.0');\n * ```\n */\n\nexport const addServiceToDomain =\n (directory: string) => async (id: string, service: { id: string; version: string }, version?: string) => {\n let domain: Domain = await getDomain(directory)(id, version);\n\n if (domain.services === undefined) {\n domain.services = [];\n }\n\n const eventExistsInList = domain.services.some((s) => s.id === service.id && s.version === service.version);\n\n if (eventExistsInList) {\n return;\n }\n\n // Add service to the list\n domain.services.push(service);\n\n await rmDomainById(directory)(id, version);\n await writeDomain(directory)(domain);\n };\n"],"mappings":"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","names":["join","fs","join","match","join","matter","fs","join","file","fs","join","fs","join","fs","join","fs","join","dirname","fs","join","dirname","fs","join","fs","join","join"]}
@@ -129,6 +129,23 @@ declare const addFileToService: (directory: string) => (id: string, file: {
129
129
  content: string;
130
130
  fileName: string;
131
131
  }, version?: string) => Promise<void>;
132
+ /**
133
+ * Returns specification files for a service
134
+ *
135
+ * Optionally specify a version to of the service
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * import utils from '@eventcatalog/utils';
140
+ *
141
+ * const { getSpecificationFilesForService } = utils('/path/to/eventcatalog');
142
+ *
143
+ * // returns a list of specification files for a service
144
+ * await getSpecificationFilesForService('InventoryService', '0.0.1');
145
+ *
146
+ * ```
147
+ */
148
+ declare const getSpecificationFilesForService: (directory: string) => (id: string, version?: string) => Promise<any>;
132
149
  /**
133
150
  * Add an event/command to a service by it's id.
134
151
  *
@@ -175,4 +192,4 @@ declare const addMessageToService: (directory: string) => (id: string, direction
175
192
  */
176
193
  declare const serviceHasVersion: (directory: string) => (id: string, version: string) => Promise<boolean>;
177
194
 
178
- export { addFileToService, addMessageToService, getService, rmService, rmServiceById, serviceHasVersion, versionService, writeService };
195
+ export { addFileToService, addMessageToService, getService, getSpecificationFilesForService, rmService, rmServiceById, serviceHasVersion, versionService, writeService };
@@ -129,6 +129,23 @@ declare const addFileToService: (directory: string) => (id: string, file: {
129
129
  content: string;
130
130
  fileName: string;
131
131
  }, version?: string) => Promise<void>;
132
+ /**
133
+ * Returns specification files for a service
134
+ *
135
+ * Optionally specify a version to of the service
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * import utils from '@eventcatalog/utils';
140
+ *
141
+ * const { getSpecificationFilesForService } = utils('/path/to/eventcatalog');
142
+ *
143
+ * // returns a list of specification files for a service
144
+ * await getSpecificationFilesForService('InventoryService', '0.0.1');
145
+ *
146
+ * ```
147
+ */
148
+ declare const getSpecificationFilesForService: (directory: string) => (id: string, version?: string) => Promise<any>;
132
149
  /**
133
150
  * Add an event/command to a service by it's id.
134
151
  *
@@ -175,4 +192,4 @@ declare const addMessageToService: (directory: string) => (id: string, direction
175
192
  */
176
193
  declare const serviceHasVersion: (directory: string) => (id: string, version: string) => Promise<boolean>;
177
194
 
178
- export { addFileToService, addMessageToService, getService, rmService, rmServiceById, serviceHasVersion, versionService, writeService };
195
+ export { addFileToService, addMessageToService, getService, getSpecificationFilesForService, rmService, rmServiceById, serviceHasVersion, versionService, writeService };
package/dist/services.js CHANGED
@@ -33,6 +33,7 @@ __export(services_exports, {
33
33
  addFileToService: () => addFileToService,
34
34
  addMessageToService: () => addMessageToService,
35
35
  getService: () => getService,
36
+ getSpecificationFilesForService: () => getSpecificationFilesForService,
36
37
  rmService: () => rmService,
37
38
  rmServiceById: () => rmServiceById,
38
39
  serviceHasVersion: () => serviceHasVersion,
@@ -91,7 +92,7 @@ var getFiles = async (pattern) => {
91
92
  }
92
93
  };
93
94
  var searchFilesForId = async (files, id, version) => {
94
- const idRegex = new RegExp(`^id:\\s*['"]?${id}['"]?\\s*$`, "m");
95
+ const idRegex = new RegExp(`^id:\\s*(['"]|>-)?\\s*${id}['"]?\\s*$`, "m");
95
96
  const versionRegex = new RegExp(`^version:\\s*['"]?${version}['"]?\\s*$`, "m");
96
97
  const matches = await Promise.all(
97
98
  files.map(async (file) => {
@@ -181,6 +182,13 @@ var addFileToResource = async (catalogDir, id, file, version) => {
181
182
  if (!pathToResource) throw new Error("Cannot find directory to write file to");
182
183
  await import_promises2.default.writeFile((0, import_path.join)((0, import_path.dirname)(pathToResource), file.fileName), file.content);
183
184
  };
185
+ var getFileFromResource = async (catalogDir, id, file, version) => {
186
+ const pathToResource = await findFileById(catalogDir, id, version);
187
+ if (!pathToResource) throw new Error("Cannot find directory of resource");
188
+ const exists = await import_promises2.default.access((0, import_path.join)((0, import_path.dirname)(pathToResource), file.fileName)).then(() => true).catch(() => false);
189
+ if (!exists) throw new Error(`File ${file.fileName} does not exist in resource ${id} v(${version})`);
190
+ return import_promises2.default.readFile((0, import_path.join)((0, import_path.dirname)(pathToResource), file.fileName), "utf-8");
191
+ };
184
192
 
185
193
  // src/services.ts
186
194
  var getService = (directory) => async (id, version) => getResource(directory, id, version, { type: "service" });
@@ -191,6 +199,26 @@ var rmService = (directory) => async (path) => {
191
199
  };
192
200
  var rmServiceById = (directory) => async (id, version) => rmResourceById(directory, id, version, { type: "service" });
193
201
  var addFileToService = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version);
202
+ var getSpecificationFilesForService = (directory) => async (id, version) => {
203
+ let service = await getService(directory)(id, version);
204
+ const filePathToService = await findFileById(directory, id, version);
205
+ if (!filePathToService) throw new Error("Cannot find directory of service");
206
+ let specs = [];
207
+ if (service.specifications) {
208
+ const serviceSpecifications = service.specifications;
209
+ const specificationFiles = Object.keys(serviceSpecifications);
210
+ const getSpecs = specificationFiles.map(async (specFile) => {
211
+ const fileName = serviceSpecifications[specFile];
212
+ if (!fileName) {
213
+ throw new Error(`Specification file name for ${specFile} is undefined`);
214
+ }
215
+ const rawFile = await getFileFromResource(directory, id, { fileName }, version);
216
+ return { [specFile]: { content: rawFile, fileName, path: (0, import_node_path2.join)((0, import_node_path2.dirname)(filePathToService), fileName) } };
217
+ });
218
+ specs = await Promise.all(getSpecs);
219
+ }
220
+ return specs;
221
+ };
194
222
  var addMessageToService = (directory) => async (id, direction, event, version) => {
195
223
  let service = await getService(directory)(id, version);
196
224
  if (direction === "sends") {
@@ -228,6 +256,7 @@ var serviceHasVersion = (directory) => async (id, version) => {
228
256
  addFileToService,
229
257
  addMessageToService,
230
258
  getService,
259
+ getSpecificationFilesForService,
231
260
  rmService,
232
261
  rmServiceById,
233
262
  serviceHasVersion,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/services.ts","../src/internal/resources.ts","../src/internal/utils.ts"],"sourcesContent":["import type { Service } from './types';\nimport fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { addFileToResource, getResource, rmResourceById, versionResource, writeResource } from './internal/resources';\nimport { findFileById } 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 * 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 { writeService } = utils('/path/to/eventcatalog');\n *\n * // Write a service\n * // Event 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 an event to the catalog but override the path\n * // Event 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 */\nexport const writeService =\n (directory: string) =>\n async (service: Service, options: { path: string } = { path: '' }) =>\n writeResource(directory, { ...service }, { ...options, type: 'service' });\n\n/**\n * Version a service by it's id.\n *\n * Takes the latest service and moves it to a versioned directory.\n * All files with this service are also versioned. (e.g /services/InventoryService/openapi.yml)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionService } = utils('/path/to/eventcatalog');\n *\n * // moves the latest InventoryService service to a versioned directory\n * // the version within that service is used as the version number.\n * await versionService('InventoryService');\n *\n * ```\n */\nexport const versionService = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Delete a service at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmService } = utils('/path/to/eventcatalog');\n *\n * // Removes the service at services/InventoryService\n * await rmService('/InventoryService');\n * ```\n */\nexport const rmService = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a service by it's id.\n *\n * Optionally specify a version to delete a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmServiceById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryService event\n * await rmServiceById('InventoryService');\n *\n * // deletes a specific version of the InventoryService event\n * await rmServiceById('InventoryService', '0.0.1');\n * ```\n */\nexport const rmServiceById = (directory: string) => async (id: string, version?: string) =>\n rmResourceById(directory, id, version, { type: 'service' });\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 * Add an event/command to a service by it's id.\n *\n * Optionally specify a version to add the event to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds an event to the service or command to the service\n * const { addEventToService, addCommandToService } = utils('/path/to/eventcatalog');\n *\n * // Adds a new event (InventoryUpdatedEvent) that the InventoryService will send\n * await addEventToService('InventoryService', 'sends', { event: 'InventoryUpdatedEvent', version: '2.0.0' });\n * * // Adds a new event (OrderComplete) that the InventoryService will receive\n * await addEventToService('InventoryService', 'receives', { event: 'OrderComplete', version: '1.0.0' });\n *\n * // Adds a new command (UpdateInventoryCommand) that the InventoryService will send\n * await addCommandToService('InventoryService', 'sends', { command: 'UpdateInventoryCommand', version: '2.0.0' });\n * // Adds a new command (VerifyInventory) that the InventoryService will receive\n * await addCommandToService('InventoryService', 'receives', { command: 'VerifyInventory', version: '1.0.0' });\n *\n * ```\n */\n\nexport const addMessageToService =\n (directory: string) => async (id: string, direction: string, event: { id: string; version: string }, version?: string) => {\n let service: Service = await getService(directory)(id, version);\n\n if (direction === 'sends') {\n if (service.sends === undefined) {\n service.sends = [];\n }\n // We first check if the event is already in the list\n for (let i = 0; i < service.sends.length; i++) {\n if (service.sends[i].id === event.id && service.sends[i].version === event.version) {\n return;\n }\n }\n service.sends.push({ id: event.id, version: event.version });\n } else if (direction === 'receives') {\n if (service.receives === undefined) {\n service.receives = [];\n }\n // We first check if the event is already in the list\n for (let i = 0; i < service.receives.length; i++) {\n if (service.receives[i].id === event.id && service.receives[i].version === event.version) {\n return;\n }\n }\n service.receives.push({ id: event.id, version: event.version });\n } else {\n throw new Error(`Direction ${direction} is invalid, only 'receives' and 'sends' are supported`);\n }\n\n await rmServiceById(directory)(id, version);\n await writeService(directory)(service);\n };\n\n/**\n * Check to see if the catalog has a version for the given service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { serviceHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await serviceHasVersion('InventoryService', '0.0.1');\n * await serviceHasVersion('InventoryService', 'latest');\n * await serviceHasVersion('InventoryService', '0.0.x');*\n *\n * ```\n */\nexport const serviceHasVersion = (directory: string) => async (id: string, version: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import { dirname, join } from 'path';\nimport { copyDir, findFileById, getFiles, searchFilesForId, versionExists } from './utils';\nimport matter from 'gray-matter';\nimport fs from 'node:fs/promises';\nimport { Message, Service } from '../types';\n\ntype Resource = Service | Message;\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`);\n const matchedFiles = await searchFilesForId(files, id);\n\n if (matchedFiles.length === 0) {\n throw new Error(`No event found with id: ${id}`);\n }\n\n // Event that is in the route of the project\n const file = matchedFiles[0];\n const sourceDirectory = dirname(file);\n const { data: { version = '0.0.1' } = {} } = matter.read(file);\n const targetDirectory = join(sourceDirectory, 'versioned', version);\n\n await fs.mkdir(targetDirectory, { recursive: true });\n\n // Copy the event to the versioned directory\n await copyDir(catalogDir, sourceDirectory, targetDirectory, (src) => {\n return !src.includes('versioned');\n });\n\n // Remove all the files in the root of the resource as they have now been versioned\n await fs.readdir(sourceDirectory).then(async (resourceFiles) => {\n await Promise.all(\n resourceFiles.map(async (file) => {\n if (file !== 'versioned') {\n await fs.rm(join(sourceDirectory, file), { recursive: true });\n }\n })\n );\n });\n};\n\nexport const writeResource = async (\n catalogDir: string,\n resource: Resource,\n options: { path: string; type: string } = { path: '', type: '' }\n) => {\n // Get the path\n const path = options.path || `/${resource.id}`;\n const exists = await versionExists(catalogDir, resource.id, resource.version);\n\n if (exists) {\n throw new Error(`Failed to write ${options.type} as the version ${resource.version} already exists`);\n }\n\n const { markdown, ...frontmatter } = resource;\n const document = matter.stringify(markdown.trim(), frontmatter);\n await fs.mkdir(join(catalogDir, path), { recursive: true });\n await fs.writeFile(join(catalogDir, path, 'index.md'), document);\n};\n\nexport const getResource = async (\n catalogDir: string,\n id: string,\n version?: string,\n options?: { type: string }\n): Promise<Resource | undefined> => {\n const file = await findFileById(catalogDir, id, version);\n if (!file) return;\n\n const { data, content } = matter.read(file);\n\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n};\n\nexport const rmResourceById = async (catalogDir: string, id: string, version?: string, options?: { type: string }) => {\n const files = await getFiles(`${catalogDir}/**/index.md`);\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 await Promise.all(matchedFiles.map((file) => fs.rm(file)));\n};\n\nexport const addFileToResource = async (\n catalogDir: string,\n id: string,\n file: { content: string; fileName: string },\n version?: string\n) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory to write file to');\n\n await fs.writeFile(join(dirname(pathToResource), file.fileName), file.content);\n};\n","import { glob } from 'glob';\nimport fs from 'node:fs/promises';\nimport { copy, CopyFilterAsync, CopyFilterSync } from 'fs-extra';\nimport { join } from 'node:path';\nimport matter from 'gray-matter';\nimport { satisfies, validRange } from 'semver';\n\n/**\n * Returns true if a given version of a resource id exists in the catalog\n */\nexport const versionExists = async (catalogDir: string, id: string, version: string) => {\n const files = await getFiles(`${catalogDir}/**/index.md`);\n const matchedFiles = (await searchFilesForId(files, id, version)) || [];\n return matchedFiles.length > 0;\n};\n\nexport const findFileById = async (catalogDir: string, id: string, version?: string): Promise<string | undefined> => {\n const files = await getFiles(`${catalogDir}/**/index.md`);\n const matchedFiles = (await searchFilesForId(files, id)) || [];\n const latestVersion = matchedFiles.find((path) => !path.includes('versioned'));\n\n // If no version is provided, return the latest version\n if (!version) {\n return latestVersion;\n }\n\n // map files into gray matter to get versions\n const parsedFiles = matchedFiles.map((path) => {\n const { data } = matter.read(path);\n return { ...data, path };\n }) as any[];\n\n const semverRange = validRange(version);\n\n if (semverRange) {\n const match = parsedFiles.filter((c) => satisfies(c.version, semverRange));\n return match.length > 0 ? match[0].path : undefined;\n }\n\n // Order by version\n const sorted = parsedFiles.sort((a, b) => {\n return a.version.localeCompare(b.version);\n });\n\n // latest version\n const match = sorted.length > 0 ? [sorted[sorted.length - 1]] : [];\n\n if (match.length > 0) {\n return match[0].path;\n }\n};\n\nexport const getFiles = async (pattern: string) => {\n try {\n const files = await glob(pattern, { ignore: 'node_modules/**' });\n return files;\n } catch (error) {\n throw new Error(`Error finding files: ${error}`);\n }\n};\n\nexport const searchFilesForId = async (files: string[], id: string, version?: string) => {\n const idRegex = new RegExp(`^id:\\\\s*['\"]?${id}['\"]?\\\\s*$`, 'm');\n const versionRegex = new RegExp(`^version:\\\\s*['\"]?${version}['\"]?\\\\s*$`, 'm');\n\n const matches = await Promise.all(\n files.map(async (file) => {\n const content = await fs.readFile(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\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 await fs.mkdir(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 await fs.rm(tmpDirectory, { recursive: true });\n};\n"],"mappings":"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","names":["import_promises","import_node_path","matter","match","fs","import_gray_matter","import_promises","matter","fs","file","fs"]}
1
+ {"version":3,"sources":["../src/services.ts","../src/internal/resources.ts","../src/internal/utils.ts"],"sourcesContent":["import type { Service, Specifications } from './types';\nimport fs from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport {\n addFileToResource,\n getFileFromResource,\n getResource,\n rmResourceById,\n versionResource,\n writeResource,\n} from './internal/resources';\nimport { findFileById } 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 * 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 { writeService } = utils('/path/to/eventcatalog');\n *\n * // Write a service\n * // Event 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 an event to the catalog but override the path\n * // Event 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 */\nexport const writeService =\n (directory: string) =>\n async (service: Service, options: { path: string } = { path: '' }) =>\n writeResource(directory, { ...service }, { ...options, type: 'service' });\n\n/**\n * Version a service by it's id.\n *\n * Takes the latest service and moves it to a versioned directory.\n * All files with this service are also versioned. (e.g /services/InventoryService/openapi.yml)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionService } = utils('/path/to/eventcatalog');\n *\n * // moves the latest InventoryService service to a versioned directory\n * // the version within that service is used as the version number.\n * await versionService('InventoryService');\n *\n * ```\n */\nexport const versionService = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Delete a service at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmService } = utils('/path/to/eventcatalog');\n *\n * // Removes the service at services/InventoryService\n * await rmService('/InventoryService');\n * ```\n */\nexport const rmService = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a service by it's id.\n *\n * Optionally specify a version to delete a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmServiceById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryService event\n * await rmServiceById('InventoryService');\n *\n * // deletes a specific version of the InventoryService event\n * await rmServiceById('InventoryService', '0.0.1');\n * ```\n */\nexport const rmServiceById = (directory: string) => async (id: string, version?: string) =>\n rmResourceById(directory, id, version, { type: 'service' });\n\n/**\n * Add a file to a service by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToService } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest InventoryService event\n * await addFileToService('InventoryService', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the InventoryService event\n * await addFileToService('InventoryService', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\n\nexport const addFileToService =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Returns specification files for a service\n *\n * Optionally specify a version to of the service\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getSpecificationFilesForService } = utils('/path/to/eventcatalog');\n *\n * // returns a list of specification files for a service\n * await getSpecificationFilesForService('InventoryService', '0.0.1');\n *\n * ```\n */\n\nexport const getSpecificationFilesForService = (directory: string) => async (id: string, version?: string) => {\n let service: Service = await getService(directory)(id, version);\n const filePathToService = await findFileById(directory, id, version);\n\n if (!filePathToService) throw new Error('Cannot find directory of service');\n\n let specs = [] as any;\n if (service.specifications) {\n const serviceSpecifications = service.specifications;\n const specificationFiles = Object.keys(serviceSpecifications);\n\n const getSpecs = specificationFiles.map(async (specFile) => {\n const fileName = serviceSpecifications[specFile as keyof Specifications];\n\n if (!fileName) {\n throw new Error(`Specification file name for ${specFile} is undefined`);\n }\n const rawFile = await getFileFromResource(directory, id, { fileName }, version);\n\n return { [specFile]: { content: rawFile, fileName: fileName, path: join(dirname(filePathToService), fileName) } };\n });\n\n specs = await Promise.all(getSpecs);\n }\n return specs;\n};\n\n/**\n * Add an event/command to a service by it's id.\n *\n * Optionally specify a version to add the event to a specific version of the service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * // Adds an event to the service or command to the service\n * const { addEventToService, addCommandToService } = utils('/path/to/eventcatalog');\n *\n * // Adds a new event (InventoryUpdatedEvent) that the InventoryService will send\n * await addEventToService('InventoryService', 'sends', { event: 'InventoryUpdatedEvent', version: '2.0.0' });\n * * // Adds a new event (OrderComplete) that the InventoryService will receive\n * await addEventToService('InventoryService', 'receives', { event: 'OrderComplete', version: '1.0.0' });\n *\n * // Adds a new command (UpdateInventoryCommand) that the InventoryService will send\n * await addCommandToService('InventoryService', 'sends', { command: 'UpdateInventoryCommand', version: '2.0.0' });\n * // Adds a new command (VerifyInventory) that the InventoryService will receive\n * await addCommandToService('InventoryService', 'receives', { command: 'VerifyInventory', version: '1.0.0' });\n *\n * ```\n */\n\nexport const addMessageToService =\n (directory: string) => async (id: string, direction: string, event: { id: string; version: string }, version?: string) => {\n let service: Service = await getService(directory)(id, version);\n\n if (direction === 'sends') {\n if (service.sends === undefined) {\n service.sends = [];\n }\n // We first check if the event is already in the list\n for (let i = 0; i < service.sends.length; i++) {\n if (service.sends[i].id === event.id && service.sends[i].version === event.version) {\n return;\n }\n }\n service.sends.push({ id: event.id, version: event.version });\n } else if (direction === 'receives') {\n if (service.receives === undefined) {\n service.receives = [];\n }\n // We first check if the event is already in the list\n for (let i = 0; i < service.receives.length; i++) {\n if (service.receives[i].id === event.id && service.receives[i].version === event.version) {\n return;\n }\n }\n service.receives.push({ id: event.id, version: event.version });\n } else {\n throw new Error(`Direction ${direction} is invalid, only 'receives' and 'sends' are supported`);\n }\n\n await rmServiceById(directory)(id, version);\n await writeService(directory)(service);\n };\n\n/**\n * Check to see if the catalog has a version for the given service.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { serviceHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await serviceHasVersion('InventoryService', '0.0.1');\n * await serviceHasVersion('InventoryService', 'latest');\n * await serviceHasVersion('InventoryService', '0.0.x');*\n *\n * ```\n */\nexport const serviceHasVersion = (directory: string) => async (id: string, version: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import { dirname, join } from 'path';\nimport { copyDir, findFileById, getFiles, searchFilesForId, versionExists } from './utils';\nimport matter from 'gray-matter';\nimport fs from 'node:fs/promises';\nimport { Message, Service } from '../types';\n\ntype Resource = Service | Message;\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`);\n const matchedFiles = await searchFilesForId(files, id);\n\n if (matchedFiles.length === 0) {\n throw new Error(`No event found with id: ${id}`);\n }\n\n // Event that is in the route of the project\n const file = matchedFiles[0];\n const sourceDirectory = dirname(file);\n const { data: { version = '0.0.1' } = {} } = matter.read(file);\n const targetDirectory = join(sourceDirectory, 'versioned', version);\n\n await fs.mkdir(targetDirectory, { recursive: true });\n\n // Copy the event to the versioned directory\n await copyDir(catalogDir, sourceDirectory, targetDirectory, (src) => {\n return !src.includes('versioned');\n });\n\n // Remove all the files in the root of the resource as they have now been versioned\n await fs.readdir(sourceDirectory).then(async (resourceFiles) => {\n await Promise.all(\n resourceFiles.map(async (file) => {\n if (file !== 'versioned') {\n await fs.rm(join(sourceDirectory, file), { recursive: true });\n }\n })\n );\n });\n};\n\nexport const writeResource = async (\n catalogDir: string,\n resource: Resource,\n options: { path: string; type: string } = { path: '', type: '' }\n) => {\n // Get the path\n const path = options.path || `/${resource.id}`;\n const exists = await versionExists(catalogDir, resource.id, resource.version);\n\n if (exists) {\n throw new Error(`Failed to write ${options.type} as the version ${resource.version} already exists`);\n }\n\n const { markdown, ...frontmatter } = resource;\n const document = matter.stringify(markdown.trim(), frontmatter);\n await fs.mkdir(join(catalogDir, path), { recursive: true });\n await fs.writeFile(join(catalogDir, path, 'index.md'), document);\n};\n\nexport const getResource = async (\n catalogDir: string,\n id: string,\n version?: string,\n options?: { type: string }\n): Promise<Resource | undefined> => {\n const file = await findFileById(catalogDir, id, version);\n if (!file) return;\n\n const { data, content } = matter.read(file);\n\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n};\n\nexport const rmResourceById = async (catalogDir: string, id: string, version?: string, options?: { type: string }) => {\n const files = await getFiles(`${catalogDir}/**/index.md`);\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 await Promise.all(matchedFiles.map((file) => fs.rm(file)));\n};\n\nexport const addFileToResource = async (\n catalogDir: string,\n id: string,\n file: { content: string; fileName: string },\n version?: string\n) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory to write file to');\n\n await fs.writeFile(join(dirname(pathToResource), file.fileName), file.content);\n};\n\nexport const getFileFromResource = async (catalogDir: string, id: string, file: { fileName: string }, version?: string) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory of resource');\n\n const exists = await fs\n .access(join(dirname(pathToResource), file.fileName))\n .then(() => true)\n .catch(() => false);\n if (!exists) throw new Error(`File ${file.fileName} does not exist in resource ${id} v(${version})`);\n\n return fs.readFile(join(dirname(pathToResource), file.fileName), 'utf-8');\n};\n","import { glob } from 'glob';\nimport fs from 'node:fs/promises';\nimport { copy, CopyFilterAsync, CopyFilterSync } from 'fs-extra';\nimport { join } from 'node:path';\nimport matter from 'gray-matter';\nimport { satisfies, validRange } from 'semver';\n\n/**\n * Returns true if a given version of a resource id exists in the catalog\n */\nexport const versionExists = async (catalogDir: string, id: string, version: string) => {\n const files = await getFiles(`${catalogDir}/**/index.md`);\n const matchedFiles = (await searchFilesForId(files, id, version)) || [];\n return matchedFiles.length > 0;\n};\n\nexport const findFileById = async (catalogDir: string, id: string, version?: string): Promise<string | undefined> => {\n const files = await getFiles(`${catalogDir}/**/index.md`);\n const matchedFiles = (await searchFilesForId(files, id)) || [];\n const latestVersion = matchedFiles.find((path) => !path.includes('versioned'));\n\n // If no version is provided, return the latest version\n if (!version) {\n return latestVersion;\n }\n\n // map files into gray matter to get versions\n const parsedFiles = matchedFiles.map((path) => {\n const { data } = matter.read(path);\n return { ...data, path };\n }) as any[];\n\n const semverRange = validRange(version);\n\n if (semverRange) {\n const match = parsedFiles.filter((c) => satisfies(c.version, semverRange));\n return match.length > 0 ? match[0].path : undefined;\n }\n\n // Order by version\n const sorted = parsedFiles.sort((a, b) => {\n return a.version.localeCompare(b.version);\n });\n\n // latest version\n const match = sorted.length > 0 ? [sorted[sorted.length - 1]] : [];\n\n if (match.length > 0) {\n return match[0].path;\n }\n};\n\nexport const getFiles = async (pattern: string) => {\n try {\n const files = await glob(pattern, { ignore: 'node_modules/**' });\n return files;\n } catch (error) {\n throw new Error(`Error finding files: ${error}`);\n }\n};\n\nexport const searchFilesForId = async (files: string[], id: string, version?: string) => {\n const idRegex = new RegExp(`^id:\\\\s*(['\"]|>-)?\\\\s*${id}['\"]?\\\\s*$`, 'm');\n const versionRegex = new RegExp(`^version:\\\\s*['\"]?${version}['\"]?\\\\s*$`, 'm');\n\n const matches = await Promise.all(\n files.map(async (file) => {\n const content = await fs.readFile(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\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 await fs.mkdir(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 await fs.rm(tmpDirectory, { recursive: true });\n};\n"],"mappings":"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","names":["import_promises","import_node_path","matter","match","fs","import_gray_matter","import_promises","matter","fs","file","fs"]}
package/dist/services.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/services.ts
2
2
  import fs3 from "node:fs/promises";
3
- import { join as join3 } from "node:path";
3
+ import { join as join3, dirname as dirname2 } from "node:path";
4
4
 
5
5
  // src/internal/resources.ts
6
6
  import { dirname, join as join2 } from "path";
@@ -50,7 +50,7 @@ var getFiles = async (pattern) => {
50
50
  }
51
51
  };
52
52
  var searchFilesForId = async (files, id, version) => {
53
- const idRegex = new RegExp(`^id:\\s*['"]?${id}['"]?\\s*$`, "m");
53
+ const idRegex = new RegExp(`^id:\\s*(['"]|>-)?\\s*${id}['"]?\\s*$`, "m");
54
54
  const versionRegex = new RegExp(`^version:\\s*['"]?${version}['"]?\\s*$`, "m");
55
55
  const matches = await Promise.all(
56
56
  files.map(async (file) => {
@@ -140,6 +140,13 @@ var addFileToResource = async (catalogDir, id, file, version) => {
140
140
  if (!pathToResource) throw new Error("Cannot find directory to write file to");
141
141
  await fs2.writeFile(join2(dirname(pathToResource), file.fileName), file.content);
142
142
  };
143
+ var getFileFromResource = async (catalogDir, id, file, version) => {
144
+ const pathToResource = await findFileById(catalogDir, id, version);
145
+ if (!pathToResource) throw new Error("Cannot find directory of resource");
146
+ const exists = await fs2.access(join2(dirname(pathToResource), file.fileName)).then(() => true).catch(() => false);
147
+ if (!exists) throw new Error(`File ${file.fileName} does not exist in resource ${id} v(${version})`);
148
+ return fs2.readFile(join2(dirname(pathToResource), file.fileName), "utf-8");
149
+ };
143
150
 
144
151
  // src/services.ts
145
152
  var getService = (directory) => async (id, version) => getResource(directory, id, version, { type: "service" });
@@ -150,6 +157,26 @@ var rmService = (directory) => async (path) => {
150
157
  };
151
158
  var rmServiceById = (directory) => async (id, version) => rmResourceById(directory, id, version, { type: "service" });
152
159
  var addFileToService = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version);
160
+ var getSpecificationFilesForService = (directory) => async (id, version) => {
161
+ let service = await getService(directory)(id, version);
162
+ const filePathToService = await findFileById(directory, id, version);
163
+ if (!filePathToService) throw new Error("Cannot find directory of service");
164
+ let specs = [];
165
+ if (service.specifications) {
166
+ const serviceSpecifications = service.specifications;
167
+ const specificationFiles = Object.keys(serviceSpecifications);
168
+ const getSpecs = specificationFiles.map(async (specFile) => {
169
+ const fileName = serviceSpecifications[specFile];
170
+ if (!fileName) {
171
+ throw new Error(`Specification file name for ${specFile} is undefined`);
172
+ }
173
+ const rawFile = await getFileFromResource(directory, id, { fileName }, version);
174
+ return { [specFile]: { content: rawFile, fileName, path: join3(dirname2(filePathToService), fileName) } };
175
+ });
176
+ specs = await Promise.all(getSpecs);
177
+ }
178
+ return specs;
179
+ };
153
180
  var addMessageToService = (directory) => async (id, direction, event, version) => {
154
181
  let service = await getService(directory)(id, version);
155
182
  if (direction === "sends") {
@@ -186,6 +213,7 @@ export {
186
213
  addFileToService,
187
214
  addMessageToService,
188
215
  getService,
216
+ getSpecificationFilesForService,
189
217
  rmService,
190
218
  rmServiceById,
191
219
  serviceHasVersion,