@eventcatalog/sdk 2.7.5 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/channels.js +18 -9
- package/dist/channels.js.map +1 -1
- package/dist/channels.mjs +11 -2
- package/dist/channels.mjs.map +1 -1
- package/dist/commands.js +14 -5
- package/dist/commands.js.map +1 -1
- package/dist/commands.mjs +11 -2
- package/dist/commands.mjs.map +1 -1
- package/dist/custom-docs.js +6 -5
- package/dist/custom-docs.js.map +1 -1
- package/dist/custom-docs.mjs +1 -0
- package/dist/custom-docs.mjs.map +1 -1
- package/dist/domains.js +17 -8
- package/dist/domains.js.map +1 -1
- package/dist/domains.mjs +11 -2
- package/dist/domains.mjs.map +1 -1
- package/dist/entities.js +13 -4
- package/dist/entities.js.map +1 -1
- package/dist/entities.mjs +11 -2
- package/dist/entities.mjs.map +1 -1
- package/dist/eventcatalog.js +172 -156
- package/dist/eventcatalog.js.map +1 -1
- package/dist/eventcatalog.mjs +23 -7
- package/dist/eventcatalog.mjs.map +1 -1
- package/dist/events.js +14 -5
- package/dist/events.js.map +1 -1
- package/dist/events.mjs +11 -2
- package/dist/events.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +172 -156
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +23 -7
- package/dist/index.mjs.map +1 -1
- package/dist/messages.js +4 -3
- package/dist/messages.js.map +1 -1
- package/dist/messages.mjs +1 -0
- package/dist/messages.mjs.map +1 -1
- package/dist/queries.js +14 -5
- package/dist/queries.js.map +1 -1
- package/dist/queries.mjs +11 -2
- package/dist/queries.mjs.map +1 -1
- package/dist/services.js +31 -15
- package/dist/services.js.map +1 -1
- package/dist/services.mjs +23 -7
- package/dist/services.mjs.map +1 -1
- package/dist/teams.js +9 -8
- package/dist/teams.js.map +1 -1
- package/dist/teams.mjs +1 -0
- package/dist/teams.mjs.map +1 -1
- package/dist/types.d.d.mts +9 -2
- package/dist/types.d.d.ts +9 -2
- package/dist/types.d.js.map +1 -1
- package/package.json +1 -1
package/dist/queries.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/queries.ts","../src/internal/utils.ts","../src/internal/resources.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { findFileById } from './internal/utils';\nimport type { Query } from './types';\nimport {\n addFileToResource,\n getResource,\n getResourcePath,\n getResources,\n rmResourceById,\n versionResource,\n writeResource,\n} from './internal/resources';\n\n/**\n * Returns a query from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the query\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getQuery } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the event\n * const event = await getQuery('GetOrder');\n *\n * // Gets a version of the event\n * const event = await getQuery('GetOrder', '0.0.1');\n *\n * // Gets the query with the schema attached\n * const event = await getQuery('GetOrder', '0.0.1', { attachSchema: true });\n * ```\n */\nexport const getQuery =\n (directory: string) =>\n async (id: string, version?: string, options?: { attachSchema?: boolean }): Promise<Query> =>\n getResource(directory, id, version, { type: 'query', ...options }) as Promise<Query>;\n\n/**\n * Write a query to EventCatalog.\n *\n * You can optionally override the path of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeQuery } = utils('/path/to/eventcatalog');\n *\n * // Write an event to the catalog\n * // Event would be written to queries/GetOrder\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * });\n *\n * // Write an event to the catalog but override the path\n * // Event would be written to queries/Inventory/GetOrder\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { path: \"/Orders/GetOrder\"});\n *\n * // Write a query to the catalog and override the existing content (if there is any)\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { override: true });\n *\n * // Write a query to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeQuery =\n (directory: string) =>\n async (\n query: Query,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n versionExistingContent: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...query }, { ...options, type: 'query' });\n\n/**\n * Returns all queries from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the queries.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getQueries } = utils('/path/to/eventcatalog');\n *\n * // Gets all queries (and versions) from the catalog\n * const queries = await getQueries();\n *\n * // Gets all queries (only latest version) from the catalog\n * const queries = await getQueries({ latestOnly: true });\n *\n * // Gets all queries with the schema attached\n * const queries = await getQueries({ attachSchema: true });\n * ```\n */\nexport const getQueries =\n (directory: string) =>\n async (options?: { latestOnly?: boolean; attachSchema?: boolean }): Promise<Query[]> =>\n getResources(directory, { type: 'queries', ...options }) as Promise<Query[]>;\n\n/**\n * Write a query to a service in EventCatalog.\n *\n * You can optionally override the path of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeQueryToService } = utils('/path/to/eventcatalog');\n *\n * // Write an event to a given service in the catalog\n * // Event would be written to services/Orders/queries/GetOrder\n * await writeQueryToService({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { id: 'Orders' });\n * ```\n */\nexport const writeQueryToService =\n (directory: string) =>\n async (\n query: Query,\n service: { id: string; version?: string },\n options: { path?: string; format?: 'md' | 'mdx'; override?: boolean } = { path: '', format: 'mdx', override: false }\n ) => {\n const resourcePath = await getResourcePath(directory, service.id, service.version);\n if (!resourcePath) {\n throw new Error('Service not found');\n }\n let pathForQuery =\n service.version && service.version !== 'latest'\n ? `${resourcePath.directory}/versioned/${service.version}/queries`\n : `${resourcePath.directory}/queries`;\n pathForQuery = join(pathForQuery, query.id);\n await writeResource(directory, { ...query }, { ...options, path: pathForQuery, type: 'query' });\n };\n\n/**\n * Delete a query at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmQuery } = utils('/path/to/eventcatalog');\n *\n * // removes an query at the given path (queries dir is appended to the given path)\n * // Removes the query at queries/GetOrders\n * await rmQuery('/GetOrders');\n * ```\n */\nexport const rmQuery = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a query by it's id.\n *\n * Optionally specify a version to delete a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmQueryById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryAdjusted query\n * await rmQueryById('GetOrder');\n *\n * // deletes a specific version of the GetOrder query\n * await rmQueryById('GetOrder', '0.0.1');\n * ```\n */\nexport const rmQueryById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) => {\n await rmResourceById(directory, id, version, { type: 'query', persistFiles });\n};\n\n/**\n * Version a query by it's id.\n *\n * Takes the latest query and moves it to a versioned directory.\n * All files with this query are also versioned (e.g /queries/GetOrder/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionQuery } = utils('/path/to/eventcatalog');\n *\n * // moves the latest GetOrder query to a versioned directory\n * // the version within that query is used as the version number.\n * await versionQuery('GetOrder');\n *\n * ```\n */\nexport const versionQuery = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Add a file to a query by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToQuery } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest GetOrder query\n * await addFileToQuery('GetOrder', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the GetOrder query\n * await addFileToQuery('GetOrder', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToQuery =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Add a schema to a query by it's id.\n *\n * Optionally specify a version to add a schema to a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addSchemaToQuery } = utils('/path/to/eventcatalog');\n *\n * // JSON schema example\n * const schema = {\n * \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n * \"type\": \"object\",\n * \"properties\": {\n * \"name\": {\n * \"type\": \"string\"\n * },\n * \"age\": {\n * \"type\": \"number\"\n * }\n * },\n * \"required\": [\"name\", \"age\"]\n * };\n *\n * // adds a schema to the latest GetOrder query\n * await addSchemaToQuery('GetOrder', { schema, fileName: 'schema.json' });\n *\n * // adds a file to a specific version of the GetOrder query\n * await addSchemaToQuery('GetOrder', { schema, fileName: 'schema.json' }, '0.0.1');\n *\n * ```\n */\nexport const addSchemaToQuery =\n (directory: string) => async (id: string, schema: { schema: string; fileName: string }, version?: string) => {\n await addFileToQuery(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);\n };\n\n/**\n * Check to see if the catalog has a version for the given query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { queryHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await queryHasVersion('GetOrder', '0.0.1');\n * await queryHasVersion('GetOrder', 'latest');\n * await queryHasVersion('GetOrder', '0.0.x');*\n *\n * ```\n */\nexport const queryHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import { globSync } from 'glob';\nimport fsSync from 'node:fs';\nimport { copy, CopyFilterAsync, CopyFilterSync } from 'fs-extra';\nimport { join, dirname, normalize, sep as pathSeparator, resolve, basename, relative } from 'node:path';\nimport matter from 'gray-matter';\nimport { satisfies, validRange, valid } from 'semver';\n\n/**\n * Returns true if a given version of a resource id exists in the catalog\n */\nexport const versionExists = async (catalogDir: string, id: string, version: string) => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n const matchedFiles = (await searchFilesForId(files, id, version)) || [];\n return matchedFiles.length > 0;\n};\n\nexport const findFileById = async (catalogDir: string, id: string, version?: string): Promise<string | undefined> => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n\n const matchedFiles = (await searchFilesForId(files, id)) || [];\n const latestVersion = matchedFiles.find((path) => !path.includes('versioned'));\n\n // If no version is provided, return the latest version\n if (!version) {\n return latestVersion;\n }\n\n // map files into gray matter to get versions\n const parsedFiles = matchedFiles.map((path) => {\n const { data } = matter.read(path);\n return { ...data, path };\n }) as any[];\n\n const semverRange = validRange(version);\n\n if (semverRange && valid(version)) {\n const match = parsedFiles.filter((c) => satisfies(c.version, semverRange));\n return match.length > 0 ? match[0].path : undefined;\n }\n\n // Order by version\n const sorted = parsedFiles.sort((a, b) => {\n return a.version.localeCompare(b.version);\n });\n\n // latest version\n const match = sorted.length > 0 ? [sorted[sorted.length - 1]] : [];\n\n if (match.length > 0) {\n return match[0].path;\n }\n};\n\nexport const getFiles = async (pattern: string, ignore: string | string[] = '') => {\n try {\n // 1. Normalize the input pattern to handle mixed separators potentially\n const normalizedInputPattern = normalize(pattern);\n\n // 2. Determine the absolute base directory (cwd for glob)\n // Resolve ensures it's absolute. Handles cases with/without globstar.\n const absoluteBaseDir = resolve(\n normalizedInputPattern.includes('**') ? normalizedInputPattern.split('**')[0] : dirname(normalizedInputPattern)\n );\n\n // 3. Determine the pattern part relative to the absolute base directory\n // We extract the part of the normalized pattern that comes *after* the absoluteBaseDir\n let relativePattern = relative(absoluteBaseDir, normalizedInputPattern);\n\n // On Windows, relative() might return empty string if paths are identical,\n // or might need normalization if the original pattern didn't have `**`\n // Example: pattern = 'dir/file.md', absoluteBaseDir='.../dir', normalized='...\\dir\\file.md'\n // relative() -> 'file.md'\n // Example: pattern = 'dir/**/file.md', absoluteBaseDir='.../dir', normalized='...\\dir\\**\\file.md'\n // relative() -> '**\\file.md'\n // Convert separators in the relative pattern to forward slashes for glob\n relativePattern = relativePattern.replace(/\\\\/g, '/');\n\n const ignoreList = Array.isArray(ignore) ? ignore : [ignore];\n\n const files = globSync(relativePattern, {\n cwd: absoluteBaseDir,\n ignore: ['node_modules/**', ...ignoreList],\n absolute: true,\n nodir: true,\n });\n\n // 5. Normalize results for consistency before returning\n return files.map(normalize);\n } catch (error: any) {\n // Add more diagnostic info to the error\n const absoluteBaseDirForError = resolve(\n normalize(pattern).includes('**') ? normalize(pattern).split('**')[0] : dirname(normalize(pattern))\n );\n const relativePatternForError = relative(absoluteBaseDirForError, normalize(pattern)).replace(/\\\\/g, '/');\n throw new Error(\n `Error finding files for pattern \"${pattern}\" (using cwd: \"${absoluteBaseDirForError}\", globPattern: \"${relativePatternForError}\"): ${error.message}`\n );\n }\n};\n\nexport const readMdxFile = async (path: string) => {\n const { data } = matter.read(path);\n const { markdown, ...frontmatter } = data;\n return { ...frontmatter, markdown };\n};\n\nexport const searchFilesForId = async (files: string[], id: string, version?: string) => {\n // Escape the id to avoid regex issues\n const escapedId = id.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const idRegex = new RegExp(`^id:\\\\s*(['\"]|>-)?\\\\s*${escapedId}['\"]?\\\\s*$`, 'm');\n\n const versionRegex = new RegExp(`^version:\\\\s*['\"]?${version}['\"]?\\\\s*$`, 'm');\n\n const matches = files.map((file) => {\n const content = fsSync.readFileSync(file, 'utf-8');\n const hasIdMatch = content.match(idRegex);\n\n // Check version if provided\n if (version && !content.match(versionRegex)) {\n return undefined;\n }\n\n if (hasIdMatch) {\n return file;\n }\n });\n\n return matches.filter(Boolean).filter((file) => file !== undefined);\n};\n\n/**\n * Function to copy a directory from source to target, uses a tmp directory\n * @param catalogDir\n * @param source\n * @param target\n * @param filter\n */\nexport const copyDir = async (catalogDir: string, source: string, target: string, filter?: CopyFilterAsync | CopyFilterSync) => {\n const tmpDirectory = join(catalogDir, 'tmp');\n fsSync.mkdirSync(tmpDirectory, { recursive: true });\n\n // Copy everything over\n await copy(source, tmpDirectory, {\n overwrite: true,\n filter,\n });\n\n await copy(tmpDirectory, target, {\n overwrite: true,\n filter,\n });\n\n // Remove the tmp directory\n fsSync.rmSync(tmpDirectory, { recursive: true });\n};\n\n// Makes sure values in sends/recieves are unique\nexport const uniqueVersions = (messages: { id: string; version: string }[]): { id: string; version: string }[] => {\n const uniqueSet = new Set();\n\n return messages.filter((message) => {\n const key = `${message.id}-${message.version}`;\n if (!uniqueSet.has(key)) {\n uniqueSet.add(key);\n return true;\n }\n return false;\n });\n};\n","import { dirname, join } from 'path';\nimport { copyDir, findFileById, getFiles, searchFilesForId, versionExists } from './utils';\nimport matter from 'gray-matter';\nimport fs from 'node:fs/promises';\nimport fsSync from 'node:fs';\nimport { Message, Service, CustomDoc } from '../types';\nimport { satisfies } from 'semver';\nimport { lock, unlock } from 'proper-lockfile';\n\ntype Resource = Service | Message | CustomDoc;\n\nexport const versionResource = async (catalogDir: string, id: string) => {\n // Find all the events in the directory\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n const matchedFiles = await searchFilesForId(files, id);\n\n if (matchedFiles.length === 0) {\n throw new Error(`No resource found with id: ${id}`);\n }\n\n // Event that is in the route of the project\n const file = matchedFiles[0];\n const sourceDirectory = dirname(file);\n const { data: { version = '0.0.1' } = {} } = matter.read(file);\n const targetDirectory = getVersionedDirectory(sourceDirectory, version);\n\n fsSync.mkdirSync(targetDirectory, { recursive: true });\n\n // Copy the event to the versioned directory\n await copyDir(catalogDir, sourceDirectory, targetDirectory, (src) => {\n return !src.includes('versioned');\n });\n\n // Remove all the files in the root of the resource as they have now been versioned\n await fs.readdir(sourceDirectory).then(async (resourceFiles) => {\n await Promise.all(\n resourceFiles.map(async (file) => {\n if (file !== 'versioned') {\n fsSync.rmSync(join(sourceDirectory, file), { recursive: true });\n }\n })\n );\n });\n};\n\nexport const writeResource = async (\n catalogDir: string,\n resource: Resource,\n options: { path?: string; type: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n type: '',\n override: false,\n versionExistingContent: false,\n format: 'mdx',\n }\n) => {\n const path = options.path || `/${resource.id}`;\n const fullPath = join(catalogDir, path);\n const format = options.format || 'mdx';\n\n // Create directory if it doesn't exist\n fsSync.mkdirSync(fullPath, { recursive: true });\n\n // Create or get lock file path\n const lockPath = join(fullPath, `index.${format}`);\n\n // Ensure the file exists before attempting to lock it\n if (!fsSync.existsSync(lockPath)) {\n fsSync.writeFileSync(lockPath, '');\n }\n\n try {\n // Acquire lock with retry\n await lock(lockPath, {\n retries: 5,\n stale: 10000, // 10 seconds\n });\n\n const exists = await versionExists(catalogDir, resource.id, resource.version);\n\n if (exists && !options.override) {\n throw new Error(`Failed to write ${resource.id} (${options.type}) as the version ${resource.version} already exists`);\n }\n\n const { markdown, ...frontmatter } = resource;\n\n if (options.versionExistingContent && !exists) {\n const currentResource = await getResource(catalogDir, resource.id);\n\n if (currentResource) {\n if (satisfies(resource.version, `>${currentResource.version}`)) {\n await versionResource(catalogDir, resource.id);\n } else {\n throw new Error(`New version ${resource.version} is not greater than current version ${currentResource.version}`);\n }\n }\n }\n\n const document = matter.stringify(markdown.trim(), frontmatter);\n fsSync.writeFileSync(lockPath, document);\n } finally {\n // Always release the lock\n await unlock(lockPath).catch(() => {});\n }\n};\n\nexport const getResource = async (\n catalogDir: string,\n id?: string,\n version?: string,\n options?: { type: string; attachSchema?: boolean },\n filePath?: string\n): Promise<Resource | undefined> => {\n const attachSchema = options?.attachSchema || false;\n const file = filePath || (id ? await findFileById(catalogDir, id, version) : undefined);\n if (!file || !fsSync.existsSync(file)) return;\n\n const { data, content } = matter.read(file);\n\n if (attachSchema && data?.schemaPath) {\n const resourceDirectory = dirname(file);\n const pathToSchema = join(resourceDirectory, data.schemaPath);\n if (fsSync.existsSync(pathToSchema)) {\n const schema = fsSync.readFileSync(pathToSchema, 'utf8');\n // Try to parse the schema\n try {\n data.schema = JSON.parse(schema);\n } catch (error) {\n data.schema = schema;\n }\n }\n }\n\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n};\n\nexport const getResourcePath = async (catalogDir: string, id: string, version?: string) => {\n const file = await findFileById(catalogDir, id, version);\n if (!file) return;\n\n return {\n fullPath: file,\n relativePath: file.replace(catalogDir, ''),\n directory: dirname(file.replace(catalogDir, '')),\n };\n};\n\nexport const toResource = async (catalogDir: string, rawContents: string) => {\n const { data, content } = matter(rawContents);\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n};\n\nexport const getResources = async (\n catalogDir: string,\n {\n type,\n latestOnly = false,\n ignore = [],\n pattern = '',\n attachSchema = false,\n }: { type: string; pattern?: string; latestOnly?: boolean; ignore?: string[]; attachSchema?: boolean }\n): Promise<Resource[] | undefined> => {\n const ignoreList = latestOnly ? `**/versioned/**` : '';\n const filePattern = pattern || `${catalogDir}/**/${type}/**/index.{md,mdx}`;\n const files = await getFiles(filePattern, [ignoreList, ...ignore]);\n\n if (files.length === 0) return;\n\n return files.map((file) => {\n const { data, content } = matter.read(file);\n\n // Attach the schema if the attachSchema option is set to true\n if (attachSchema && data?.schemaPath) {\n const resourceDirectory = dirname(file);\n const pathToSchema = join(resourceDirectory, data.schemaPath);\n if (fsSync.existsSync(pathToSchema)) {\n const schema = fsSync.readFileSync(pathToSchema, 'utf8');\n // Try to parse the schema\n try {\n data.schema = JSON.parse(schema);\n } catch (error) {\n data.schema = schema;\n }\n }\n }\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n });\n};\n\nexport const rmResourceById = async (\n catalogDir: string,\n id: string,\n version?: string,\n options?: { type: string; persistFiles?: boolean }\n) => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n\n const matchedFiles = await searchFilesForId(files, id, version);\n\n if (matchedFiles.length === 0) {\n throw new Error(`No ${options?.type || 'resource'} found with id: ${id}`);\n }\n\n if (options?.persistFiles) {\n await Promise.all(\n matchedFiles.map(async (file) => {\n await fs.rm(file, { recursive: true });\n // Verify file is actually removed\n await waitForFileRemoval(file);\n })\n );\n } else {\n await Promise.all(\n matchedFiles.map(async (file) => {\n const directory = dirname(file);\n await fs.rm(directory, { recursive: true, force: true });\n // Verify directory is actually removed\n await waitForFileRemoval(directory);\n })\n );\n }\n};\n\n// Helper function to ensure file/directory is completely removed\nconst waitForFileRemoval = async (path: string, maxRetries: number = 50, delay: number = 10): Promise<void> => {\n for (let i = 0; i < maxRetries; i++) {\n try {\n await fs.access(path);\n // If access succeeds, file still exists, wait and retry\n await new Promise((resolve) => setTimeout(resolve, delay));\n } catch (error) {\n // If access fails, file is removed\n return;\n }\n }\n // If we reach here, file still exists after all retries\n throw new Error(`File/directory ${path} was not removed after ${maxRetries} attempts`);\n};\n\nexport const addFileToResource = async (\n catalogDir: string,\n id: string,\n file: { content: string; fileName: string },\n version?: string\n) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory to write file to');\n\n let fileContent = file.content.trim();\n\n try {\n const json = JSON.parse(fileContent);\n fileContent = JSON.stringify(json, null, 2);\n } catch (error) {\n // Just silently fail if the file is not valid JSON\n // Write it as it is\n }\n\n fsSync.writeFileSync(join(dirname(pathToResource), file.fileName), fileContent);\n};\n\nexport const getFileFromResource = async (catalogDir: string, id: string, file: { fileName: string }, version?: string) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory of resource');\n\n const exists = await fs\n .access(join(dirname(pathToResource), file.fileName))\n .then(() => true)\n .catch(() => false);\n if (!exists) throw new Error(`File ${file.fileName} does not exist in resource ${id} v(${version})`);\n\n return fsSync.readFileSync(join(dirname(pathToResource), file.fileName), 'utf-8');\n};\nexport const getVersionedDirectory = (sourceDirectory: string, version: any): string => {\n return join(sourceDirectory, 'versioned', version);\n};\n\nexport const isLatestVersion = async (catalogDir: string, id: string, version?: string) => {\n const resource = await getResource(catalogDir, id, version);\n if (!resource) return false;\n\n const pathToResource = await getResourcePath(catalogDir, id, version);\n\n return !pathToResource?.relativePath.replace(/\\\\/g, '/').includes('/versioned/');\n};\n"],"mappings":"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","names":["import_promises","import_node_path","matter","match","fsSync","import_gray_matter","import_node_fs","import_semver","matter","fsSync","fs","file","matter","fsSync","fs","resolve","fs"]}
|
|
1
|
+
{"version":3,"sources":["../src/queries.ts","../src/internal/utils.ts","../src/internal/resources.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { findFileById } from './internal/utils';\nimport type { Query } from './types';\nimport {\n addFileToResource,\n getResource,\n getResourcePath,\n getResources,\n rmResourceById,\n versionResource,\n writeResource,\n} from './internal/resources';\n\n/**\n * Returns a query from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the query\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getQuery } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the event\n * const event = await getQuery('GetOrder');\n *\n * // Gets a version of the event\n * const event = await getQuery('GetOrder', '0.0.1');\n *\n * // Gets the query with the schema attached\n * const event = await getQuery('GetOrder', '0.0.1', { attachSchema: true });\n * ```\n */\nexport const getQuery =\n (directory: string) =>\n async (id: string, version?: string, options?: { attachSchema?: boolean }): Promise<Query> =>\n getResource(directory, id, version, { type: 'query', ...options }) as Promise<Query>;\n\n/**\n * Write a query to EventCatalog.\n *\n * You can optionally override the path of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeQuery } = utils('/path/to/eventcatalog');\n *\n * // Write an event to the catalog\n * // Event would be written to queries/GetOrder\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * });\n *\n * // Write an event to the catalog but override the path\n * // Event would be written to queries/Inventory/GetOrder\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { path: \"/Orders/GetOrder\"});\n *\n * // Write a query to the catalog and override the existing content (if there is any)\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { override: true });\n *\n * // Write a query to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeQuery =\n (directory: string) =>\n async (\n query: Query,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n versionExistingContent: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...query }, { ...options, type: 'query' });\n\n/**\n * Returns all queries from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the queries.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getQueries } = utils('/path/to/eventcatalog');\n *\n * // Gets all queries (and versions) from the catalog\n * const queries = await getQueries();\n *\n * // Gets all queries (only latest version) from the catalog\n * const queries = await getQueries({ latestOnly: true });\n *\n * // Gets all queries with the schema attached\n * const queries = await getQueries({ attachSchema: true });\n * ```\n */\nexport const getQueries =\n (directory: string) =>\n async (options?: { latestOnly?: boolean; attachSchema?: boolean }): Promise<Query[]> =>\n getResources(directory, { type: 'queries', ...options }) as Promise<Query[]>;\n\n/**\n * Write a query to a service in EventCatalog.\n *\n * You can optionally override the path of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeQueryToService } = utils('/path/to/eventcatalog');\n *\n * // Write an event to a given service in the catalog\n * // Event would be written to services/Orders/queries/GetOrder\n * await writeQueryToService({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { id: 'Orders' });\n * ```\n */\nexport const writeQueryToService =\n (directory: string) =>\n async (\n query: Query,\n service: { id: string; version?: string },\n options: { path?: string; format?: 'md' | 'mdx'; override?: boolean } = { path: '', format: 'mdx', override: false }\n ) => {\n const resourcePath = await getResourcePath(directory, service.id, service.version);\n if (!resourcePath) {\n throw new Error('Service not found');\n }\n let pathForQuery =\n service.version && service.version !== 'latest'\n ? `${resourcePath.directory}/versioned/${service.version}/queries`\n : `${resourcePath.directory}/queries`;\n pathForQuery = join(pathForQuery, query.id);\n await writeResource(directory, { ...query }, { ...options, path: pathForQuery, type: 'query' });\n };\n\n/**\n * Delete a query at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmQuery } = utils('/path/to/eventcatalog');\n *\n * // removes an query at the given path (queries dir is appended to the given path)\n * // Removes the query at queries/GetOrders\n * await rmQuery('/GetOrders');\n * ```\n */\nexport const rmQuery = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a query by it's id.\n *\n * Optionally specify a version to delete a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmQueryById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryAdjusted query\n * await rmQueryById('GetOrder');\n *\n * // deletes a specific version of the GetOrder query\n * await rmQueryById('GetOrder', '0.0.1');\n * ```\n */\nexport const rmQueryById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) => {\n await rmResourceById(directory, id, version, { type: 'query', persistFiles });\n};\n\n/**\n * Version a query by it's id.\n *\n * Takes the latest query and moves it to a versioned directory.\n * All files with this query are also versioned (e.g /queries/GetOrder/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionQuery } = utils('/path/to/eventcatalog');\n *\n * // moves the latest GetOrder query to a versioned directory\n * // the version within that query is used as the version number.\n * await versionQuery('GetOrder');\n *\n * ```\n */\nexport const versionQuery = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Add a file to a query by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToQuery } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest GetOrder query\n * await addFileToQuery('GetOrder', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the GetOrder query\n * await addFileToQuery('GetOrder', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToQuery =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Add a schema to a query by it's id.\n *\n * Optionally specify a version to add a schema to a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addSchemaToQuery } = utils('/path/to/eventcatalog');\n *\n * // JSON schema example\n * const schema = {\n * \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n * \"type\": \"object\",\n * \"properties\": {\n * \"name\": {\n * \"type\": \"string\"\n * },\n * \"age\": {\n * \"type\": \"number\"\n * }\n * },\n * \"required\": [\"name\", \"age\"]\n * };\n *\n * // adds a schema to the latest GetOrder query\n * await addSchemaToQuery('GetOrder', { schema, fileName: 'schema.json' });\n *\n * // adds a file to a specific version of the GetOrder query\n * await addSchemaToQuery('GetOrder', { schema, fileName: 'schema.json' }, '0.0.1');\n *\n * ```\n */\nexport const addSchemaToQuery =\n (directory: string) => async (id: string, schema: { schema: string; fileName: string }, version?: string) => {\n await addFileToQuery(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);\n };\n\n/**\n * Check to see if the catalog has a version for the given query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { queryHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await queryHasVersion('GetOrder', '0.0.1');\n * await queryHasVersion('GetOrder', 'latest');\n * await queryHasVersion('GetOrder', '0.0.x');*\n *\n * ```\n */\nexport const queryHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import { globSync } from 'glob';\nimport fsSync from 'node:fs';\nimport { copy, CopyFilterAsync, CopyFilterSync } from 'fs-extra';\nimport { join, dirname, normalize, sep as pathSeparator, resolve, basename, relative } from 'node:path';\nimport matter from 'gray-matter';\nimport { satisfies, validRange, valid } from 'semver';\n\n/**\n * Returns true if a given version of a resource id exists in the catalog\n */\nexport const versionExists = async (catalogDir: string, id: string, version: string) => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n const matchedFiles = (await searchFilesForId(files, id, version)) || [];\n return matchedFiles.length > 0;\n};\n\nexport const findFileById = async (catalogDir: string, id: string, version?: string): Promise<string | undefined> => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n\n const matchedFiles = (await searchFilesForId(files, id)) || [];\n const latestVersion = matchedFiles.find((path) => !path.includes('versioned'));\n\n // If no version is provided, return the latest version\n if (!version) {\n return latestVersion;\n }\n\n // map files into gray matter to get versions\n const parsedFiles = matchedFiles.map((path) => {\n const { data } = matter.read(path);\n return { ...data, path };\n }) as any[];\n\n const semverRange = validRange(version);\n\n if (semverRange && valid(version)) {\n const match = parsedFiles.filter((c) => satisfies(c.version, semverRange));\n return match.length > 0 ? match[0].path : undefined;\n }\n\n // Order by version\n const sorted = parsedFiles.sort((a, b) => {\n return a.version.localeCompare(b.version);\n });\n\n // latest version\n const match = sorted.length > 0 ? [sorted[sorted.length - 1]] : [];\n\n if (match.length > 0) {\n return match[0].path;\n }\n};\n\nexport const getFiles = async (pattern: string, ignore: string | string[] = '') => {\n try {\n // 1. Normalize the input pattern to handle mixed separators potentially\n const normalizedInputPattern = normalize(pattern);\n\n // 2. Determine the absolute base directory (cwd for glob)\n // Resolve ensures it's absolute. Handles cases with/without globstar.\n const absoluteBaseDir = resolve(\n normalizedInputPattern.includes('**') ? normalizedInputPattern.split('**')[0] : dirname(normalizedInputPattern)\n );\n\n // 3. Determine the pattern part relative to the absolute base directory\n // We extract the part of the normalized pattern that comes *after* the absoluteBaseDir\n let relativePattern = relative(absoluteBaseDir, normalizedInputPattern);\n\n // On Windows, relative() might return empty string if paths are identical,\n // or might need normalization if the original pattern didn't have `**`\n // Example: pattern = 'dir/file.md', absoluteBaseDir='.../dir', normalized='...\\dir\\file.md'\n // relative() -> 'file.md'\n // Example: pattern = 'dir/**/file.md', absoluteBaseDir='.../dir', normalized='...\\dir\\**\\file.md'\n // relative() -> '**\\file.md'\n // Convert separators in the relative pattern to forward slashes for glob\n relativePattern = relativePattern.replace(/\\\\/g, '/');\n\n const ignoreList = Array.isArray(ignore) ? ignore : [ignore];\n\n const files = globSync(relativePattern, {\n cwd: absoluteBaseDir,\n ignore: ['node_modules/**', ...ignoreList],\n absolute: true,\n nodir: true,\n });\n\n // 5. Normalize results for consistency before returning\n return files.map(normalize);\n } catch (error: any) {\n // Add more diagnostic info to the error\n const absoluteBaseDirForError = resolve(\n normalize(pattern).includes('**') ? normalize(pattern).split('**')[0] : dirname(normalize(pattern))\n );\n const relativePatternForError = relative(absoluteBaseDirForError, normalize(pattern)).replace(/\\\\/g, '/');\n throw new Error(\n `Error finding files for pattern \"${pattern}\" (using cwd: \"${absoluteBaseDirForError}\", globPattern: \"${relativePatternForError}\"): ${error.message}`\n );\n }\n};\n\nexport const readMdxFile = async (path: string) => {\n const { data } = matter.read(path);\n const { markdown, ...frontmatter } = data;\n return { ...frontmatter, markdown };\n};\n\nexport const searchFilesForId = async (files: string[], id: string, version?: string) => {\n // Escape the id to avoid regex issues\n const escapedId = id.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const idRegex = new RegExp(`^id:\\\\s*(['\"]|>-)?\\\\s*${escapedId}['\"]?\\\\s*$`, 'm');\n\n const versionRegex = new RegExp(`^version:\\\\s*['\"]?${version}['\"]?\\\\s*$`, 'm');\n\n const matches = files.map((file) => {\n const content = fsSync.readFileSync(file, 'utf-8');\n const hasIdMatch = content.match(idRegex);\n\n // Check version if provided\n if (version && !content.match(versionRegex)) {\n return undefined;\n }\n\n if (hasIdMatch) {\n return file;\n }\n });\n\n return matches.filter(Boolean).filter((file) => file !== undefined);\n};\n\n/**\n * Function to copy a directory from source to target, uses a tmp directory\n * @param catalogDir\n * @param source\n * @param target\n * @param filter\n */\nexport const copyDir = async (catalogDir: string, source: string, target: string, filter?: CopyFilterAsync | CopyFilterSync) => {\n const tmpDirectory = join(catalogDir, 'tmp');\n fsSync.mkdirSync(tmpDirectory, { recursive: true });\n\n // Copy everything over\n await copy(source, tmpDirectory, {\n overwrite: true,\n filter,\n });\n\n await copy(tmpDirectory, target, {\n overwrite: true,\n filter,\n });\n\n // Remove the tmp directory\n fsSync.rmSync(tmpDirectory, { recursive: true });\n};\n\n// Makes sure values in sends/recieves are unique\nexport const uniqueVersions = (messages: { id: string; version: string }[]): { id: string; version: string }[] => {\n const uniqueSet = new Set();\n\n return messages.filter((message) => {\n const key = `${message.id}-${message.version}`;\n if (!uniqueSet.has(key)) {\n uniqueSet.add(key);\n return true;\n }\n return false;\n });\n};\n","import { dirname, join } from 'path';\nimport { copyDir, findFileById, getFiles, searchFilesForId, versionExists } from './utils';\nimport matter from 'gray-matter';\nimport fs from 'node:fs/promises';\nimport fsSync from 'node:fs';\nimport { Message, Service, CustomDoc } from '../types';\nimport { satisfies } from 'semver';\nimport { lock, unlock } from 'proper-lockfile';\nimport { basename } from 'node:path';\n\ntype Resource = Service | Message | CustomDoc;\n\nexport const versionResource = async (catalogDir: string, id: string) => {\n // Find all the events in the directory\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n const matchedFiles = await searchFilesForId(files, id);\n\n if (matchedFiles.length === 0) {\n throw new Error(`No resource found with id: ${id}`);\n }\n\n // Event that is in the route of the project\n const file = matchedFiles[0];\n const sourceDirectory = dirname(file).replace(/\\/versioned?\\/[^/]+\\//, '/');\n const { data: { version = '0.0.1' } = {} } = matter.read(file);\n const targetDirectory = getVersionedDirectory(sourceDirectory, version);\n\n fsSync.mkdirSync(targetDirectory, { recursive: true });\n\n const ignoreListToCopy = ['events', 'commands', 'queries', 'versioned'];\n\n // Copy the event to the versioned directory\n await copyDir(catalogDir, sourceDirectory, targetDirectory, (src) => {\n // get the folder name\n const folderName = basename(src);\n\n if (ignoreListToCopy.includes(folderName)) {\n return false;\n }\n return true;\n });\n\n // Remove all the files in the root of the resource as they have now been versioned\n await fs.readdir(sourceDirectory).then(async (resourceFiles) => {\n await Promise.all(\n resourceFiles.map(async (file) => {\n // Dont remove anything in the ignore list\n if (ignoreListToCopy.includes(file)) {\n return;\n }\n if (file !== 'versioned') {\n fsSync.rmSync(join(sourceDirectory, file), { recursive: true });\n }\n })\n );\n });\n};\n\nexport const writeResource = async (\n catalogDir: string,\n resource: Resource,\n options: { path?: string; type: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n type: '',\n override: false,\n versionExistingContent: false,\n format: 'mdx',\n }\n) => {\n const path = options.path || `/${resource.id}`;\n const fullPath = join(catalogDir, path);\n const format = options.format || 'mdx';\n\n // Create directory if it doesn't exist\n fsSync.mkdirSync(fullPath, { recursive: true });\n\n // Create or get lock file path\n const lockPath = join(fullPath, `index.${format}`);\n\n // Ensure the file exists before attempting to lock it\n if (!fsSync.existsSync(lockPath)) {\n fsSync.writeFileSync(lockPath, '');\n }\n\n try {\n // Acquire lock with retry\n await lock(lockPath, {\n retries: 5,\n stale: 10000, // 10 seconds\n });\n\n const exists = await versionExists(catalogDir, resource.id, resource.version);\n\n if (exists && !options.override) {\n throw new Error(`Failed to write ${resource.id} (${options.type}) as the version ${resource.version} already exists`);\n }\n\n const { markdown, ...frontmatter } = resource;\n\n if (options.versionExistingContent && !exists) {\n const currentResource = await getResource(catalogDir, resource.id);\n\n if (currentResource) {\n if (satisfies(resource.version, `>${currentResource.version}`)) {\n await versionResource(catalogDir, resource.id);\n } else {\n throw new Error(`New version ${resource.version} is not greater than current version ${currentResource.version}`);\n }\n }\n }\n\n const document = matter.stringify(markdown.trim(), frontmatter);\n fsSync.writeFileSync(lockPath, document);\n } finally {\n // Always release the lock\n await unlock(lockPath).catch(() => {});\n }\n};\n\nexport const getResource = async (\n catalogDir: string,\n id?: string,\n version?: string,\n options?: { type: string; attachSchema?: boolean },\n filePath?: string\n): Promise<Resource | undefined> => {\n const attachSchema = options?.attachSchema || false;\n const file = filePath || (id ? await findFileById(catalogDir, id, version) : undefined);\n if (!file || !fsSync.existsSync(file)) return;\n\n const { data, content } = matter.read(file);\n\n if (attachSchema && data?.schemaPath) {\n const resourceDirectory = dirname(file);\n const pathToSchema = join(resourceDirectory, data.schemaPath);\n if (fsSync.existsSync(pathToSchema)) {\n const schema = fsSync.readFileSync(pathToSchema, 'utf8');\n // Try to parse the schema\n try {\n data.schema = JSON.parse(schema);\n } catch (error) {\n data.schema = schema;\n }\n }\n }\n\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n};\n\nexport const getResourcePath = async (catalogDir: string, id: string, version?: string) => {\n const file = await findFileById(catalogDir, id, version);\n if (!file) return;\n\n return {\n fullPath: file,\n relativePath: file.replace(catalogDir, ''),\n directory: dirname(file.replace(catalogDir, '')),\n };\n};\n\nexport const toResource = async (catalogDir: string, rawContents: string) => {\n const { data, content } = matter(rawContents);\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n};\n\nexport const getResources = async (\n catalogDir: string,\n {\n type,\n latestOnly = false,\n ignore = [],\n pattern = '',\n attachSchema = false,\n }: { type: string; pattern?: string; latestOnly?: boolean; ignore?: string[]; attachSchema?: boolean }\n): Promise<Resource[] | undefined> => {\n const ignoreList = latestOnly ? `**/versioned/**` : '';\n const filePattern = pattern || `${catalogDir}/**/${type}/**/index.{md,mdx}`;\n const files = await getFiles(filePattern, [ignoreList, ...ignore]);\n\n if (files.length === 0) return;\n\n return files.map((file) => {\n const { data, content } = matter.read(file);\n\n // Attach the schema if the attachSchema option is set to true\n if (attachSchema && data?.schemaPath) {\n const resourceDirectory = dirname(file);\n const pathToSchema = join(resourceDirectory, data.schemaPath);\n if (fsSync.existsSync(pathToSchema)) {\n const schema = fsSync.readFileSync(pathToSchema, 'utf8');\n // Try to parse the schema\n try {\n data.schema = JSON.parse(schema);\n } catch (error) {\n data.schema = schema;\n }\n }\n }\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n });\n};\n\nexport const rmResourceById = async (\n catalogDir: string,\n id: string,\n version?: string,\n options?: { type: string; persistFiles?: boolean }\n) => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n\n const matchedFiles = await searchFilesForId(files, id, version);\n\n if (matchedFiles.length === 0) {\n throw new Error(`No ${options?.type || 'resource'} found with id: ${id}`);\n }\n\n if (options?.persistFiles) {\n await Promise.all(\n matchedFiles.map(async (file) => {\n await fs.rm(file, { recursive: true });\n // Verify file is actually removed\n await waitForFileRemoval(file);\n })\n );\n } else {\n await Promise.all(\n matchedFiles.map(async (file) => {\n const directory = dirname(file);\n await fs.rm(directory, { recursive: true, force: true });\n // Verify directory is actually removed\n await waitForFileRemoval(directory);\n })\n );\n }\n};\n\n// Helper function to ensure file/directory is completely removed\nconst waitForFileRemoval = async (path: string, maxRetries: number = 50, delay: number = 10): Promise<void> => {\n for (let i = 0; i < maxRetries; i++) {\n try {\n await fs.access(path);\n // If access succeeds, file still exists, wait and retry\n await new Promise((resolve) => setTimeout(resolve, delay));\n } catch (error) {\n // If access fails, file is removed\n return;\n }\n }\n // If we reach here, file still exists after all retries\n throw new Error(`File/directory ${path} was not removed after ${maxRetries} attempts`);\n};\n\nexport const addFileToResource = async (\n catalogDir: string,\n id: string,\n file: { content: string; fileName: string },\n version?: string\n) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory to write file to');\n\n let fileContent = file.content.trim();\n\n try {\n const json = JSON.parse(fileContent);\n fileContent = JSON.stringify(json, null, 2);\n } catch (error) {\n // Just silently fail if the file is not valid JSON\n // Write it as it is\n }\n\n fsSync.writeFileSync(join(dirname(pathToResource), file.fileName), fileContent);\n};\n\nexport const getFileFromResource = async (catalogDir: string, id: string, file: { fileName: string }, version?: string) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory of resource');\n\n const exists = await fs\n .access(join(dirname(pathToResource), file.fileName))\n .then(() => true)\n .catch(() => false);\n if (!exists) throw new Error(`File ${file.fileName} does not exist in resource ${id} v(${version})`);\n\n return fsSync.readFileSync(join(dirname(pathToResource), file.fileName), 'utf-8');\n};\nexport const getVersionedDirectory = (sourceDirectory: string, version: any): string => {\n return join(sourceDirectory, 'versioned', version);\n};\n\nexport const isLatestVersion = async (catalogDir: string, id: string, version?: string) => {\n const resource = await getResource(catalogDir, id, version);\n if (!resource) return false;\n\n const pathToResource = await getResourcePath(catalogDir, id, version);\n\n return !pathToResource?.relativePath.replace(/\\\\/g, '/').includes('/versioned/');\n};\n"],"mappings":"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","names":["import_promises","import_node_path","matter","match","fsSync","import_gray_matter","import_node_fs","import_semver","import_node_path","matter","fsSync","fs","file","matter","fsSync","fs","resolve","fs"]}
|
package/dist/queries.mjs
CHANGED
|
@@ -101,6 +101,7 @@ import fs from "fs/promises";
|
|
|
101
101
|
import fsSync2 from "fs";
|
|
102
102
|
import { satisfies as satisfies2 } from "semver";
|
|
103
103
|
import { lock, unlock } from "proper-lockfile";
|
|
104
|
+
import { basename as basename2 } from "path";
|
|
104
105
|
var versionResource = async (catalogDir, id) => {
|
|
105
106
|
const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);
|
|
106
107
|
const matchedFiles = await searchFilesForId(files, id);
|
|
@@ -108,16 +109,24 @@ var versionResource = async (catalogDir, id) => {
|
|
|
108
109
|
throw new Error(`No resource found with id: ${id}`);
|
|
109
110
|
}
|
|
110
111
|
const file = matchedFiles[0];
|
|
111
|
-
const sourceDirectory = dirname2(file);
|
|
112
|
+
const sourceDirectory = dirname2(file).replace(/\/versioned?\/[^/]+\//, "/");
|
|
112
113
|
const { data: { version = "0.0.1" } = {} } = matter2.read(file);
|
|
113
114
|
const targetDirectory = getVersionedDirectory(sourceDirectory, version);
|
|
114
115
|
fsSync2.mkdirSync(targetDirectory, { recursive: true });
|
|
116
|
+
const ignoreListToCopy = ["events", "commands", "queries", "versioned"];
|
|
115
117
|
await copyDir(catalogDir, sourceDirectory, targetDirectory, (src) => {
|
|
116
|
-
|
|
118
|
+
const folderName = basename2(src);
|
|
119
|
+
if (ignoreListToCopy.includes(folderName)) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
return true;
|
|
117
123
|
});
|
|
118
124
|
await fs.readdir(sourceDirectory).then(async (resourceFiles) => {
|
|
119
125
|
await Promise.all(
|
|
120
126
|
resourceFiles.map(async (file2) => {
|
|
127
|
+
if (ignoreListToCopy.includes(file2)) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
121
130
|
if (file2 !== "versioned") {
|
|
122
131
|
fsSync2.rmSync(join2(sourceDirectory, file2), { recursive: true });
|
|
123
132
|
}
|
package/dist/queries.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/queries.ts","../src/internal/utils.ts","../src/internal/resources.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { findFileById } from './internal/utils';\nimport type { Query } from './types';\nimport {\n addFileToResource,\n getResource,\n getResourcePath,\n getResources,\n rmResourceById,\n versionResource,\n writeResource,\n} from './internal/resources';\n\n/**\n * Returns a query from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the query\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getQuery } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the event\n * const event = await getQuery('GetOrder');\n *\n * // Gets a version of the event\n * const event = await getQuery('GetOrder', '0.0.1');\n *\n * // Gets the query with the schema attached\n * const event = await getQuery('GetOrder', '0.0.1', { attachSchema: true });\n * ```\n */\nexport const getQuery =\n (directory: string) =>\n async (id: string, version?: string, options?: { attachSchema?: boolean }): Promise<Query> =>\n getResource(directory, id, version, { type: 'query', ...options }) as Promise<Query>;\n\n/**\n * Write a query to EventCatalog.\n *\n * You can optionally override the path of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeQuery } = utils('/path/to/eventcatalog');\n *\n * // Write an event to the catalog\n * // Event would be written to queries/GetOrder\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * });\n *\n * // Write an event to the catalog but override the path\n * // Event would be written to queries/Inventory/GetOrder\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { path: \"/Orders/GetOrder\"});\n *\n * // Write a query to the catalog and override the existing content (if there is any)\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { override: true });\n *\n * // Write a query to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeQuery =\n (directory: string) =>\n async (\n query: Query,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n versionExistingContent: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...query }, { ...options, type: 'query' });\n\n/**\n * Returns all queries from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the queries.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getQueries } = utils('/path/to/eventcatalog');\n *\n * // Gets all queries (and versions) from the catalog\n * const queries = await getQueries();\n *\n * // Gets all queries (only latest version) from the catalog\n * const queries = await getQueries({ latestOnly: true });\n *\n * // Gets all queries with the schema attached\n * const queries = await getQueries({ attachSchema: true });\n * ```\n */\nexport const getQueries =\n (directory: string) =>\n async (options?: { latestOnly?: boolean; attachSchema?: boolean }): Promise<Query[]> =>\n getResources(directory, { type: 'queries', ...options }) as Promise<Query[]>;\n\n/**\n * Write a query to a service in EventCatalog.\n *\n * You can optionally override the path of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeQueryToService } = utils('/path/to/eventcatalog');\n *\n * // Write an event to a given service in the catalog\n * // Event would be written to services/Orders/queries/GetOrder\n * await writeQueryToService({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { id: 'Orders' });\n * ```\n */\nexport const writeQueryToService =\n (directory: string) =>\n async (\n query: Query,\n service: { id: string; version?: string },\n options: { path?: string; format?: 'md' | 'mdx'; override?: boolean } = { path: '', format: 'mdx', override: false }\n ) => {\n const resourcePath = await getResourcePath(directory, service.id, service.version);\n if (!resourcePath) {\n throw new Error('Service not found');\n }\n let pathForQuery =\n service.version && service.version !== 'latest'\n ? `${resourcePath.directory}/versioned/${service.version}/queries`\n : `${resourcePath.directory}/queries`;\n pathForQuery = join(pathForQuery, query.id);\n await writeResource(directory, { ...query }, { ...options, path: pathForQuery, type: 'query' });\n };\n\n/**\n * Delete a query at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmQuery } = utils('/path/to/eventcatalog');\n *\n * // removes an query at the given path (queries dir is appended to the given path)\n * // Removes the query at queries/GetOrders\n * await rmQuery('/GetOrders');\n * ```\n */\nexport const rmQuery = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a query by it's id.\n *\n * Optionally specify a version to delete a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmQueryById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryAdjusted query\n * await rmQueryById('GetOrder');\n *\n * // deletes a specific version of the GetOrder query\n * await rmQueryById('GetOrder', '0.0.1');\n * ```\n */\nexport const rmQueryById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) => {\n await rmResourceById(directory, id, version, { type: 'query', persistFiles });\n};\n\n/**\n * Version a query by it's id.\n *\n * Takes the latest query and moves it to a versioned directory.\n * All files with this query are also versioned (e.g /queries/GetOrder/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionQuery } = utils('/path/to/eventcatalog');\n *\n * // moves the latest GetOrder query to a versioned directory\n * // the version within that query is used as the version number.\n * await versionQuery('GetOrder');\n *\n * ```\n */\nexport const versionQuery = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Add a file to a query by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToQuery } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest GetOrder query\n * await addFileToQuery('GetOrder', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the GetOrder query\n * await addFileToQuery('GetOrder', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToQuery =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Add a schema to a query by it's id.\n *\n * Optionally specify a version to add a schema to a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addSchemaToQuery } = utils('/path/to/eventcatalog');\n *\n * // JSON schema example\n * const schema = {\n * \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n * \"type\": \"object\",\n * \"properties\": {\n * \"name\": {\n * \"type\": \"string\"\n * },\n * \"age\": {\n * \"type\": \"number\"\n * }\n * },\n * \"required\": [\"name\", \"age\"]\n * };\n *\n * // adds a schema to the latest GetOrder query\n * await addSchemaToQuery('GetOrder', { schema, fileName: 'schema.json' });\n *\n * // adds a file to a specific version of the GetOrder query\n * await addSchemaToQuery('GetOrder', { schema, fileName: 'schema.json' }, '0.0.1');\n *\n * ```\n */\nexport const addSchemaToQuery =\n (directory: string) => async (id: string, schema: { schema: string; fileName: string }, version?: string) => {\n await addFileToQuery(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);\n };\n\n/**\n * Check to see if the catalog has a version for the given query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { queryHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await queryHasVersion('GetOrder', '0.0.1');\n * await queryHasVersion('GetOrder', 'latest');\n * await queryHasVersion('GetOrder', '0.0.x');*\n *\n * ```\n */\nexport const queryHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import { globSync } from 'glob';\nimport fsSync from 'node:fs';\nimport { copy, CopyFilterAsync, CopyFilterSync } from 'fs-extra';\nimport { join, dirname, normalize, sep as pathSeparator, resolve, basename, relative } from 'node:path';\nimport matter from 'gray-matter';\nimport { satisfies, validRange, valid } from 'semver';\n\n/**\n * Returns true if a given version of a resource id exists in the catalog\n */\nexport const versionExists = async (catalogDir: string, id: string, version: string) => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n const matchedFiles = (await searchFilesForId(files, id, version)) || [];\n return matchedFiles.length > 0;\n};\n\nexport const findFileById = async (catalogDir: string, id: string, version?: string): Promise<string | undefined> => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n\n const matchedFiles = (await searchFilesForId(files, id)) || [];\n const latestVersion = matchedFiles.find((path) => !path.includes('versioned'));\n\n // If no version is provided, return the latest version\n if (!version) {\n return latestVersion;\n }\n\n // map files into gray matter to get versions\n const parsedFiles = matchedFiles.map((path) => {\n const { data } = matter.read(path);\n return { ...data, path };\n }) as any[];\n\n const semverRange = validRange(version);\n\n if (semverRange && valid(version)) {\n const match = parsedFiles.filter((c) => satisfies(c.version, semverRange));\n return match.length > 0 ? match[0].path : undefined;\n }\n\n // Order by version\n const sorted = parsedFiles.sort((a, b) => {\n return a.version.localeCompare(b.version);\n });\n\n // latest version\n const match = sorted.length > 0 ? [sorted[sorted.length - 1]] : [];\n\n if (match.length > 0) {\n return match[0].path;\n }\n};\n\nexport const getFiles = async (pattern: string, ignore: string | string[] = '') => {\n try {\n // 1. Normalize the input pattern to handle mixed separators potentially\n const normalizedInputPattern = normalize(pattern);\n\n // 2. Determine the absolute base directory (cwd for glob)\n // Resolve ensures it's absolute. Handles cases with/without globstar.\n const absoluteBaseDir = resolve(\n normalizedInputPattern.includes('**') ? normalizedInputPattern.split('**')[0] : dirname(normalizedInputPattern)\n );\n\n // 3. Determine the pattern part relative to the absolute base directory\n // We extract the part of the normalized pattern that comes *after* the absoluteBaseDir\n let relativePattern = relative(absoluteBaseDir, normalizedInputPattern);\n\n // On Windows, relative() might return empty string if paths are identical,\n // or might need normalization if the original pattern didn't have `**`\n // Example: pattern = 'dir/file.md', absoluteBaseDir='.../dir', normalized='...\\dir\\file.md'\n // relative() -> 'file.md'\n // Example: pattern = 'dir/**/file.md', absoluteBaseDir='.../dir', normalized='...\\dir\\**\\file.md'\n // relative() -> '**\\file.md'\n // Convert separators in the relative pattern to forward slashes for glob\n relativePattern = relativePattern.replace(/\\\\/g, '/');\n\n const ignoreList = Array.isArray(ignore) ? ignore : [ignore];\n\n const files = globSync(relativePattern, {\n cwd: absoluteBaseDir,\n ignore: ['node_modules/**', ...ignoreList],\n absolute: true,\n nodir: true,\n });\n\n // 5. Normalize results for consistency before returning\n return files.map(normalize);\n } catch (error: any) {\n // Add more diagnostic info to the error\n const absoluteBaseDirForError = resolve(\n normalize(pattern).includes('**') ? normalize(pattern).split('**')[0] : dirname(normalize(pattern))\n );\n const relativePatternForError = relative(absoluteBaseDirForError, normalize(pattern)).replace(/\\\\/g, '/');\n throw new Error(\n `Error finding files for pattern \"${pattern}\" (using cwd: \"${absoluteBaseDirForError}\", globPattern: \"${relativePatternForError}\"): ${error.message}`\n );\n }\n};\n\nexport const readMdxFile = async (path: string) => {\n const { data } = matter.read(path);\n const { markdown, ...frontmatter } = data;\n return { ...frontmatter, markdown };\n};\n\nexport const searchFilesForId = async (files: string[], id: string, version?: string) => {\n // Escape the id to avoid regex issues\n const escapedId = id.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const idRegex = new RegExp(`^id:\\\\s*(['\"]|>-)?\\\\s*${escapedId}['\"]?\\\\s*$`, 'm');\n\n const versionRegex = new RegExp(`^version:\\\\s*['\"]?${version}['\"]?\\\\s*$`, 'm');\n\n const matches = files.map((file) => {\n const content = fsSync.readFileSync(file, 'utf-8');\n const hasIdMatch = content.match(idRegex);\n\n // Check version if provided\n if (version && !content.match(versionRegex)) {\n return undefined;\n }\n\n if (hasIdMatch) {\n return file;\n }\n });\n\n return matches.filter(Boolean).filter((file) => file !== undefined);\n};\n\n/**\n * Function to copy a directory from source to target, uses a tmp directory\n * @param catalogDir\n * @param source\n * @param target\n * @param filter\n */\nexport const copyDir = async (catalogDir: string, source: string, target: string, filter?: CopyFilterAsync | CopyFilterSync) => {\n const tmpDirectory = join(catalogDir, 'tmp');\n fsSync.mkdirSync(tmpDirectory, { recursive: true });\n\n // Copy everything over\n await copy(source, tmpDirectory, {\n overwrite: true,\n filter,\n });\n\n await copy(tmpDirectory, target, {\n overwrite: true,\n filter,\n });\n\n // Remove the tmp directory\n fsSync.rmSync(tmpDirectory, { recursive: true });\n};\n\n// Makes sure values in sends/recieves are unique\nexport const uniqueVersions = (messages: { id: string; version: string }[]): { id: string; version: string }[] => {\n const uniqueSet = new Set();\n\n return messages.filter((message) => {\n const key = `${message.id}-${message.version}`;\n if (!uniqueSet.has(key)) {\n uniqueSet.add(key);\n return true;\n }\n return false;\n });\n};\n","import { dirname, join } from 'path';\nimport { copyDir, findFileById, getFiles, searchFilesForId, versionExists } from './utils';\nimport matter from 'gray-matter';\nimport fs from 'node:fs/promises';\nimport fsSync from 'node:fs';\nimport { Message, Service, CustomDoc } from '../types';\nimport { satisfies } from 'semver';\nimport { lock, unlock } from 'proper-lockfile';\n\ntype Resource = Service | Message | CustomDoc;\n\nexport const versionResource = async (catalogDir: string, id: string) => {\n // Find all the events in the directory\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n const matchedFiles = await searchFilesForId(files, id);\n\n if (matchedFiles.length === 0) {\n throw new Error(`No resource found with id: ${id}`);\n }\n\n // Event that is in the route of the project\n const file = matchedFiles[0];\n const sourceDirectory = dirname(file);\n const { data: { version = '0.0.1' } = {} } = matter.read(file);\n const targetDirectory = getVersionedDirectory(sourceDirectory, version);\n\n fsSync.mkdirSync(targetDirectory, { recursive: true });\n\n // Copy the event to the versioned directory\n await copyDir(catalogDir, sourceDirectory, targetDirectory, (src) => {\n return !src.includes('versioned');\n });\n\n // Remove all the files in the root of the resource as they have now been versioned\n await fs.readdir(sourceDirectory).then(async (resourceFiles) => {\n await Promise.all(\n resourceFiles.map(async (file) => {\n if (file !== 'versioned') {\n fsSync.rmSync(join(sourceDirectory, file), { recursive: true });\n }\n })\n );\n });\n};\n\nexport const writeResource = async (\n catalogDir: string,\n resource: Resource,\n options: { path?: string; type: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n type: '',\n override: false,\n versionExistingContent: false,\n format: 'mdx',\n }\n) => {\n const path = options.path || `/${resource.id}`;\n const fullPath = join(catalogDir, path);\n const format = options.format || 'mdx';\n\n // Create directory if it doesn't exist\n fsSync.mkdirSync(fullPath, { recursive: true });\n\n // Create or get lock file path\n const lockPath = join(fullPath, `index.${format}`);\n\n // Ensure the file exists before attempting to lock it\n if (!fsSync.existsSync(lockPath)) {\n fsSync.writeFileSync(lockPath, '');\n }\n\n try {\n // Acquire lock with retry\n await lock(lockPath, {\n retries: 5,\n stale: 10000, // 10 seconds\n });\n\n const exists = await versionExists(catalogDir, resource.id, resource.version);\n\n if (exists && !options.override) {\n throw new Error(`Failed to write ${resource.id} (${options.type}) as the version ${resource.version} already exists`);\n }\n\n const { markdown, ...frontmatter } = resource;\n\n if (options.versionExistingContent && !exists) {\n const currentResource = await getResource(catalogDir, resource.id);\n\n if (currentResource) {\n if (satisfies(resource.version, `>${currentResource.version}`)) {\n await versionResource(catalogDir, resource.id);\n } else {\n throw new Error(`New version ${resource.version} is not greater than current version ${currentResource.version}`);\n }\n }\n }\n\n const document = matter.stringify(markdown.trim(), frontmatter);\n fsSync.writeFileSync(lockPath, document);\n } finally {\n // Always release the lock\n await unlock(lockPath).catch(() => {});\n }\n};\n\nexport const getResource = async (\n catalogDir: string,\n id?: string,\n version?: string,\n options?: { type: string; attachSchema?: boolean },\n filePath?: string\n): Promise<Resource | undefined> => {\n const attachSchema = options?.attachSchema || false;\n const file = filePath || (id ? await findFileById(catalogDir, id, version) : undefined);\n if (!file || !fsSync.existsSync(file)) return;\n\n const { data, content } = matter.read(file);\n\n if (attachSchema && data?.schemaPath) {\n const resourceDirectory = dirname(file);\n const pathToSchema = join(resourceDirectory, data.schemaPath);\n if (fsSync.existsSync(pathToSchema)) {\n const schema = fsSync.readFileSync(pathToSchema, 'utf8');\n // Try to parse the schema\n try {\n data.schema = JSON.parse(schema);\n } catch (error) {\n data.schema = schema;\n }\n }\n }\n\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n};\n\nexport const getResourcePath = async (catalogDir: string, id: string, version?: string) => {\n const file = await findFileById(catalogDir, id, version);\n if (!file) return;\n\n return {\n fullPath: file,\n relativePath: file.replace(catalogDir, ''),\n directory: dirname(file.replace(catalogDir, '')),\n };\n};\n\nexport const toResource = async (catalogDir: string, rawContents: string) => {\n const { data, content } = matter(rawContents);\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n};\n\nexport const getResources = async (\n catalogDir: string,\n {\n type,\n latestOnly = false,\n ignore = [],\n pattern = '',\n attachSchema = false,\n }: { type: string; pattern?: string; latestOnly?: boolean; ignore?: string[]; attachSchema?: boolean }\n): Promise<Resource[] | undefined> => {\n const ignoreList = latestOnly ? `**/versioned/**` : '';\n const filePattern = pattern || `${catalogDir}/**/${type}/**/index.{md,mdx}`;\n const files = await getFiles(filePattern, [ignoreList, ...ignore]);\n\n if (files.length === 0) return;\n\n return files.map((file) => {\n const { data, content } = matter.read(file);\n\n // Attach the schema if the attachSchema option is set to true\n if (attachSchema && data?.schemaPath) {\n const resourceDirectory = dirname(file);\n const pathToSchema = join(resourceDirectory, data.schemaPath);\n if (fsSync.existsSync(pathToSchema)) {\n const schema = fsSync.readFileSync(pathToSchema, 'utf8');\n // Try to parse the schema\n try {\n data.schema = JSON.parse(schema);\n } catch (error) {\n data.schema = schema;\n }\n }\n }\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n });\n};\n\nexport const rmResourceById = async (\n catalogDir: string,\n id: string,\n version?: string,\n options?: { type: string; persistFiles?: boolean }\n) => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n\n const matchedFiles = await searchFilesForId(files, id, version);\n\n if (matchedFiles.length === 0) {\n throw new Error(`No ${options?.type || 'resource'} found with id: ${id}`);\n }\n\n if (options?.persistFiles) {\n await Promise.all(\n matchedFiles.map(async (file) => {\n await fs.rm(file, { recursive: true });\n // Verify file is actually removed\n await waitForFileRemoval(file);\n })\n );\n } else {\n await Promise.all(\n matchedFiles.map(async (file) => {\n const directory = dirname(file);\n await fs.rm(directory, { recursive: true, force: true });\n // Verify directory is actually removed\n await waitForFileRemoval(directory);\n })\n );\n }\n};\n\n// Helper function to ensure file/directory is completely removed\nconst waitForFileRemoval = async (path: string, maxRetries: number = 50, delay: number = 10): Promise<void> => {\n for (let i = 0; i < maxRetries; i++) {\n try {\n await fs.access(path);\n // If access succeeds, file still exists, wait and retry\n await new Promise((resolve) => setTimeout(resolve, delay));\n } catch (error) {\n // If access fails, file is removed\n return;\n }\n }\n // If we reach here, file still exists after all retries\n throw new Error(`File/directory ${path} was not removed after ${maxRetries} attempts`);\n};\n\nexport const addFileToResource = async (\n catalogDir: string,\n id: string,\n file: { content: string; fileName: string },\n version?: string\n) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory to write file to');\n\n let fileContent = file.content.trim();\n\n try {\n const json = JSON.parse(fileContent);\n fileContent = JSON.stringify(json, null, 2);\n } catch (error) {\n // Just silently fail if the file is not valid JSON\n // Write it as it is\n }\n\n fsSync.writeFileSync(join(dirname(pathToResource), file.fileName), fileContent);\n};\n\nexport const getFileFromResource = async (catalogDir: string, id: string, file: { fileName: string }, version?: string) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory of resource');\n\n const exists = await fs\n .access(join(dirname(pathToResource), file.fileName))\n .then(() => true)\n .catch(() => false);\n if (!exists) throw new Error(`File ${file.fileName} does not exist in resource ${id} v(${version})`);\n\n return fsSync.readFileSync(join(dirname(pathToResource), file.fileName), 'utf-8');\n};\nexport const getVersionedDirectory = (sourceDirectory: string, version: any): string => {\n return join(sourceDirectory, 'versioned', version);\n};\n\nexport const isLatestVersion = async (catalogDir: string, id: string, version?: string) => {\n const resource = await getResource(catalogDir, id, version);\n if (!resource) return false;\n\n const pathToResource = await getResourcePath(catalogDir, id, version);\n\n return !pathToResource?.relativePath.replace(/\\\\/g, '/').includes('/versioned/');\n};\n"],"mappings":"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","names":["fs","join","match","dirname","join","matter","fsSync","satisfies","dirname","file","join","matter","dirname","join","fsSync","resolve","join","join","fs"]}
|
|
1
|
+
{"version":3,"sources":["../src/queries.ts","../src/internal/utils.ts","../src/internal/resources.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { findFileById } from './internal/utils';\nimport type { Query } from './types';\nimport {\n addFileToResource,\n getResource,\n getResourcePath,\n getResources,\n rmResourceById,\n versionResource,\n writeResource,\n} from './internal/resources';\n\n/**\n * Returns a query from EventCatalog.\n *\n * You can optionally specify a version to get a specific version of the query\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getQuery } = utils('/path/to/eventcatalog');\n *\n * // Gets the latest version of the event\n * const event = await getQuery('GetOrder');\n *\n * // Gets a version of the event\n * const event = await getQuery('GetOrder', '0.0.1');\n *\n * // Gets the query with the schema attached\n * const event = await getQuery('GetOrder', '0.0.1', { attachSchema: true });\n * ```\n */\nexport const getQuery =\n (directory: string) =>\n async (id: string, version?: string, options?: { attachSchema?: boolean }): Promise<Query> =>\n getResource(directory, id, version, { type: 'query', ...options }) as Promise<Query>;\n\n/**\n * Write a query to EventCatalog.\n *\n * You can optionally override the path of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeQuery } = utils('/path/to/eventcatalog');\n *\n * // Write an event to the catalog\n * // Event would be written to queries/GetOrder\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * });\n *\n * // Write an event to the catalog but override the path\n * // Event would be written to queries/Inventory/GetOrder\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { path: \"/Orders/GetOrder\"});\n *\n * // Write a query to the catalog and override the existing content (if there is any)\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { override: true });\n *\n * // Write a query to the catalog and version the previous version\n * // only works if the new version is greater than the previous version\n * await writeQuery({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { versionExistingContent: true });\n *\n * ```\n */\nexport const writeQuery =\n (directory: string) =>\n async (\n query: Query,\n options: { path?: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n override: false,\n versionExistingContent: false,\n format: 'mdx',\n }\n ) =>\n writeResource(directory, { ...query }, { ...options, type: 'query' });\n\n/**\n * Returns all queries from EventCatalog.\n *\n * You can optionally specify if you want to get the latest version of the queries.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { getQueries } = utils('/path/to/eventcatalog');\n *\n * // Gets all queries (and versions) from the catalog\n * const queries = await getQueries();\n *\n * // Gets all queries (only latest version) from the catalog\n * const queries = await getQueries({ latestOnly: true });\n *\n * // Gets all queries with the schema attached\n * const queries = await getQueries({ attachSchema: true });\n * ```\n */\nexport const getQueries =\n (directory: string) =>\n async (options?: { latestOnly?: boolean; attachSchema?: boolean }): Promise<Query[]> =>\n getResources(directory, { type: 'queries', ...options }) as Promise<Query[]>;\n\n/**\n * Write a query to a service in EventCatalog.\n *\n * You can optionally override the path of the event.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { writeQueryToService } = utils('/path/to/eventcatalog');\n *\n * // Write an event to a given service in the catalog\n * // Event would be written to services/Orders/queries/GetOrder\n * await writeQueryToService({\n * id: 'GetOrder',\n * name: 'Get Order',\n * version: '0.0.1',\n * summary: 'This is a summary',\n * markdown: '# Hello world',\n * }, { id: 'Orders' });\n * ```\n */\nexport const writeQueryToService =\n (directory: string) =>\n async (\n query: Query,\n service: { id: string; version?: string },\n options: { path?: string; format?: 'md' | 'mdx'; override?: boolean } = { path: '', format: 'mdx', override: false }\n ) => {\n const resourcePath = await getResourcePath(directory, service.id, service.version);\n if (!resourcePath) {\n throw new Error('Service not found');\n }\n let pathForQuery =\n service.version && service.version !== 'latest'\n ? `${resourcePath.directory}/versioned/${service.version}/queries`\n : `${resourcePath.directory}/queries`;\n pathForQuery = join(pathForQuery, query.id);\n await writeResource(directory, { ...query }, { ...options, path: pathForQuery, type: 'query' });\n };\n\n/**\n * Delete a query at it's given path.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmQuery } = utils('/path/to/eventcatalog');\n *\n * // removes an query at the given path (queries dir is appended to the given path)\n * // Removes the query at queries/GetOrders\n * await rmQuery('/GetOrders');\n * ```\n */\nexport const rmQuery = (directory: string) => async (path: string) => {\n await fs.rm(join(directory, path), { recursive: true });\n};\n\n/**\n * Delete a query by it's id.\n *\n * Optionally specify a version to delete a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { rmQueryById } = utils('/path/to/eventcatalog');\n *\n * // deletes the latest InventoryAdjusted query\n * await rmQueryById('GetOrder');\n *\n * // deletes a specific version of the GetOrder query\n * await rmQueryById('GetOrder', '0.0.1');\n * ```\n */\nexport const rmQueryById = (directory: string) => async (id: string, version?: string, persistFiles?: boolean) => {\n await rmResourceById(directory, id, version, { type: 'query', persistFiles });\n};\n\n/**\n * Version a query by it's id.\n *\n * Takes the latest query and moves it to a versioned directory.\n * All files with this query are also versioned (e.g /queries/GetOrder/schema.json)\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { versionQuery } = utils('/path/to/eventcatalog');\n *\n * // moves the latest GetOrder query to a versioned directory\n * // the version within that query is used as the version number.\n * await versionQuery('GetOrder');\n *\n * ```\n */\nexport const versionQuery = (directory: string) => async (id: string) => versionResource(directory, id);\n\n/**\n * Add a file to a query by it's id.\n *\n * Optionally specify a version to add a file to a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addFileToQuery } = utils('/path/to/eventcatalog');\n *\n * // adds a file to the latest GetOrder query\n * await addFileToQuery('GetOrder', { content: 'Hello world', fileName: 'hello.txt' });\n *\n * // adds a file to a specific version of the GetOrder query\n * await addFileToQuery('GetOrder', { content: 'Hello world', fileName: 'hello.txt' }, '0.0.1');\n *\n * ```\n */\nexport const addFileToQuery =\n (directory: string) => async (id: string, file: { content: string; fileName: string }, version?: string) =>\n addFileToResource(directory, id, file, version);\n\n/**\n * Add a schema to a query by it's id.\n *\n * Optionally specify a version to add a schema to a specific version of the query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { addSchemaToQuery } = utils('/path/to/eventcatalog');\n *\n * // JSON schema example\n * const schema = {\n * \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n * \"type\": \"object\",\n * \"properties\": {\n * \"name\": {\n * \"type\": \"string\"\n * },\n * \"age\": {\n * \"type\": \"number\"\n * }\n * },\n * \"required\": [\"name\", \"age\"]\n * };\n *\n * // adds a schema to the latest GetOrder query\n * await addSchemaToQuery('GetOrder', { schema, fileName: 'schema.json' });\n *\n * // adds a file to a specific version of the GetOrder query\n * await addSchemaToQuery('GetOrder', { schema, fileName: 'schema.json' }, '0.0.1');\n *\n * ```\n */\nexport const addSchemaToQuery =\n (directory: string) => async (id: string, schema: { schema: string; fileName: string }, version?: string) => {\n await addFileToQuery(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);\n };\n\n/**\n * Check to see if the catalog has a version for the given query.\n *\n * @example\n * ```ts\n * import utils from '@eventcatalog/utils';\n *\n * const { queryHasVersion } = utils('/path/to/eventcatalog');\n *\n * // returns true if version is found for the given event and version (supports semver)\n * await queryHasVersion('GetOrder', '0.0.1');\n * await queryHasVersion('GetOrder', 'latest');\n * await queryHasVersion('GetOrder', '0.0.x');*\n *\n * ```\n */\nexport const queryHasVersion = (directory: string) => async (id: string, version?: string) => {\n const file = await findFileById(directory, id, version);\n return !!file;\n};\n","import { globSync } from 'glob';\nimport fsSync from 'node:fs';\nimport { copy, CopyFilterAsync, CopyFilterSync } from 'fs-extra';\nimport { join, dirname, normalize, sep as pathSeparator, resolve, basename, relative } from 'node:path';\nimport matter from 'gray-matter';\nimport { satisfies, validRange, valid } from 'semver';\n\n/**\n * Returns true if a given version of a resource id exists in the catalog\n */\nexport const versionExists = async (catalogDir: string, id: string, version: string) => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n const matchedFiles = (await searchFilesForId(files, id, version)) || [];\n return matchedFiles.length > 0;\n};\n\nexport const findFileById = async (catalogDir: string, id: string, version?: string): Promise<string | undefined> => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n\n const matchedFiles = (await searchFilesForId(files, id)) || [];\n const latestVersion = matchedFiles.find((path) => !path.includes('versioned'));\n\n // If no version is provided, return the latest version\n if (!version) {\n return latestVersion;\n }\n\n // map files into gray matter to get versions\n const parsedFiles = matchedFiles.map((path) => {\n const { data } = matter.read(path);\n return { ...data, path };\n }) as any[];\n\n const semverRange = validRange(version);\n\n if (semverRange && valid(version)) {\n const match = parsedFiles.filter((c) => satisfies(c.version, semverRange));\n return match.length > 0 ? match[0].path : undefined;\n }\n\n // Order by version\n const sorted = parsedFiles.sort((a, b) => {\n return a.version.localeCompare(b.version);\n });\n\n // latest version\n const match = sorted.length > 0 ? [sorted[sorted.length - 1]] : [];\n\n if (match.length > 0) {\n return match[0].path;\n }\n};\n\nexport const getFiles = async (pattern: string, ignore: string | string[] = '') => {\n try {\n // 1. Normalize the input pattern to handle mixed separators potentially\n const normalizedInputPattern = normalize(pattern);\n\n // 2. Determine the absolute base directory (cwd for glob)\n // Resolve ensures it's absolute. Handles cases with/without globstar.\n const absoluteBaseDir = resolve(\n normalizedInputPattern.includes('**') ? normalizedInputPattern.split('**')[0] : dirname(normalizedInputPattern)\n );\n\n // 3. Determine the pattern part relative to the absolute base directory\n // We extract the part of the normalized pattern that comes *after* the absoluteBaseDir\n let relativePattern = relative(absoluteBaseDir, normalizedInputPattern);\n\n // On Windows, relative() might return empty string if paths are identical,\n // or might need normalization if the original pattern didn't have `**`\n // Example: pattern = 'dir/file.md', absoluteBaseDir='.../dir', normalized='...\\dir\\file.md'\n // relative() -> 'file.md'\n // Example: pattern = 'dir/**/file.md', absoluteBaseDir='.../dir', normalized='...\\dir\\**\\file.md'\n // relative() -> '**\\file.md'\n // Convert separators in the relative pattern to forward slashes for glob\n relativePattern = relativePattern.replace(/\\\\/g, '/');\n\n const ignoreList = Array.isArray(ignore) ? ignore : [ignore];\n\n const files = globSync(relativePattern, {\n cwd: absoluteBaseDir,\n ignore: ['node_modules/**', ...ignoreList],\n absolute: true,\n nodir: true,\n });\n\n // 5. Normalize results for consistency before returning\n return files.map(normalize);\n } catch (error: any) {\n // Add more diagnostic info to the error\n const absoluteBaseDirForError = resolve(\n normalize(pattern).includes('**') ? normalize(pattern).split('**')[0] : dirname(normalize(pattern))\n );\n const relativePatternForError = relative(absoluteBaseDirForError, normalize(pattern)).replace(/\\\\/g, '/');\n throw new Error(\n `Error finding files for pattern \"${pattern}\" (using cwd: \"${absoluteBaseDirForError}\", globPattern: \"${relativePatternForError}\"): ${error.message}`\n );\n }\n};\n\nexport const readMdxFile = async (path: string) => {\n const { data } = matter.read(path);\n const { markdown, ...frontmatter } = data;\n return { ...frontmatter, markdown };\n};\n\nexport const searchFilesForId = async (files: string[], id: string, version?: string) => {\n // Escape the id to avoid regex issues\n const escapedId = id.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const idRegex = new RegExp(`^id:\\\\s*(['\"]|>-)?\\\\s*${escapedId}['\"]?\\\\s*$`, 'm');\n\n const versionRegex = new RegExp(`^version:\\\\s*['\"]?${version}['\"]?\\\\s*$`, 'm');\n\n const matches = files.map((file) => {\n const content = fsSync.readFileSync(file, 'utf-8');\n const hasIdMatch = content.match(idRegex);\n\n // Check version if provided\n if (version && !content.match(versionRegex)) {\n return undefined;\n }\n\n if (hasIdMatch) {\n return file;\n }\n });\n\n return matches.filter(Boolean).filter((file) => file !== undefined);\n};\n\n/**\n * Function to copy a directory from source to target, uses a tmp directory\n * @param catalogDir\n * @param source\n * @param target\n * @param filter\n */\nexport const copyDir = async (catalogDir: string, source: string, target: string, filter?: CopyFilterAsync | CopyFilterSync) => {\n const tmpDirectory = join(catalogDir, 'tmp');\n fsSync.mkdirSync(tmpDirectory, { recursive: true });\n\n // Copy everything over\n await copy(source, tmpDirectory, {\n overwrite: true,\n filter,\n });\n\n await copy(tmpDirectory, target, {\n overwrite: true,\n filter,\n });\n\n // Remove the tmp directory\n fsSync.rmSync(tmpDirectory, { recursive: true });\n};\n\n// Makes sure values in sends/recieves are unique\nexport const uniqueVersions = (messages: { id: string; version: string }[]): { id: string; version: string }[] => {\n const uniqueSet = new Set();\n\n return messages.filter((message) => {\n const key = `${message.id}-${message.version}`;\n if (!uniqueSet.has(key)) {\n uniqueSet.add(key);\n return true;\n }\n return false;\n });\n};\n","import { dirname, join } from 'path';\nimport { copyDir, findFileById, getFiles, searchFilesForId, versionExists } from './utils';\nimport matter from 'gray-matter';\nimport fs from 'node:fs/promises';\nimport fsSync from 'node:fs';\nimport { Message, Service, CustomDoc } from '../types';\nimport { satisfies } from 'semver';\nimport { lock, unlock } from 'proper-lockfile';\nimport { basename } from 'node:path';\n\ntype Resource = Service | Message | CustomDoc;\n\nexport const versionResource = async (catalogDir: string, id: string) => {\n // Find all the events in the directory\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n const matchedFiles = await searchFilesForId(files, id);\n\n if (matchedFiles.length === 0) {\n throw new Error(`No resource found with id: ${id}`);\n }\n\n // Event that is in the route of the project\n const file = matchedFiles[0];\n const sourceDirectory = dirname(file).replace(/\\/versioned?\\/[^/]+\\//, '/');\n const { data: { version = '0.0.1' } = {} } = matter.read(file);\n const targetDirectory = getVersionedDirectory(sourceDirectory, version);\n\n fsSync.mkdirSync(targetDirectory, { recursive: true });\n\n const ignoreListToCopy = ['events', 'commands', 'queries', 'versioned'];\n\n // Copy the event to the versioned directory\n await copyDir(catalogDir, sourceDirectory, targetDirectory, (src) => {\n // get the folder name\n const folderName = basename(src);\n\n if (ignoreListToCopy.includes(folderName)) {\n return false;\n }\n return true;\n });\n\n // Remove all the files in the root of the resource as they have now been versioned\n await fs.readdir(sourceDirectory).then(async (resourceFiles) => {\n await Promise.all(\n resourceFiles.map(async (file) => {\n // Dont remove anything in the ignore list\n if (ignoreListToCopy.includes(file)) {\n return;\n }\n if (file !== 'versioned') {\n fsSync.rmSync(join(sourceDirectory, file), { recursive: true });\n }\n })\n );\n });\n};\n\nexport const writeResource = async (\n catalogDir: string,\n resource: Resource,\n options: { path?: string; type: string; override?: boolean; versionExistingContent?: boolean; format?: 'md' | 'mdx' } = {\n path: '',\n type: '',\n override: false,\n versionExistingContent: false,\n format: 'mdx',\n }\n) => {\n const path = options.path || `/${resource.id}`;\n const fullPath = join(catalogDir, path);\n const format = options.format || 'mdx';\n\n // Create directory if it doesn't exist\n fsSync.mkdirSync(fullPath, { recursive: true });\n\n // Create or get lock file path\n const lockPath = join(fullPath, `index.${format}`);\n\n // Ensure the file exists before attempting to lock it\n if (!fsSync.existsSync(lockPath)) {\n fsSync.writeFileSync(lockPath, '');\n }\n\n try {\n // Acquire lock with retry\n await lock(lockPath, {\n retries: 5,\n stale: 10000, // 10 seconds\n });\n\n const exists = await versionExists(catalogDir, resource.id, resource.version);\n\n if (exists && !options.override) {\n throw new Error(`Failed to write ${resource.id} (${options.type}) as the version ${resource.version} already exists`);\n }\n\n const { markdown, ...frontmatter } = resource;\n\n if (options.versionExistingContent && !exists) {\n const currentResource = await getResource(catalogDir, resource.id);\n\n if (currentResource) {\n if (satisfies(resource.version, `>${currentResource.version}`)) {\n await versionResource(catalogDir, resource.id);\n } else {\n throw new Error(`New version ${resource.version} is not greater than current version ${currentResource.version}`);\n }\n }\n }\n\n const document = matter.stringify(markdown.trim(), frontmatter);\n fsSync.writeFileSync(lockPath, document);\n } finally {\n // Always release the lock\n await unlock(lockPath).catch(() => {});\n }\n};\n\nexport const getResource = async (\n catalogDir: string,\n id?: string,\n version?: string,\n options?: { type: string; attachSchema?: boolean },\n filePath?: string\n): Promise<Resource | undefined> => {\n const attachSchema = options?.attachSchema || false;\n const file = filePath || (id ? await findFileById(catalogDir, id, version) : undefined);\n if (!file || !fsSync.existsSync(file)) return;\n\n const { data, content } = matter.read(file);\n\n if (attachSchema && data?.schemaPath) {\n const resourceDirectory = dirname(file);\n const pathToSchema = join(resourceDirectory, data.schemaPath);\n if (fsSync.existsSync(pathToSchema)) {\n const schema = fsSync.readFileSync(pathToSchema, 'utf8');\n // Try to parse the schema\n try {\n data.schema = JSON.parse(schema);\n } catch (error) {\n data.schema = schema;\n }\n }\n }\n\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n};\n\nexport const getResourcePath = async (catalogDir: string, id: string, version?: string) => {\n const file = await findFileById(catalogDir, id, version);\n if (!file) return;\n\n return {\n fullPath: file,\n relativePath: file.replace(catalogDir, ''),\n directory: dirname(file.replace(catalogDir, '')),\n };\n};\n\nexport const toResource = async (catalogDir: string, rawContents: string) => {\n const { data, content } = matter(rawContents);\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n};\n\nexport const getResources = async (\n catalogDir: string,\n {\n type,\n latestOnly = false,\n ignore = [],\n pattern = '',\n attachSchema = false,\n }: { type: string; pattern?: string; latestOnly?: boolean; ignore?: string[]; attachSchema?: boolean }\n): Promise<Resource[] | undefined> => {\n const ignoreList = latestOnly ? `**/versioned/**` : '';\n const filePattern = pattern || `${catalogDir}/**/${type}/**/index.{md,mdx}`;\n const files = await getFiles(filePattern, [ignoreList, ...ignore]);\n\n if (files.length === 0) return;\n\n return files.map((file) => {\n const { data, content } = matter.read(file);\n\n // Attach the schema if the attachSchema option is set to true\n if (attachSchema && data?.schemaPath) {\n const resourceDirectory = dirname(file);\n const pathToSchema = join(resourceDirectory, data.schemaPath);\n if (fsSync.existsSync(pathToSchema)) {\n const schema = fsSync.readFileSync(pathToSchema, 'utf8');\n // Try to parse the schema\n try {\n data.schema = JSON.parse(schema);\n } catch (error) {\n data.schema = schema;\n }\n }\n }\n return {\n ...data,\n markdown: content.trim(),\n } as Resource;\n });\n};\n\nexport const rmResourceById = async (\n catalogDir: string,\n id: string,\n version?: string,\n options?: { type: string; persistFiles?: boolean }\n) => {\n const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);\n\n const matchedFiles = await searchFilesForId(files, id, version);\n\n if (matchedFiles.length === 0) {\n throw new Error(`No ${options?.type || 'resource'} found with id: ${id}`);\n }\n\n if (options?.persistFiles) {\n await Promise.all(\n matchedFiles.map(async (file) => {\n await fs.rm(file, { recursive: true });\n // Verify file is actually removed\n await waitForFileRemoval(file);\n })\n );\n } else {\n await Promise.all(\n matchedFiles.map(async (file) => {\n const directory = dirname(file);\n await fs.rm(directory, { recursive: true, force: true });\n // Verify directory is actually removed\n await waitForFileRemoval(directory);\n })\n );\n }\n};\n\n// Helper function to ensure file/directory is completely removed\nconst waitForFileRemoval = async (path: string, maxRetries: number = 50, delay: number = 10): Promise<void> => {\n for (let i = 0; i < maxRetries; i++) {\n try {\n await fs.access(path);\n // If access succeeds, file still exists, wait and retry\n await new Promise((resolve) => setTimeout(resolve, delay));\n } catch (error) {\n // If access fails, file is removed\n return;\n }\n }\n // If we reach here, file still exists after all retries\n throw new Error(`File/directory ${path} was not removed after ${maxRetries} attempts`);\n};\n\nexport const addFileToResource = async (\n catalogDir: string,\n id: string,\n file: { content: string; fileName: string },\n version?: string\n) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory to write file to');\n\n let fileContent = file.content.trim();\n\n try {\n const json = JSON.parse(fileContent);\n fileContent = JSON.stringify(json, null, 2);\n } catch (error) {\n // Just silently fail if the file is not valid JSON\n // Write it as it is\n }\n\n fsSync.writeFileSync(join(dirname(pathToResource), file.fileName), fileContent);\n};\n\nexport const getFileFromResource = async (catalogDir: string, id: string, file: { fileName: string }, version?: string) => {\n const pathToResource = await findFileById(catalogDir, id, version);\n\n if (!pathToResource) throw new Error('Cannot find directory of resource');\n\n const exists = await fs\n .access(join(dirname(pathToResource), file.fileName))\n .then(() => true)\n .catch(() => false);\n if (!exists) throw new Error(`File ${file.fileName} does not exist in resource ${id} v(${version})`);\n\n return fsSync.readFileSync(join(dirname(pathToResource), file.fileName), 'utf-8');\n};\nexport const getVersionedDirectory = (sourceDirectory: string, version: any): string => {\n return join(sourceDirectory, 'versioned', version);\n};\n\nexport const isLatestVersion = async (catalogDir: string, id: string, version?: string) => {\n const resource = await getResource(catalogDir, id, version);\n if (!resource) return false;\n\n const pathToResource = await getResourcePath(catalogDir, id, version);\n\n return !pathToResource?.relativePath.replace(/\\\\/g, '/').includes('/versioned/');\n};\n"],"mappings":"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","names":["fs","join","match","dirname","join","matter","fsSync","satisfies","basename","dirname","file","join","matter","dirname","join","fsSync","resolve","join","join","fs"]}
|
package/dist/services.js
CHANGED
|
@@ -49,7 +49,7 @@ __export(services_exports, {
|
|
|
49
49
|
});
|
|
50
50
|
module.exports = __toCommonJS(services_exports);
|
|
51
51
|
var import_promises2 = __toESM(require("fs/promises"));
|
|
52
|
-
var
|
|
52
|
+
var import_node_path3 = require("path");
|
|
53
53
|
|
|
54
54
|
// src/internal/resources.ts
|
|
55
55
|
var import_path = require("path");
|
|
@@ -163,6 +163,7 @@ var import_promises = __toESM(require("fs/promises"));
|
|
|
163
163
|
var import_node_fs2 = __toESM(require("fs"));
|
|
164
164
|
var import_semver2 = require("semver");
|
|
165
165
|
var import_proper_lockfile = require("proper-lockfile");
|
|
166
|
+
var import_node_path2 = require("path");
|
|
166
167
|
var versionResource = async (catalogDir, id) => {
|
|
167
168
|
const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);
|
|
168
169
|
const matchedFiles = await searchFilesForId(files, id);
|
|
@@ -170,16 +171,24 @@ var versionResource = async (catalogDir, id) => {
|
|
|
170
171
|
throw new Error(`No resource found with id: ${id}`);
|
|
171
172
|
}
|
|
172
173
|
const file = matchedFiles[0];
|
|
173
|
-
const sourceDirectory = (0, import_path.dirname)(file);
|
|
174
|
+
const sourceDirectory = (0, import_path.dirname)(file).replace(/\/versioned?\/[^/]+\//, "/");
|
|
174
175
|
const { data: { version = "0.0.1" } = {} } = import_gray_matter2.default.read(file);
|
|
175
176
|
const targetDirectory = getVersionedDirectory(sourceDirectory, version);
|
|
176
177
|
import_node_fs2.default.mkdirSync(targetDirectory, { recursive: true });
|
|
178
|
+
const ignoreListToCopy = ["events", "commands", "queries", "versioned"];
|
|
177
179
|
await copyDir(catalogDir, sourceDirectory, targetDirectory, (src) => {
|
|
178
|
-
|
|
180
|
+
const folderName = (0, import_node_path2.basename)(src);
|
|
181
|
+
if (ignoreListToCopy.includes(folderName)) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
return true;
|
|
179
185
|
});
|
|
180
186
|
await import_promises.default.readdir(sourceDirectory).then(async (resourceFiles) => {
|
|
181
187
|
await Promise.all(
|
|
182
188
|
resourceFiles.map(async (file2) => {
|
|
189
|
+
if (ignoreListToCopy.includes(file2)) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
183
192
|
if (file2 !== "versioned") {
|
|
184
193
|
import_node_fs2.default.rmSync((0, import_path.join)(sourceDirectory, file2), { recursive: true });
|
|
185
194
|
}
|
|
@@ -387,12 +396,12 @@ var writeVersionedService = (directory) => async (service) => {
|
|
|
387
396
|
};
|
|
388
397
|
var writeServiceToDomain = (directory) => async (service, domain, options = { path: "", format: "mdx", override: false }) => {
|
|
389
398
|
let pathForService = domain.version && domain.version !== "latest" ? `/${domain.id}/versioned/${domain.version}/services` : `/${domain.id}/services`;
|
|
390
|
-
pathForService = (0,
|
|
399
|
+
pathForService = (0, import_node_path3.join)(pathForService, service.id);
|
|
391
400
|
await writeResource(directory, { ...service }, { ...options, path: pathForService, type: "service" });
|
|
392
401
|
};
|
|
393
402
|
var versionService = (directory) => async (id) => versionResource(directory, id);
|
|
394
403
|
var rmService = (directory) => async (path) => {
|
|
395
|
-
await import_promises2.default.rm((0,
|
|
404
|
+
await import_promises2.default.rm((0, import_node_path3.join)(directory, path), { recursive: true });
|
|
396
405
|
};
|
|
397
406
|
var rmServiceById = (directory) => async (id, version, persistFiles) => {
|
|
398
407
|
await rmResourceById(directory, id, version, { type: "service", persistFiles });
|
|
@@ -405,14 +414,21 @@ var getSpecificationFilesForService = (directory) => async (id, version) => {
|
|
|
405
414
|
let specs = [];
|
|
406
415
|
if (service.specifications) {
|
|
407
416
|
const serviceSpecifications = service.specifications;
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
417
|
+
let specificationFiles;
|
|
418
|
+
if (Array.isArray(serviceSpecifications)) {
|
|
419
|
+
specificationFiles = serviceSpecifications.map((spec) => ({ key: spec.type, path: spec.path }));
|
|
420
|
+
} else {
|
|
421
|
+
specificationFiles = Object.keys(serviceSpecifications).map((spec) => ({
|
|
422
|
+
key: spec,
|
|
423
|
+
path: serviceSpecifications[spec]
|
|
424
|
+
}));
|
|
425
|
+
}
|
|
426
|
+
const getSpecs = specificationFiles.map(async ({ key, path: fileName }) => {
|
|
411
427
|
if (!fileName) {
|
|
412
|
-
throw new Error(`Specification file name for ${
|
|
428
|
+
throw new Error(`Specification file name for ${fileName} is undefined`);
|
|
413
429
|
}
|
|
414
430
|
const rawFile = await getFileFromResource(directory, id, { fileName }, version);
|
|
415
|
-
return { key
|
|
431
|
+
return { key, content: rawFile, fileName, path: (0, import_node_path3.join)((0, import_node_path3.dirname)(filePathToService), fileName) };
|
|
416
432
|
});
|
|
417
433
|
specs = await Promise.all(getSpecs);
|
|
418
434
|
}
|
|
@@ -421,7 +437,7 @@ var getSpecificationFilesForService = (directory) => async (id, version) => {
|
|
|
421
437
|
var addMessageToService = (directory) => async (id, direction, event, version) => {
|
|
422
438
|
let service = await getService(directory)(id, version);
|
|
423
439
|
const servicePath = await getResourcePath(directory, id, version);
|
|
424
|
-
const extension = (0,
|
|
440
|
+
const extension = (0, import_node_path3.extname)(servicePath?.fullPath || "");
|
|
425
441
|
if (direction === "sends") {
|
|
426
442
|
if (service.sends === void 0) {
|
|
427
443
|
service.sends = [];
|
|
@@ -450,7 +466,7 @@ var addMessageToService = (directory) => async (id, direction, event, version) =
|
|
|
450
466
|
throw new Error(`Cannot find service ${id} in the catalog`);
|
|
451
467
|
}
|
|
452
468
|
const path = existingResource.split(/[\\/]+services/)[0];
|
|
453
|
-
const pathToResource = (0,
|
|
469
|
+
const pathToResource = (0, import_node_path3.join)(path, "services");
|
|
454
470
|
await rmServiceById(directory)(id, version);
|
|
455
471
|
await writeService(pathToResource)(service, { format: extension === ".md" ? "md" : "mdx" });
|
|
456
472
|
};
|
|
@@ -460,7 +476,7 @@ var serviceHasVersion = (directory) => async (id, version) => {
|
|
|
460
476
|
};
|
|
461
477
|
var isService = (directory) => async (path) => {
|
|
462
478
|
const service = await getServiceByPath(directory)(path);
|
|
463
|
-
const relativePath = (0,
|
|
479
|
+
const relativePath = (0, import_node_path3.relative)(directory, path);
|
|
464
480
|
const segments = relativePath.split(/[/\\]+/);
|
|
465
481
|
return !!service && segments.includes("services");
|
|
466
482
|
};
|
|
@@ -468,7 +484,7 @@ var toService = (directory) => async (file) => toResource(directory, file);
|
|
|
468
484
|
var addEntityToService = (directory) => async (id, entity, version) => {
|
|
469
485
|
let service = await getService(directory)(id, version);
|
|
470
486
|
const servicePath = await getResourcePath(directory, id, version);
|
|
471
|
-
const extension = (0,
|
|
487
|
+
const extension = (0, import_node_path3.extname)(servicePath?.fullPath || "");
|
|
472
488
|
if (service.entities === void 0) {
|
|
473
489
|
service.entities = [];
|
|
474
490
|
}
|
|
@@ -483,7 +499,7 @@ var addEntityToService = (directory) => async (id, entity, version) => {
|
|
|
483
499
|
throw new Error(`Cannot find service ${id} in the catalog`);
|
|
484
500
|
}
|
|
485
501
|
const path = existingResource.split(/[\\/]+services/)[0];
|
|
486
|
-
const pathToResource = (0,
|
|
502
|
+
const pathToResource = (0, import_node_path3.join)(path, "services");
|
|
487
503
|
await rmServiceById(directory)(id, version);
|
|
488
504
|
await writeService(pathToResource)(service, { format: extension === ".md" ? "md" : "mdx" });
|
|
489
505
|
};
|