@event-driven-io/emmett 0.43.0-beta.14 → 0.43.0-beta.16

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/cli.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.cjs","names":["CliCommand","EmmettError","isPluginConfig","Command"],"sources":["../src/commandLine/config.ts","../src/commandLine/plugins.ts","../src/cli.ts"],"sourcesContent":["import { Command as CliCommand } from 'commander';\n// eslint-disable-next-line no-restricted-imports\nimport { writeFileSync } from 'node:fs';\nimport { exit } from 'process';\n\nexport const sampleConfig = (plugins: string[] = ['emmett-expressjs']) => {\n const pluginsNames =\n plugins.length > 0\n ? `[\\n${plugins.map((p) => `\"${p}\"`).join(',\\n')} \\n]`\n : '[]';\n\n return `\nexport default {\n plugins: ${pluginsNames},\n};\n`;\n};\n\nexport const generateConfigFile = (\n configPath: string,\n collectionNames: string[],\n): void => {\n try {\n writeFileSync(configPath, sampleConfig(collectionNames), 'utf8');\n console.log(`Configuration file stored at: ${configPath}`);\n } catch (error) {\n console.error(`Error: Couldn't store config file: ${configPath}!`);\n console.error(error);\n process.exit(1);\n }\n};\n\nexport const configCommand = new CliCommand('config').description(\n 'Manage Pongo configuration',\n);\n\ntype SampleConfigOptions =\n | {\n plugin: string[];\n print?: boolean;\n }\n | {\n plugin: string[];\n generate?: boolean;\n file?: string;\n };\n\nconfigCommand\n .command('sample')\n .description('Generate or print sample configuration')\n .option(\n '-plg, --plugins <name>',\n 'Specify the plugin name',\n (value: string, previous: string[]) => {\n // Accumulate plugins names into an array (explicitly typing `previous` as `string[]`)\n return previous.concat([value]);\n },\n [] as string[],\n )\n .option(\n '-f, --file <path>',\n 'Path to configuration file with collection list',\n )\n .option('-g, --generate', 'Generate sample config file')\n .option('-p, --print', 'Print sample config file')\n .action((options: SampleConfigOptions) => {\n const plugins =\n options.plugin.length > 0\n ? options.plugin\n : ['@event-driven-io/emmett-expressjs'];\n\n if (!('print' in options) && !('generate' in options)) {\n console.error(\n 'Error: Please provide either:\\n--print param to print sample config or\\n--generate to generate sample config file',\n );\n exit(1);\n }\n\n if ('print' in options) {\n console.log(`${sampleConfig(plugins)}`);\n } else if ('generate' in options) {\n if (!options.file) {\n console.error(\n 'Error: You need to provide a config file through a --file',\n );\n exit(1);\n }\n\n generateConfigFile(options.file, plugins);\n }\n });\n","import type { Command as CliCommand } from 'commander';\nimport path from 'path';\nimport {\n isPluginConfig,\n type EmmettCliCommand,\n type EmmettCliPlugin,\n type EmmettPlugin,\n type EmmettPluginConfig,\n type EmmettPluginsConfig,\n type EmmettPluginType,\n} from '../config';\nimport { EmmettError } from '../errors';\nimport { sampleConfig } from './config';\n\nconst PluginsConfigImportError = {\n missingDefaultExport: `Error: Config should contain default export, e.g.\\n\\n${sampleConfig()}`,\n missingPluginsPropertyExport: `Error: Config should contain default export with plugins array, e.g.\\n\\n${sampleConfig()}`,\n wrongPluginStructure: `Error: Plugin config should be either string with plugin name or object with plugin name, e.g. { name: 'emmett-expressjs' }`,\n};\nexport const importPluginsConfig = async (options?: {\n configPath?: string | undefined;\n}): Promise<EmmettPluginsConfig | EmmettError> => {\n const configPath = path.join(\n process.cwd(),\n options?.configPath ?? './dist/emmett.config.js',\n );\n\n console.log('IMPORTING' + configPath);\n\n try {\n const imported = (await import(configPath)) as {\n default: Partial<EmmettPluginsConfig>;\n };\n\n if (!imported.default) {\n return new EmmettError(PluginsConfigImportError.missingDefaultExport);\n }\n\n if (!imported.default.plugins || !Array.isArray(imported.default.plugins)) {\n return new EmmettError(\n PluginsConfigImportError.missingPluginsPropertyExport,\n );\n }\n\n if (!imported.default.plugins.every(isPluginConfig)) {\n return new EmmettError(PluginsConfigImportError.wrongPluginStructure);\n }\n\n return { plugins: imported.default.plugins };\n } catch (error) {\n if (!options?.configPath) {\n console.warn('Didn`t find config file: ' + configPath, error);\n return { plugins: [] };\n }\n return new EmmettError(\n `Error: Couldn't load file:` + (error as Error).toString(),\n );\n }\n};\n\nexport const loadPlugins = async (options?: {\n pluginType?: EmmettPluginType;\n configPath?: string;\n}): Promise<EmmettPlugin[]> => {\n try {\n const pluginsConfig = await importPluginsConfig({\n configPath: options?.configPath,\n });\n\n if (pluginsConfig instanceof EmmettError) throw pluginsConfig;\n\n if (pluginsConfig.plugins.length === 0) {\n console.log(`No extensions specified in config ${options?.configPath}.`);\n return [];\n }\n\n const pluginsToLoad = filterPluginsByType(\n pluginsConfig.plugins,\n options?.pluginType,\n );\n\n const pluginsPromises = pluginsToLoad.map(async (pluginConfig) => {\n const importPath = getImportPath(pluginConfig, options?.pluginType);\n try {\n const plugin = (await import(importPath)) as { default: EmmettPlugin };\n\n console.info(`Loaded plugin: ${importPath}`);\n\n if (!plugin.default) {\n throw new Error(`Plugin: ${importPath} is missing default export`);\n }\n\n return plugin.default;\n } catch (error) {\n console.error(`Failed to load extension \"${importPath}\":`, error);\n return undefined;\n }\n });\n\n return (await Promise.all(pluginsPromises)).filter(\n (plugin) => plugin !== undefined,\n );\n } catch (error) {\n console.error(`Failed to load config ${options?.configPath}:`, error);\n return [];\n }\n};\n\nexport const registerCliPlugins = async (\n program: CliCommand,\n plugins: EmmettCliPlugin[],\n): Promise<void> => {\n const result: EmmettCliPlugin[] = [];\n\n for (const plugin of plugins) {\n const pluginName = plugin.name;\n\n if (!('registerCommands' in plugin)) {\n console.warn(`No registerCommands function found in ${pluginName}`);\n }\n await plugin.registerCommands(program as EmmettCliCommand);\n console.log(`Loaded extension: ${plugin.name}`);\n result.push(plugin);\n }\n};\n\nconst filterPluginsByType = (\n plugins: EmmettPluginConfig[],\n pluginType?: EmmettPluginType,\n): EmmettPluginConfig[] =>\n plugins.filter(\n (p) =>\n typeof p === 'string' ||\n (pluginType &&\n (p.register === undefined ||\n p.register.some((r) => r.pluginType === pluginType))),\n );\n\nconst getImportPath = (\n pluginConfig: EmmettPluginConfig,\n pluginType: EmmettPluginType | undefined,\n) => {\n if (typeof pluginConfig === 'string') {\n return pluginType ? `${pluginConfig}/${pluginType}` : pluginConfig;\n }\n\n const pluginSubpath =\n pluginConfig.register.find((r) => pluginType && r.pluginType === pluginType)\n ?.path ?? pluginType;\n\n return pluginSubpath\n ? `${pluginConfig.name}/${pluginSubpath}`\n : pluginConfig.name;\n};\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { loadPlugins, registerCliPlugins } from './commandLine';\n\nconst program = new Command();\n\nprogram\n .name('emmett')\n .description('CLI tool for Emmett')\n .option('--config <path>', 'Path to the configuration file');\n\n// Load extensions and parse CLI arguments\nconst initCLI = async () => {\n const configIndex = process.argv.indexOf('--config');\n\n const configPath =\n configIndex !== -1 && process.argv.length > configIndex + 1\n ? process.argv[configIndex + 1]\n : undefined;\n\n try {\n const plugins = await loadPlugins({\n pluginType: 'cli',\n configPath: configPath,\n });\n await registerCliPlugins(program, plugins);\n\n // Parse the CLI arguments\n program.parse(process.argv);\n } catch (err) {\n console.error(`Failed to load config from ${configPath}:`, err);\n }\n};\n\n//Initialize CLI and handle errors\ninitCLI().catch((err) => {\n console.error(`CLI initialization failed:`);\n console.error(err);\n});\n\nexport default program;\nexport * from './commandLine';\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.cjs","names":["CliCommand","EmmettError","isPluginConfig","Command"],"sources":["../src/commandLine/config.ts","../src/commandLine/plugins.ts","../src/cli.ts"],"sourcesContent":["import { Command as CliCommand } from 'commander';\n// eslint-disable-next-line no-restricted-imports\nimport { writeFileSync } from 'node:fs';\nimport { exit } from 'process';\n\nexport const sampleConfig = (plugins: string[] = ['emmett-expressjs']) => {\n const pluginsNames =\n plugins.length > 0\n ? `[\\n${plugins.map((p) => `\"${p}\"`).join(',\\n')} \\n]`\n : '[]';\n\n return `\nexport default {\n plugins: ${pluginsNames},\n};\n`;\n};\n\nexport const generateConfigFile = (\n configPath: string,\n collectionNames: string[],\n): void => {\n try {\n writeFileSync(configPath, sampleConfig(collectionNames), 'utf8');\n console.log(`Configuration file stored at: ${configPath}`);\n } catch (error) {\n console.error(`Error: Couldn't store config file: ${configPath}!`);\n console.error(error);\n process.exit(1);\n }\n};\n\nexport const configCommand = new CliCommand('config').description(\n 'Manage Pongo configuration',\n);\n\ntype SampleConfigOptions =\n | {\n plugin: string[];\n print?: boolean;\n }\n | {\n plugin: string[];\n generate?: boolean;\n file?: string;\n };\n\nconfigCommand\n .command('sample')\n .description('Generate or print sample configuration')\n .option(\n '-plg, --plugins <name>',\n 'Specify the plugin name',\n (value: string, previous: string[]) => {\n // Accumulate plugins names into an array (explicitly typing `previous` as `string[]`)\n return previous.concat([value]);\n },\n [] as string[],\n )\n .option(\n '-f, --file <path>',\n 'Path to configuration file with collection list',\n )\n .option('-g, --generate', 'Generate sample config file')\n .option('-p, --print', 'Print sample config file')\n .action((options: SampleConfigOptions) => {\n const plugins =\n options.plugin.length > 0\n ? options.plugin\n : ['@event-driven-io/emmett-expressjs'];\n\n if (!('print' in options) && !('generate' in options)) {\n console.error(\n 'Error: Please provide either:\\n--print param to print sample config or\\n--generate to generate sample config file',\n );\n exit(1);\n }\n\n if ('print' in options) {\n console.log(`${sampleConfig(plugins)}`);\n } else if ('generate' in options) {\n if (!options.file) {\n console.error(\n 'Error: You need to provide a config file through a --file',\n );\n exit(1);\n }\n\n generateConfigFile(options.file, plugins);\n }\n });\n","import type { Command as CliCommand } from 'commander';\nimport path from 'path';\nimport {\n isPluginConfig,\n type EmmettCliCommand,\n type EmmettCliPlugin,\n type EmmettPlugin,\n type EmmettPluginConfig,\n type EmmettPluginsConfig,\n type EmmettPluginType,\n} from '../config';\nimport { EmmettError } from '../errors';\nimport { sampleConfig } from './config';\n\nconst PluginsConfigImportError = {\n missingDefaultExport: `Error: Config should contain default export, e.g.\\n\\n${sampleConfig()}`,\n missingPluginsPropertyExport: `Error: Config should contain default export with plugins array, e.g.\\n\\n${sampleConfig()}`,\n wrongPluginStructure: `Error: Plugin config should be either string with plugin name or object with plugin name, e.g. { name: 'emmett-expressjs' }`,\n};\nexport const importPluginsConfig = async (options?: {\n configPath?: string | undefined;\n}): Promise<EmmettPluginsConfig | EmmettError> => {\n const configPath = path.join(\n process.cwd(),\n options?.configPath ?? './dist/emmett.config.js',\n );\n\n console.log('IMPORTING' + configPath);\n\n try {\n const imported = (await import(configPath)) as {\n default: Partial<EmmettPluginsConfig>;\n };\n\n if (!imported.default) {\n return new EmmettError(PluginsConfigImportError.missingDefaultExport);\n }\n\n if (!imported.default.plugins || !Array.isArray(imported.default.plugins)) {\n return new EmmettError(\n PluginsConfigImportError.missingPluginsPropertyExport,\n );\n }\n\n if (!imported.default.plugins.every(isPluginConfig)) {\n return new EmmettError(PluginsConfigImportError.wrongPluginStructure);\n }\n\n return { plugins: imported.default.plugins };\n } catch (error) {\n if (!options?.configPath) {\n console.warn('Didn`t find config file: ' + configPath, error);\n return { plugins: [] };\n }\n return new EmmettError(\n `Error: Couldn't load file:` + (error as Error).toString(),\n );\n }\n};\n\nexport const loadPlugins = async (options?: {\n pluginType?: EmmettPluginType;\n configPath?: string;\n}): Promise<EmmettPlugin[]> => {\n try {\n const pluginsConfig = await importPluginsConfig({\n configPath: options?.configPath,\n });\n\n if (pluginsConfig instanceof EmmettError) throw pluginsConfig;\n\n if (pluginsConfig.plugins.length === 0) {\n console.log(`No extensions specified in config ${options?.configPath}.`);\n return [];\n }\n\n const pluginsToLoad = filterPluginsByType(\n pluginsConfig.plugins,\n options?.pluginType,\n );\n\n const pluginsPromises = pluginsToLoad.map(async (pluginConfig) => {\n const importPath = getImportPath(pluginConfig, options?.pluginType);\n try {\n const plugin = (await import(importPath)) as { default: EmmettPlugin };\n\n console.info(`Loaded plugin: ${importPath}`);\n\n if (!plugin.default) {\n throw new Error(`Plugin: ${importPath} is missing default export`);\n }\n\n return plugin.default;\n } catch (error) {\n console.error(`Failed to load extension \"${importPath}\":`, error);\n return undefined;\n }\n });\n\n return (await Promise.all(pluginsPromises)).filter(\n (plugin) => plugin !== undefined,\n );\n } catch (error) {\n console.error(`Failed to load config ${options?.configPath}:`, error);\n return [];\n }\n};\n\nexport const registerCliPlugins = async (\n program: CliCommand,\n plugins: EmmettCliPlugin[],\n): Promise<void> => {\n const result: EmmettCliPlugin[] = [];\n\n for (const plugin of plugins) {\n const pluginName = plugin.name;\n\n if (!('registerCommands' in plugin)) {\n console.warn(`No registerCommands function found in ${pluginName}`);\n }\n await plugin.registerCommands(program as EmmettCliCommand);\n console.log(`Loaded extension: ${plugin.name}`);\n result.push(plugin);\n }\n};\n\nconst filterPluginsByType = (\n plugins: EmmettPluginConfig[],\n pluginType?: EmmettPluginType,\n): EmmettPluginConfig[] =>\n plugins.filter(\n (p) =>\n typeof p === 'string' ||\n (pluginType &&\n (p.register === undefined ||\n p.register.some((r) => r.pluginType === pluginType))),\n );\n\nconst getImportPath = (\n pluginConfig: EmmettPluginConfig,\n pluginType: EmmettPluginType | undefined,\n) => {\n if (typeof pluginConfig === 'string') {\n return pluginType ? `${pluginConfig}/${pluginType}` : pluginConfig;\n }\n\n const pluginSubpath =\n pluginConfig.register.find((r) => pluginType && r.pluginType === pluginType)\n ?.path ?? pluginType;\n\n return pluginSubpath\n ? `${pluginConfig.name}/${pluginSubpath}`\n : pluginConfig.name;\n};\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { loadPlugins, registerCliPlugins } from './commandLine';\n\nconst program = new Command();\n\nprogram\n .name('emmett')\n .description('CLI tool for Emmett')\n .option('--config <path>', 'Path to the configuration file');\n\n// Load extensions and parse CLI arguments\nconst initCLI = async () => {\n const configIndex = process.argv.indexOf('--config');\n\n const configPath =\n configIndex !== -1 && process.argv.length > configIndex + 1\n ? process.argv[configIndex + 1]\n : undefined;\n\n try {\n const plugins = await loadPlugins({\n pluginType: 'cli',\n configPath: configPath,\n });\n await registerCliPlugins(program, plugins);\n\n // Parse the CLI arguments\n program.parse(process.argv);\n } catch (err) {\n console.error(`Failed to load config from ${configPath}:`, err);\n }\n};\n\n//Initialize CLI and handle errors\ninitCLI().catch((err) => {\n console.error(`CLI initialization failed:`);\n console.error(err);\n});\n\nexport default program;\nexport * from './commandLine';\n"],"mappings":"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"}
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":["CliCommand"],"sources":["../src/commandLine/config.ts","../src/commandLine/plugins.ts","../src/cli.ts"],"sourcesContent":["import { Command as CliCommand } from 'commander';\n// eslint-disable-next-line no-restricted-imports\nimport { writeFileSync } from 'node:fs';\nimport { exit } from 'process';\n\nexport const sampleConfig = (plugins: string[] = ['emmett-expressjs']) => {\n const pluginsNames =\n plugins.length > 0\n ? `[\\n${plugins.map((p) => `\"${p}\"`).join(',\\n')} \\n]`\n : '[]';\n\n return `\nexport default {\n plugins: ${pluginsNames},\n};\n`;\n};\n\nexport const generateConfigFile = (\n configPath: string,\n collectionNames: string[],\n): void => {\n try {\n writeFileSync(configPath, sampleConfig(collectionNames), 'utf8');\n console.log(`Configuration file stored at: ${configPath}`);\n } catch (error) {\n console.error(`Error: Couldn't store config file: ${configPath}!`);\n console.error(error);\n process.exit(1);\n }\n};\n\nexport const configCommand = new CliCommand('config').description(\n 'Manage Pongo configuration',\n);\n\ntype SampleConfigOptions =\n | {\n plugin: string[];\n print?: boolean;\n }\n | {\n plugin: string[];\n generate?: boolean;\n file?: string;\n };\n\nconfigCommand\n .command('sample')\n .description('Generate or print sample configuration')\n .option(\n '-plg, --plugins <name>',\n 'Specify the plugin name',\n (value: string, previous: string[]) => {\n // Accumulate plugins names into an array (explicitly typing `previous` as `string[]`)\n return previous.concat([value]);\n },\n [] as string[],\n )\n .option(\n '-f, --file <path>',\n 'Path to configuration file with collection list',\n )\n .option('-g, --generate', 'Generate sample config file')\n .option('-p, --print', 'Print sample config file')\n .action((options: SampleConfigOptions) => {\n const plugins =\n options.plugin.length > 0\n ? options.plugin\n : ['@event-driven-io/emmett-expressjs'];\n\n if (!('print' in options) && !('generate' in options)) {\n console.error(\n 'Error: Please provide either:\\n--print param to print sample config or\\n--generate to generate sample config file',\n );\n exit(1);\n }\n\n if ('print' in options) {\n console.log(`${sampleConfig(plugins)}`);\n } else if ('generate' in options) {\n if (!options.file) {\n console.error(\n 'Error: You need to provide a config file through a --file',\n );\n exit(1);\n }\n\n generateConfigFile(options.file, plugins);\n }\n });\n","import type { Command as CliCommand } from 'commander';\nimport path from 'path';\nimport {\n isPluginConfig,\n type EmmettCliCommand,\n type EmmettCliPlugin,\n type EmmettPlugin,\n type EmmettPluginConfig,\n type EmmettPluginsConfig,\n type EmmettPluginType,\n} from '../config';\nimport { EmmettError } from '../errors';\nimport { sampleConfig } from './config';\n\nconst PluginsConfigImportError = {\n missingDefaultExport: `Error: Config should contain default export, e.g.\\n\\n${sampleConfig()}`,\n missingPluginsPropertyExport: `Error: Config should contain default export with plugins array, e.g.\\n\\n${sampleConfig()}`,\n wrongPluginStructure: `Error: Plugin config should be either string with plugin name or object with plugin name, e.g. { name: 'emmett-expressjs' }`,\n};\nexport const importPluginsConfig = async (options?: {\n configPath?: string | undefined;\n}): Promise<EmmettPluginsConfig | EmmettError> => {\n const configPath = path.join(\n process.cwd(),\n options?.configPath ?? './dist/emmett.config.js',\n );\n\n console.log('IMPORTING' + configPath);\n\n try {\n const imported = (await import(configPath)) as {\n default: Partial<EmmettPluginsConfig>;\n };\n\n if (!imported.default) {\n return new EmmettError(PluginsConfigImportError.missingDefaultExport);\n }\n\n if (!imported.default.plugins || !Array.isArray(imported.default.plugins)) {\n return new EmmettError(\n PluginsConfigImportError.missingPluginsPropertyExport,\n );\n }\n\n if (!imported.default.plugins.every(isPluginConfig)) {\n return new EmmettError(PluginsConfigImportError.wrongPluginStructure);\n }\n\n return { plugins: imported.default.plugins };\n } catch (error) {\n if (!options?.configPath) {\n console.warn('Didn`t find config file: ' + configPath, error);\n return { plugins: [] };\n }\n return new EmmettError(\n `Error: Couldn't load file:` + (error as Error).toString(),\n );\n }\n};\n\nexport const loadPlugins = async (options?: {\n pluginType?: EmmettPluginType;\n configPath?: string;\n}): Promise<EmmettPlugin[]> => {\n try {\n const pluginsConfig = await importPluginsConfig({\n configPath: options?.configPath,\n });\n\n if (pluginsConfig instanceof EmmettError) throw pluginsConfig;\n\n if (pluginsConfig.plugins.length === 0) {\n console.log(`No extensions specified in config ${options?.configPath}.`);\n return [];\n }\n\n const pluginsToLoad = filterPluginsByType(\n pluginsConfig.plugins,\n options?.pluginType,\n );\n\n const pluginsPromises = pluginsToLoad.map(async (pluginConfig) => {\n const importPath = getImportPath(pluginConfig, options?.pluginType);\n try {\n const plugin = (await import(importPath)) as { default: EmmettPlugin };\n\n console.info(`Loaded plugin: ${importPath}`);\n\n if (!plugin.default) {\n throw new Error(`Plugin: ${importPath} is missing default export`);\n }\n\n return plugin.default;\n } catch (error) {\n console.error(`Failed to load extension \"${importPath}\":`, error);\n return undefined;\n }\n });\n\n return (await Promise.all(pluginsPromises)).filter(\n (plugin) => plugin !== undefined,\n );\n } catch (error) {\n console.error(`Failed to load config ${options?.configPath}:`, error);\n return [];\n }\n};\n\nexport const registerCliPlugins = async (\n program: CliCommand,\n plugins: EmmettCliPlugin[],\n): Promise<void> => {\n const result: EmmettCliPlugin[] = [];\n\n for (const plugin of plugins) {\n const pluginName = plugin.name;\n\n if (!('registerCommands' in plugin)) {\n console.warn(`No registerCommands function found in ${pluginName}`);\n }\n await plugin.registerCommands(program as EmmettCliCommand);\n console.log(`Loaded extension: ${plugin.name}`);\n result.push(plugin);\n }\n};\n\nconst filterPluginsByType = (\n plugins: EmmettPluginConfig[],\n pluginType?: EmmettPluginType,\n): EmmettPluginConfig[] =>\n plugins.filter(\n (p) =>\n typeof p === 'string' ||\n (pluginType &&\n (p.register === undefined ||\n p.register.some((r) => r.pluginType === pluginType))),\n );\n\nconst getImportPath = (\n pluginConfig: EmmettPluginConfig,\n pluginType: EmmettPluginType | undefined,\n) => {\n if (typeof pluginConfig === 'string') {\n return pluginType ? `${pluginConfig}/${pluginType}` : pluginConfig;\n }\n\n const pluginSubpath =\n pluginConfig.register.find((r) => pluginType && r.pluginType === pluginType)\n ?.path ?? pluginType;\n\n return pluginSubpath\n ? `${pluginConfig.name}/${pluginSubpath}`\n : pluginConfig.name;\n};\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { loadPlugins, registerCliPlugins } from './commandLine';\n\nconst program = new Command();\n\nprogram\n .name('emmett')\n .description('CLI tool for Emmett')\n .option('--config <path>', 'Path to the configuration file');\n\n// Load extensions and parse CLI arguments\nconst initCLI = async () => {\n const configIndex = process.argv.indexOf('--config');\n\n const configPath =\n configIndex !== -1 && process.argv.length > configIndex + 1\n ? process.argv[configIndex + 1]\n : undefined;\n\n try {\n const plugins = await loadPlugins({\n pluginType: 'cli',\n configPath: configPath,\n });\n await registerCliPlugins(program, plugins);\n\n // Parse the CLI arguments\n program.parse(process.argv);\n } catch (err) {\n console.error(`Failed to load config from ${configPath}:`, err);\n }\n};\n\n//Initialize CLI and handle errors\ninitCLI().catch((err) => {\n console.error(`CLI initialization failed:`);\n console.error(err);\n});\n\nexport default program;\nexport * from './commandLine';\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":["CliCommand"],"sources":["../src/commandLine/config.ts","../src/commandLine/plugins.ts","../src/cli.ts"],"sourcesContent":["import { Command as CliCommand } from 'commander';\n// eslint-disable-next-line no-restricted-imports\nimport { writeFileSync } from 'node:fs';\nimport { exit } from 'process';\n\nexport const sampleConfig = (plugins: string[] = ['emmett-expressjs']) => {\n const pluginsNames =\n plugins.length > 0\n ? `[\\n${plugins.map((p) => `\"${p}\"`).join(',\\n')} \\n]`\n : '[]';\n\n return `\nexport default {\n plugins: ${pluginsNames},\n};\n`;\n};\n\nexport const generateConfigFile = (\n configPath: string,\n collectionNames: string[],\n): void => {\n try {\n writeFileSync(configPath, sampleConfig(collectionNames), 'utf8');\n console.log(`Configuration file stored at: ${configPath}`);\n } catch (error) {\n console.error(`Error: Couldn't store config file: ${configPath}!`);\n console.error(error);\n process.exit(1);\n }\n};\n\nexport const configCommand = new CliCommand('config').description(\n 'Manage Pongo configuration',\n);\n\ntype SampleConfigOptions =\n | {\n plugin: string[];\n print?: boolean;\n }\n | {\n plugin: string[];\n generate?: boolean;\n file?: string;\n };\n\nconfigCommand\n .command('sample')\n .description('Generate or print sample configuration')\n .option(\n '-plg, --plugins <name>',\n 'Specify the plugin name',\n (value: string, previous: string[]) => {\n // Accumulate plugins names into an array (explicitly typing `previous` as `string[]`)\n return previous.concat([value]);\n },\n [] as string[],\n )\n .option(\n '-f, --file <path>',\n 'Path to configuration file with collection list',\n )\n .option('-g, --generate', 'Generate sample config file')\n .option('-p, --print', 'Print sample config file')\n .action((options: SampleConfigOptions) => {\n const plugins =\n options.plugin.length > 0\n ? options.plugin\n : ['@event-driven-io/emmett-expressjs'];\n\n if (!('print' in options) && !('generate' in options)) {\n console.error(\n 'Error: Please provide either:\\n--print param to print sample config or\\n--generate to generate sample config file',\n );\n exit(1);\n }\n\n if ('print' in options) {\n console.log(`${sampleConfig(plugins)}`);\n } else if ('generate' in options) {\n if (!options.file) {\n console.error(\n 'Error: You need to provide a config file through a --file',\n );\n exit(1);\n }\n\n generateConfigFile(options.file, plugins);\n }\n });\n","import type { Command as CliCommand } from 'commander';\nimport path from 'path';\nimport {\n isPluginConfig,\n type EmmettCliCommand,\n type EmmettCliPlugin,\n type EmmettPlugin,\n type EmmettPluginConfig,\n type EmmettPluginsConfig,\n type EmmettPluginType,\n} from '../config';\nimport { EmmettError } from '../errors';\nimport { sampleConfig } from './config';\n\nconst PluginsConfigImportError = {\n missingDefaultExport: `Error: Config should contain default export, e.g.\\n\\n${sampleConfig()}`,\n missingPluginsPropertyExport: `Error: Config should contain default export with plugins array, e.g.\\n\\n${sampleConfig()}`,\n wrongPluginStructure: `Error: Plugin config should be either string with plugin name or object with plugin name, e.g. { name: 'emmett-expressjs' }`,\n};\nexport const importPluginsConfig = async (options?: {\n configPath?: string | undefined;\n}): Promise<EmmettPluginsConfig | EmmettError> => {\n const configPath = path.join(\n process.cwd(),\n options?.configPath ?? './dist/emmett.config.js',\n );\n\n console.log('IMPORTING' + configPath);\n\n try {\n const imported = (await import(configPath)) as {\n default: Partial<EmmettPluginsConfig>;\n };\n\n if (!imported.default) {\n return new EmmettError(PluginsConfigImportError.missingDefaultExport);\n }\n\n if (!imported.default.plugins || !Array.isArray(imported.default.plugins)) {\n return new EmmettError(\n PluginsConfigImportError.missingPluginsPropertyExport,\n );\n }\n\n if (!imported.default.plugins.every(isPluginConfig)) {\n return new EmmettError(PluginsConfigImportError.wrongPluginStructure);\n }\n\n return { plugins: imported.default.plugins };\n } catch (error) {\n if (!options?.configPath) {\n console.warn('Didn`t find config file: ' + configPath, error);\n return { plugins: [] };\n }\n return new EmmettError(\n `Error: Couldn't load file:` + (error as Error).toString(),\n );\n }\n};\n\nexport const loadPlugins = async (options?: {\n pluginType?: EmmettPluginType;\n configPath?: string;\n}): Promise<EmmettPlugin[]> => {\n try {\n const pluginsConfig = await importPluginsConfig({\n configPath: options?.configPath,\n });\n\n if (pluginsConfig instanceof EmmettError) throw pluginsConfig;\n\n if (pluginsConfig.plugins.length === 0) {\n console.log(`No extensions specified in config ${options?.configPath}.`);\n return [];\n }\n\n const pluginsToLoad = filterPluginsByType(\n pluginsConfig.plugins,\n options?.pluginType,\n );\n\n const pluginsPromises = pluginsToLoad.map(async (pluginConfig) => {\n const importPath = getImportPath(pluginConfig, options?.pluginType);\n try {\n const plugin = (await import(importPath)) as { default: EmmettPlugin };\n\n console.info(`Loaded plugin: ${importPath}`);\n\n if (!plugin.default) {\n throw new Error(`Plugin: ${importPath} is missing default export`);\n }\n\n return plugin.default;\n } catch (error) {\n console.error(`Failed to load extension \"${importPath}\":`, error);\n return undefined;\n }\n });\n\n return (await Promise.all(pluginsPromises)).filter(\n (plugin) => plugin !== undefined,\n );\n } catch (error) {\n console.error(`Failed to load config ${options?.configPath}:`, error);\n return [];\n }\n};\n\nexport const registerCliPlugins = async (\n program: CliCommand,\n plugins: EmmettCliPlugin[],\n): Promise<void> => {\n const result: EmmettCliPlugin[] = [];\n\n for (const plugin of plugins) {\n const pluginName = plugin.name;\n\n if (!('registerCommands' in plugin)) {\n console.warn(`No registerCommands function found in ${pluginName}`);\n }\n await plugin.registerCommands(program as EmmettCliCommand);\n console.log(`Loaded extension: ${plugin.name}`);\n result.push(plugin);\n }\n};\n\nconst filterPluginsByType = (\n plugins: EmmettPluginConfig[],\n pluginType?: EmmettPluginType,\n): EmmettPluginConfig[] =>\n plugins.filter(\n (p) =>\n typeof p === 'string' ||\n (pluginType &&\n (p.register === undefined ||\n p.register.some((r) => r.pluginType === pluginType))),\n );\n\nconst getImportPath = (\n pluginConfig: EmmettPluginConfig,\n pluginType: EmmettPluginType | undefined,\n) => {\n if (typeof pluginConfig === 'string') {\n return pluginType ? `${pluginConfig}/${pluginType}` : pluginConfig;\n }\n\n const pluginSubpath =\n pluginConfig.register.find((r) => pluginType && r.pluginType === pluginType)\n ?.path ?? pluginType;\n\n return pluginSubpath\n ? `${pluginConfig.name}/${pluginSubpath}`\n : pluginConfig.name;\n};\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { loadPlugins, registerCliPlugins } from './commandLine';\n\nconst program = new Command();\n\nprogram\n .name('emmett')\n .description('CLI tool for Emmett')\n .option('--config <path>', 'Path to the configuration file');\n\n// Load extensions and parse CLI arguments\nconst initCLI = async () => {\n const configIndex = process.argv.indexOf('--config');\n\n const configPath =\n configIndex !== -1 && process.argv.length > configIndex + 1\n ? process.argv[configIndex + 1]\n : undefined;\n\n try {\n const plugins = await loadPlugins({\n pluginType: 'cli',\n configPath: configPath,\n });\n await registerCliPlugins(program, plugins);\n\n // Parse the CLI arguments\n program.parse(process.argv);\n } catch (err) {\n console.error(`Failed to load config from ${configPath}:`, err);\n }\n};\n\n//Initialize CLI and handle errors\ninitCLI().catch((err) => {\n console.error(`CLI initialization failed:`);\n console.error(err);\n});\n\nexport default program;\nexport * from './commandLine';\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -3,6 +3,7 @@ const require_plugins = require('./plugins-DB9xe8AV.cjs');
3
3
  let uuid = require("uuid");
4
4
  let async_retry = require("async-retry");
5
5
  async_retry = require_plugins.__toESM(async_retry, 1);
6
+ let _event_driven_io_almanac = require("@event-driven-io/almanac");
6
7
 
7
8
  //#region src/eventStore/afterCommit/afterEventStoreCommitHandler.ts
8
9
  async function tryPublishMessagesAfterCommit(messages, options, context) {
@@ -1070,14 +1071,27 @@ const reactor = (options) => {
1070
1071
  canHandle,
1071
1072
  init,
1072
1073
  start: async (startOptions) => {
1073
- if (isActive) return;
1074
+ if (isActive) {
1075
+ console.log(`Processor ${processorId} with instance id ${instanceId} is already active. Start request ignored.`);
1076
+ return;
1077
+ }
1078
+ console.log(`Starting processor ${processorId} with instance id ${instanceId}`);
1074
1079
  await init(startOptions);
1075
1080
  isActive = true;
1076
1081
  closeSignal = onShutdown(() => close(startOptions));
1077
- if (lastCheckpoint !== null) return { lastCheckpoint };
1082
+ if (lastCheckpoint !== null) {
1083
+ console.log(`Processor ${processorId} started with instance id ${instanceId}, checkpoint: ${JSONSerializer.serialize(lastCheckpoint)}`);
1084
+ return { lastCheckpoint };
1085
+ }
1078
1086
  return await processingScope(async (context) => {
1079
- if (hooks.onStart) await hooks.onStart(context);
1080
- if (startFrom && startFrom !== "CURRENT") return startFrom;
1087
+ if (hooks.onStart) {
1088
+ console.log(`Executing onStart hook for processor ${processorId} with instance id ${instanceId}`);
1089
+ await hooks.onStart(context);
1090
+ }
1091
+ if (startFrom && startFrom !== "CURRENT") {
1092
+ console.log(`Processor ${processorId} with instance id ${instanceId} starting from: ${JSONSerializer.serialize(startFrom)}`);
1093
+ return startFrom;
1094
+ }
1081
1095
  if (checkpoints) lastCheckpoint = (await checkpoints?.read({
1082
1096
  processorId,
1083
1097
  partition
@@ -1085,7 +1099,11 @@ const reactor = (options) => {
1085
1099
  ...startOptions,
1086
1100
  ...context
1087
1101
  })).lastCheckpoint;
1088
- if (lastCheckpoint === null) return "BEGINNING";
1102
+ if (lastCheckpoint === null) {
1103
+ console.log(`Processor ${processorId} with instance id ${instanceId} starting from: BEGINNING`);
1104
+ return "BEGINNING";
1105
+ }
1106
+ console.log(`Checkpoint read for processor ${processorId} with instance id ${instanceId}: ${JSONSerializer.serialize(lastCheckpoint)}`);
1089
1107
  return { lastCheckpoint };
1090
1108
  }, startOptions);
1091
1109
  },
@@ -1095,34 +1113,44 @@ const reactor = (options) => {
1095
1113
  },
1096
1114
  handle: async (messages, partialContext) => {
1097
1115
  if (!isActive) return Promise.resolve();
1098
- return await processingScope(async (context) => {
1099
- const messagesAboveCheckpoint = messages.filter((message) => !wasMessageHandled(message, lastCheckpoint));
1100
- const upcastedMessages = messagesAboveCheckpoint.map((message) => upcastRecordedMessage(message, options.messageOptions?.schema?.versioning)).filter((upcasted) => !canHandle || canHandle.includes(upcasted.type));
1101
- const stopMessageIndex = isCustomBatch && stopAfter ? upcastedMessages.findIndex(stopAfter) : -1;
1102
- const unhandledMessages = stopMessageIndex !== -1 ? upcastedMessages.slice(0, stopMessageIndex + 1) : upcastedMessages;
1103
- const batchResult = await eachBatch(unhandledMessages, context);
1104
- const messageProcessingResult = batchResult?.type === "STOP" ? batchResult : stopMessageIndex !== -1 ? {
1116
+ try {
1117
+ return await processingScope(async (context) => {
1118
+ const messagesAboveCheckpoint = messages.filter((message) => !wasMessageHandled(message, lastCheckpoint));
1119
+ const upcastedMessages = messagesAboveCheckpoint.map((message) => upcastRecordedMessage(message, options.messageOptions?.schema?.versioning)).filter((upcasted) => !canHandle || canHandle.includes(upcasted.type));
1120
+ const stopMessageIndex = isCustomBatch && stopAfter ? upcastedMessages.findIndex(stopAfter) : -1;
1121
+ const unhandledMessages = stopMessageIndex !== -1 ? upcastedMessages.slice(0, stopMessageIndex + 1) : upcastedMessages;
1122
+ const batchResult = await eachBatch(unhandledMessages, context);
1123
+ const messageProcessingResult = batchResult?.type === "STOP" ? batchResult : stopMessageIndex !== -1 ? {
1124
+ type: "STOP",
1125
+ reason: "Stop condition reached",
1126
+ lastSuccessfulMessage: unhandledMessages[stopMessageIndex]
1127
+ } : batchResult;
1128
+ const isStop = messageProcessingResult && messageProcessingResult.type === "STOP";
1129
+ const checkpointMessage = messageProcessingResult?.type === "STOP" ? messageProcessingResult.lastSuccessfulMessage : messagesAboveCheckpoint[messagesAboveCheckpoint.length - 1];
1130
+ if (checkpointMessage && checkpoints) {
1131
+ const storeCheckpointResult = await checkpoints.store({
1132
+ processorId,
1133
+ version,
1134
+ message: checkpointMessage,
1135
+ lastCheckpoint,
1136
+ partition
1137
+ }, context);
1138
+ if (storeCheckpointResult.success) lastCheckpoint = storeCheckpointResult.newCheckpoint;
1139
+ }
1140
+ if (isStop) {
1141
+ isActive = false;
1142
+ return messageProcessingResult;
1143
+ }
1144
+ }, partialContext);
1145
+ } catch (error) {
1146
+ console.log(`Error during message processing for processor ${processorId} with instance id ${instanceId}. Stopping the processor.`, error);
1147
+ isActive = false;
1148
+ return {
1105
1149
  type: "STOP",
1106
- reason: "Stop condition reached",
1107
- lastSuccessfulMessage: unhandledMessages[stopMessageIndex]
1108
- } : batchResult;
1109
- const isStop = messageProcessingResult && messageProcessingResult.type === "STOP";
1110
- const checkpointMessage = messageProcessingResult?.type === "STOP" ? messageProcessingResult.lastSuccessfulMessage : messagesAboveCheckpoint[messagesAboveCheckpoint.length - 1];
1111
- if (checkpointMessage && checkpoints) {
1112
- const storeCheckpointResult = await checkpoints.store({
1113
- processorId,
1114
- version,
1115
- message: checkpointMessage,
1116
- lastCheckpoint,
1117
- partition
1118
- }, context);
1119
- if (storeCheckpointResult.success) lastCheckpoint = storeCheckpointResult.newCheckpoint;
1120
- }
1121
- if (isStop) {
1122
- isActive = false;
1123
- return messageProcessingResult;
1124
- }
1125
- }, partialContext);
1150
+ error,
1151
+ reason: "Error during message processing"
1152
+ };
1153
+ }
1126
1154
  }
1127
1155
  };
1128
1156
  };
@@ -1374,9 +1402,12 @@ const assertNotDeepEqual = (actual, expected, message) => {
1374
1402
  const assertThat = (item) => {
1375
1403
  return { isEqualTo: (other) => assertTrue(deepEquals(item, other)) };
1376
1404
  };
1377
- const assertDefined = (value, message) => {
1378
- assertOk(value, message instanceof Error ? message.message : message);
1379
- };
1405
+ function assertDefined(value, message) {
1406
+ if (value === void 0 || value === null) throw new AssertionError((message instanceof Error ? message.message : message) ?? "Value is not defined");
1407
+ }
1408
+ function assertUndefined(value, message) {
1409
+ if (value !== void 0 && value !== null) throw new AssertionError((message instanceof Error ? message.message : message) ?? "Value is defined");
1410
+ }
1380
1411
  function assertFalse(condition, message) {
1381
1412
  if (condition !== false) throw new AssertionError(message ?? `Condition is true`);
1382
1413
  }
@@ -1855,6 +1886,247 @@ const getInMemoryEventStore = (eventStoreOptions) => {
1855
1886
  return eventStore;
1856
1887
  };
1857
1888
 
1889
+ //#endregion
1890
+ //#region src/observability/attributes.ts
1891
+ const EmmettAttributes = {
1892
+ scope: { type: "emmett.scope.type" },
1893
+ command: {
1894
+ type: "emmett.command.type",
1895
+ status: "emmett.command.status",
1896
+ eventCount: "emmett.command.event_count",
1897
+ eventTypes: "emmett.command.event_types"
1898
+ },
1899
+ stream: {
1900
+ name: "emmett.stream.name",
1901
+ versionBefore: "emmett.stream.version.before",
1902
+ versionAfter: "emmett.stream.version.after"
1903
+ },
1904
+ eventStore: {
1905
+ operation: "emmett.eventstore.operation",
1906
+ read: {
1907
+ eventCount: "emmett.eventstore.read.event_count",
1908
+ eventTypes: "emmett.eventstore.read.event_types",
1909
+ status: "emmett.eventstore.read.status"
1910
+ },
1911
+ append: {
1912
+ batchSize: "emmett.eventstore.append.batch_size",
1913
+ status: "emmett.eventstore.append.status"
1914
+ }
1915
+ },
1916
+ event: { type: "emmett.event.type" },
1917
+ processor: {
1918
+ id: "emmett.processor.id",
1919
+ type: "emmett.processor.type",
1920
+ status: "emmett.processor.status",
1921
+ batchSize: "emmett.processor.batch_size",
1922
+ eventTypes: "emmett.processor.event_types",
1923
+ checkpointBefore: "emmett.processor.checkpoint.before",
1924
+ checkpointAfter: "emmett.processor.checkpoint.after",
1925
+ lagEvents: "emmett.processor.lag_events"
1926
+ },
1927
+ workflow: {
1928
+ id: "emmett.workflow.id",
1929
+ type: "emmett.workflow.type",
1930
+ inputType: "emmett.workflow.input.type",
1931
+ outputs: "emmett.workflow.outputs",
1932
+ outputsCount: "emmett.workflow.outputs.count",
1933
+ streamPosition: "emmett.workflow.stream_position",
1934
+ stateRebuildEventCount: "emmett.workflow.state_rebuild.event_count"
1935
+ },
1936
+ consumer: {
1937
+ batchSize: "emmett.consumer.batch_size",
1938
+ processorCount: "emmett.consumer.processor_count",
1939
+ delivery: { processorId: "emmett.consumer.delivery.processor_id" }
1940
+ }
1941
+ };
1942
+ const EmmettMetrics = {
1943
+ command: { handlingDuration: "emmett.command.handling.duration" },
1944
+ event: {
1945
+ appendingCount: "emmett.event.appending.count",
1946
+ readingCount: "emmett.event.reading.count"
1947
+ },
1948
+ stream: {
1949
+ readingDuration: "emmett.stream.reading.duration",
1950
+ readingSize: "emmett.stream.reading.size",
1951
+ appendingDuration: "emmett.stream.appending.duration",
1952
+ appendingSize: "emmett.stream.appending.size"
1953
+ },
1954
+ processor: {
1955
+ processingDuration: "emmett.processor.processing.duration",
1956
+ lagEvents: "emmett.processor.lag_events"
1957
+ },
1958
+ workflow: { processingDuration: "emmett.workflow.processing.duration" },
1959
+ consumer: {
1960
+ pollDuration: "emmett.consumer.poll.duration",
1961
+ deliveryDuration: "emmett.consumer.delivery.duration"
1962
+ }
1963
+ };
1964
+ const ScopeTypes = {
1965
+ command: "command",
1966
+ processor: "processor",
1967
+ reactor: "reactor",
1968
+ projector: "projector",
1969
+ workflow: "workflow",
1970
+ consumer: "consumer"
1971
+ };
1972
+ const MessagingSystemName = "emmett";
1973
+
1974
+ //#endregion
1975
+ //#region src/observability/options.ts
1976
+ const resolveCommandObservability = (options, parent) => ({
1977
+ tracer: options?.observability?.tracer ?? parent?.observability?.tracer ?? (0, _event_driven_io_almanac.noopTracer)(),
1978
+ meter: options?.observability?.meter ?? parent?.observability?.meter ?? (0, _event_driven_io_almanac.noopMeter)(),
1979
+ attributeTarget: options?.observability?.attributeTarget ?? parent?.observability?.attributeTarget ?? "both",
1980
+ includeMessagePayloads: options?.observability?.includeMessagePayloads ?? parent?.observability?.includeMessagePayloads ?? false
1981
+ });
1982
+
1983
+ //#endregion
1984
+ //#region src/observability/tracer.ts
1985
+ const tracer = () => {};
1986
+ const LogLevel = {
1987
+ DISABLED: "DISABLED",
1988
+ INFO: "INFO",
1989
+ LOG: "LOG",
1990
+ WARN: "WARN",
1991
+ ERROR: "ERROR"
1992
+ };
1993
+ const getEnvVariable = (name) => {
1994
+ try {
1995
+ if (typeof process !== "undefined" && process.env) return process.env[name];
1996
+ return;
1997
+ } catch {
1998
+ return;
1999
+ }
2000
+ };
2001
+ const shouldLog = (logLevel) => {
2002
+ const definedLogLevel = getEnvVariable("DUMBO_LOG_LEVEL") ?? LogLevel.ERROR;
2003
+ if (definedLogLevel === LogLevel.ERROR && logLevel === LogLevel.ERROR) return true;
2004
+ if (definedLogLevel === LogLevel.WARN && [LogLevel.ERROR, LogLevel.WARN].includes(logLevel)) return true;
2005
+ if (definedLogLevel === LogLevel.LOG && [
2006
+ LogLevel.ERROR,
2007
+ LogLevel.WARN,
2008
+ LogLevel.LOG
2009
+ ].includes(logLevel)) return true;
2010
+ if (definedLogLevel === LogLevel.INFO && [
2011
+ LogLevel.ERROR,
2012
+ LogLevel.WARN,
2013
+ LogLevel.LOG,
2014
+ LogLevel.INFO
2015
+ ].includes(logLevel)) return true;
2016
+ return false;
2017
+ };
2018
+ const nulloTraceEventRecorder = () => {};
2019
+ const getTraceEventFormatter = (logStyle, serializer) => (event) => {
2020
+ serializer = serializer ?? JSONSerializer.from();
2021
+ switch (logStyle) {
2022
+ case "RAW": return serializer.serialize(event);
2023
+ case "PRETTY": return serializer.serialize(event);
2024
+ }
2025
+ };
2026
+ const getTraceEventRecorder = (logLevel, logStyle) => {
2027
+ const format = getTraceEventFormatter(logStyle);
2028
+ switch (logLevel) {
2029
+ case "DISABLED": return nulloTraceEventRecorder;
2030
+ case "INFO": return (event) => console.info(format(event));
2031
+ case "LOG": return (event) => console.log(format(event));
2032
+ case "WARN": return (event) => console.warn(format(event));
2033
+ case "ERROR": return (event) => console.error(format(event));
2034
+ }
2035
+ };
2036
+ const recordTraceEvent = (logLevel, eventName, attributes) => {
2037
+ if (!shouldLog(LogLevel.LOG)) return;
2038
+ const event = {
2039
+ name: eventName,
2040
+ timestamp: (/* @__PURE__ */ new Date()).getTime(),
2041
+ ...attributes
2042
+ };
2043
+ getTraceEventRecorder(logLevel, getEnvVariable("DUMBO_LOG_STYLE") ?? "RAW")(event);
2044
+ };
2045
+ tracer.info = (eventName, attributes) => recordTraceEvent(LogLevel.INFO, eventName, attributes);
2046
+ tracer.warn = (eventName, attributes) => recordTraceEvent(LogLevel.WARN, eventName, attributes);
2047
+ tracer.log = (eventName, attributes) => recordTraceEvent(LogLevel.LOG, eventName, attributes);
2048
+ tracer.error = (eventName, attributes) => recordTraceEvent(LogLevel.ERROR, eventName, attributes);
2049
+
2050
+ //#endregion
2051
+ //#region src/commandHandling/observability/commandHandlerCollector.ts
2052
+ const commandHandlerCollector = (observability) => {
2053
+ const { startScope } = (0, _event_driven_io_almanac.ObservabilityScope)({
2054
+ ...observability,
2055
+ attributePrefix: "emmett"
2056
+ });
2057
+ const A = EmmettAttributes;
2058
+ const M = _event_driven_io_almanac.MessagingAttributes;
2059
+ const commandHandlingDuration = observability.meter.histogram(EmmettMetrics.command.handlingDuration);
2060
+ const eventAppendingCount = observability.meter.counter(EmmettMetrics.event.appendingCount);
2061
+ return {
2062
+ startScope: (context, fn) => {
2063
+ const start = Date.now();
2064
+ return startScope("command.handle", async (scope) => {
2065
+ scope.setAttributes({
2066
+ [A.scope.type]: ScopeTypes.command,
2067
+ [M.system]: MessagingSystemName,
2068
+ [M.destination.name]: context.streamName,
2069
+ ...context.commandType ? { [A.command.type]: context.commandType } : {},
2070
+ ...context.correlationId ? { [M.message.correlationId]: context.correlationId } : {},
2071
+ ...context.causationId ? { [M.message.causationId]: context.causationId } : {}
2072
+ });
2073
+ let status = "success";
2074
+ try {
2075
+ const result = await fn(scope);
2076
+ status = "success";
2077
+ scope.setAttributes({
2078
+ [A.command.status]: "success",
2079
+ error: false
2080
+ });
2081
+ return result;
2082
+ } catch (err) {
2083
+ status = "failure";
2084
+ scope.setAttributes({
2085
+ [A.command.status]: "failure",
2086
+ error: true,
2087
+ "exception.message": err instanceof Error ? err.message : String(err),
2088
+ "exception.type": err instanceof Error ? err.constructor.name : "unknown"
2089
+ });
2090
+ scope.recordException(err instanceof Error ? err : new Error(String(err)));
2091
+ throw err;
2092
+ } finally {
2093
+ commandHandlingDuration.record(Date.now() - start, {
2094
+ [A.command.status]: status,
2095
+ ...typeof context.commandType === "string" ? { [A.command.type]: context.commandType } : {}
2096
+ });
2097
+ }
2098
+ }, {
2099
+ parent: context.traceId && context.spanId ? {
2100
+ traceId: context.traceId,
2101
+ spanId: context.spanId
2102
+ } : void 0,
2103
+ attributes: {
2104
+ [A.scope.type]: ScopeTypes.command,
2105
+ [A.stream.name]: context.streamName,
2106
+ ...context.commandType ? { [A.command.type]: context.commandType } : {},
2107
+ ...context.correlationId ? { [M.message.correlationId]: context.correlationId } : {},
2108
+ ...context.causationId ? { [M.message.causationId]: context.causationId } : {}
2109
+ }
2110
+ });
2111
+ },
2112
+ recordEvents: (scope, events, status) => {
2113
+ scope.setAttributes({
2114
+ [A.command.eventCount]: events.length,
2115
+ [A.command.eventTypes]: events.map((e) => e.type),
2116
+ [M.batch.messageCount]: events.length,
2117
+ [A.command.status]: status
2118
+ });
2119
+ for (const event of events) eventAppendingCount.add(1, { [A.event.type]: event.type });
2120
+ },
2121
+ recordVersions: (scope, before, after) => {
2122
+ scope.setAttributes({
2123
+ [A.stream.versionBefore]: Number(before),
2124
+ [A.stream.versionAfter]: Number(after)
2125
+ });
2126
+ }
2127
+ };
2128
+ };
2129
+
1858
2130
  //#endregion
1859
2131
  //#region src/commandHandling/handleCommand.ts
1860
2132
  const CommandHandlerStreamVersionConflictRetryOptions = {
@@ -1863,6 +2135,76 @@ const CommandHandlerStreamVersionConflictRetryOptions = {
1863
2135
  factor: 1.5,
1864
2136
  shouldRetryError: isExpectedVersionConflictError
1865
2137
  };
2138
+ const CommandHandler = (options) => async (store, id, handle, handleOptions) => {
2139
+ const collector = commandHandlerCollector(resolveCommandObservability(options));
2140
+ const streamName = (options.mapToStreamId ?? ((id) => id))(id);
2141
+ const commandType = handleOptions?.commandType ?? options.commandType ?? options.name ?? handlerNames(handle);
2142
+ const correlationId = handleOptions?.observability?.correlationId ?? (0, uuid.v7)();
2143
+ const causationId = handleOptions?.observability?.causationId;
2144
+ return asyncRetry(() => collector.startScope({
2145
+ streamName,
2146
+ commandType,
2147
+ correlationId,
2148
+ causationId,
2149
+ traceId: handleOptions?.observability?.traceId,
2150
+ spanId: handleOptions?.observability?.spanId
2151
+ }, async (scope) => {
2152
+ return await withSession$1(store, async ({ eventStore }) => {
2153
+ const { evolve, initialState } = options;
2154
+ const aggregationResult = await eventStore.aggregateStream(streamName, {
2155
+ evolve,
2156
+ initialState,
2157
+ read: {
2158
+ schema: options.schema,
2159
+ ...handleOptions,
2160
+ serialization: options.serialization,
2161
+ expectedStreamVersion: handleOptions?.expectedStreamVersion ?? "NO_CONCURRENCY_CHECK"
2162
+ }
2163
+ });
2164
+ const { currentStreamVersion, streamExists: _streamExists, ...restOfAggregationResult } = aggregationResult;
2165
+ let state = aggregationResult.state;
2166
+ const handlers = Array.isArray(handle) ? handle : [handle];
2167
+ let eventsToAppend = [];
2168
+ for (const handler of handlers) {
2169
+ const result = await handler(state);
2170
+ const newEvents = Array.isArray(result) ? result : [result];
2171
+ if (newEvents.length > 0) state = newEvents.reduce(evolve, state);
2172
+ eventsToAppend = [...eventsToAppend, ...newEvents];
2173
+ }
2174
+ if (eventsToAppend.length === 0) {
2175
+ collector.recordVersions(scope, currentStreamVersion, currentStreamVersion);
2176
+ return {
2177
+ ...restOfAggregationResult,
2178
+ newEvents: [],
2179
+ newState: state,
2180
+ nextExpectedStreamVersion: currentStreamVersion,
2181
+ createdNewStream: false
2182
+ };
2183
+ }
2184
+ const expectedStreamVersion = handleOptions?.expectedStreamVersion ?? (aggregationResult.streamExists ? currentStreamVersion : "STREAM_DOES_NOT_EXIST");
2185
+ const { traceId, spanId } = scope.spanContext();
2186
+ const { observability: _appendObservability, ...handleOptionsForAppend } = handleOptions ?? {};
2187
+ const appendResult = await eventStore.appendToStream(streamName, eventsToAppend, {
2188
+ ...handleOptionsForAppend,
2189
+ expectedStreamVersion,
2190
+ correlationId,
2191
+ ...causationId ? { causationId } : {},
2192
+ traceId,
2193
+ spanId
2194
+ });
2195
+ collector.recordEvents(scope, eventsToAppend, "success");
2196
+ collector.recordVersions(scope, currentStreamVersion, appendResult.nextExpectedStreamVersion);
2197
+ return {
2198
+ ...appendResult,
2199
+ newEvents: eventsToAppend,
2200
+ newState: state
2201
+ };
2202
+ });
2203
+ }), fromCommandHandlerRetryOptions(handleOptions && "retry" in handleOptions ? handleOptions.retry : options.retry));
2204
+ };
2205
+ const withSession$1 = (eventStore, callback) => {
2206
+ return (canCreateEventStoreSession(eventStore) ? eventStore : nulloSessionFactory(eventStore)).withSession(callback);
2207
+ };
1866
2208
  const fromCommandHandlerRetryOptions = (retryOptions) => {
1867
2209
  if (retryOptions === void 0) return NoRetries;
1868
2210
  if ("onVersionConflict" in retryOptions) if (typeof retryOptions.onVersionConflict === "boolean") return CommandHandlerStreamVersionConflictRetryOptions;
@@ -1873,58 +2215,24 @@ const fromCommandHandlerRetryOptions = (retryOptions) => {
1873
2215
  else return retryOptions.onVersionConflict;
1874
2216
  return retryOptions;
1875
2217
  };
1876
- const CommandHandler = (options) => async (store, id, handle, handleOptions) => asyncRetry(async () => {
1877
- return await withSession$1(store, async ({ eventStore }) => {
1878
- const { evolve, initialState } = options;
1879
- const streamName = (options.mapToStreamId ?? ((id) => id))(id);
1880
- const aggregationResult = await eventStore.aggregateStream(streamName, {
1881
- evolve,
1882
- initialState,
1883
- read: {
1884
- schema: options.schema,
1885
- ...handleOptions,
1886
- serialization: options.serialization,
1887
- expectedStreamVersion: handleOptions?.expectedStreamVersion ?? "NO_CONCURRENCY_CHECK"
1888
- }
1889
- });
1890
- const { currentStreamVersion, streamExists: _streamExists, ...restOfAggregationResult } = aggregationResult;
1891
- let state = aggregationResult.state;
1892
- const handlers = Array.isArray(handle) ? handle : [handle];
1893
- let eventsToAppend = [];
1894
- for (const handler of handlers) {
1895
- const result = await handler(state);
1896
- const newEvents = Array.isArray(result) ? result : [result];
1897
- if (newEvents.length > 0) state = newEvents.reduce(evolve, state);
1898
- eventsToAppend = [...eventsToAppend, ...newEvents];
1899
- }
1900
- if (eventsToAppend.length === 0) return {
1901
- ...restOfAggregationResult,
1902
- newEvents: [],
1903
- newState: state,
1904
- nextExpectedStreamVersion: currentStreamVersion,
1905
- createdNewStream: false
1906
- };
1907
- const expectedStreamVersion = handleOptions?.expectedStreamVersion ?? (aggregationResult.streamExists ? currentStreamVersion : "STREAM_DOES_NOT_EXIST");
1908
- return {
1909
- ...await eventStore.appendToStream(streamName, eventsToAppend, {
1910
- ...handleOptions,
1911
- expectedStreamVersion
1912
- }),
1913
- newEvents: eventsToAppend,
1914
- newState: state
1915
- };
1916
- });
1917
- }, fromCommandHandlerRetryOptions(handleOptions && "retry" in handleOptions ? handleOptions.retry : options.retry));
1918
- const withSession$1 = (eventStore, callback) => {
1919
- return (canCreateEventStoreSession(eventStore) ? eventStore : nulloSessionFactory(eventStore)).withSession(callback);
2218
+ const handlerNames = (handle) => {
2219
+ if (Array.isArray(handle)) {
2220
+ const names = handle.map((h) => h.name).filter((n) => !!n);
2221
+ return names.length > 0 ? names : void 0;
2222
+ }
2223
+ return handle.name || void 0;
1920
2224
  };
1921
2225
 
1922
2226
  //#endregion
1923
2227
  //#region src/commandHandling/handleCommandWithDecider.ts
2228
+ const commandTypesOf = (commands) => Array.isArray(commands) ? commands.map((c) => c.type) : commands.type;
1924
2229
  const DeciderCommandHandler = (options) => async (eventStore, id, commands, handleOptions) => {
1925
2230
  const { decide, ...rest } = options;
1926
2231
  const deciders = (Array.isArray(commands) ? commands : [commands]).map((command) => (state) => decide(command, state));
1927
- return CommandHandler(rest)(eventStore, id, deciders, handleOptions);
2232
+ return CommandHandler(rest)(eventStore, id, deciders, {
2233
+ commandType: commandTypesOf(commands),
2234
+ ...handleOptions
2235
+ });
1928
2236
  };
1929
2237
 
1930
2238
  //#endregion
@@ -2263,6 +2571,7 @@ exports.assertThatArray = assertThatArray;
2263
2571
  exports.assertThrows = assertThrows;
2264
2572
  exports.assertThrowsAsync = assertThrowsAsync;
2265
2573
  exports.assertTrue = assertTrue;
2574
+ exports.assertUndefined = assertUndefined;
2266
2575
  exports.assertUnsignedBigInt = require_plugins.assertUnsignedBigInt;
2267
2576
  exports.asyncAwaiter = asyncAwaiter;
2268
2577
  exports.asyncProjections = asyncProjections;