@znight/messaging 0.3.0 → 0.4.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.
@@ -1 +1 @@
1
- {"version":3,"file":"compiler.mjs","names":[],"sources":["../src/compiler/constants.ts","../src/compiler/patterns.ts","../src/compiler/values.ts","../src/compiler/retry.ts","../src/compiler/analyze.ts","../src/compiler/generate.ts","../src/compiler/validate.ts","../src/compiler/index.ts"],"sourcesContent":["/**\n * Constants shared by the compiler extension modules. This module must stay free of runtime imports:\n * the extension entry is loaded by the compiler, which must never load the messaging runtime (spec §2).\n */\nimport type { ErrorCode } from '@znight/core'\n\n/** Name of the extension, also the key of `metadata.extensions.messaging`. */\nexport const EXTENSION_NAME = 'messaging'\n\n/** Module the generated code imports its helpers and types from. */\nexport const RUNTIME_MODULE = '@znight/messaging'\n\n/** Canonical identities of the decorators owned by the extension. */\nexport const MessagingDecorator: {\n readonly Consumer: '@znight/messaging#Consumer'\n readonly OnMessage: '@znight/messaging#OnMessage'\n readonly Retry: '@znight/messaging#Retry'\n readonly OnError: '@znight/messaging#OnError'\n readonly Message: '@znight/messaging#Message'\n readonly Headers: '@znight/messaging#Headers'\n readonly Ctx: '@znight/messaging#Ctx'\n} = Object.freeze({\n Consumer: '@znight/messaging#Consumer',\n OnMessage: '@znight/messaging#OnMessage',\n Retry: '@znight/messaging#Retry',\n OnError: '@znight/messaging#OnError',\n Message: '@znight/messaging#Message',\n Headers: '@znight/messaging#Headers',\n Ctx: '@znight/messaging#Ctx',\n})\n\n/** Identity of the `InboundMessage` interface (`@Ctx()` parameters). */\nexport const INBOUND_MESSAGE_IDENTITY = '@znight/messaging#InboundMessage'\n\n/** Decorators applied to methods. */\nexport const METHOD_DECORATORS: ReadonlySet<string> = new Set([\n MessagingDecorator.OnMessage,\n MessagingDecorator.Retry,\n MessagingDecorator.OnError,\n])\n\n/** Decorators applied to handler parameters. */\nexport const PARAMETER_DECORATORS: ReadonlySet<string> = new Set([\n MessagingDecorator.Message,\n MessagingDecorator.Headers,\n MessagingDecorator.Ctx,\n])\n\n/** ZNIGHT005: invalid decorator usage (target, arguments, several decorators...). */\nexport const INVALID_DECORATOR: ErrorCode = 'ZNIGHT005'\n/** ZNIGHT011: invalid message consumer (no handler, overlapping types, retry options...). */\nexport const INVALID_CONSUMER: ErrorCode = 'ZNIGHT011'\n/** ZNIGHT017: non-primitive `@Message()` payload without schema. */\nexport const UNVALIDATED_INPUT: ErrorCode = 'ZNIGHT017'\n\n/**\n * Default backoff of `@Retry` (must equal the runtime `DEFAULT_BACKOFF`; checked by the tests, the\n * runtime module cannot be imported here).\n */\nexport const DEFAULT_BACKOFF = 'exponential'\n/** Default base delay of `@Retry`, in milliseconds (the runtime `DEFAULT_RETRY_DELAY_MS`). */\nexport const DEFAULT_RETRY_DELAY_MS = 1000\n/** Largest `attempts` accepted by the runtime (`normalizeRetry`). */\nexport const MAX_RETRY_ATTEMPTS = 10_000\n\n/** Scopes a consumer provider may have. */\nexport const CONSUMER_SCOPES: readonly string[] = ['singleton', 'request', 'transient']\n\n/** Deterministic string comparison (never `localeCompare`). */\nexport function compareStrings(a: string, b: string): number {\n if (a === b) return 0\n return a < b ? -1 : 1\n}\n","/**\n * Message type patterns of `@OnMessage(type)`, with the semantics of the runtime handler selection\n * (`consumers.ts`): a type containing `*` is a pattern where `*` matches any sequence of characters;\n * any other type is matched exactly. Exact types are tried first, then patterns in declaration order.\n */\n\n/** Whether `type` is a pattern (contains `*`). */\nexport function isPattern(type: string): boolean {\n return type.includes('*')\n}\n\n/** Whether `type` matches `pattern` (`*` matches any sequence of characters, the runtime semantics). */\nexport function matchesPattern(pattern: string, type: string): boolean {\n return covers(pattern, type, false)\n}\n\n/**\n * Whether every message type matched by `inner` is also matched by `outer`, so that `inner`, tried\n * after `outer`, can never be selected. The check is sound (never reports a pattern that can be\n * selected): `outer` must match `inner` where each `*` of `inner` can only be consumed by a `*` of\n * `outer`.\n */\nexport function patternCovers(outer: string, inner: string): boolean {\n return covers(outer, inner, true)\n}\n\n/** Glob matching of `subject` by `pattern`; with `starsAreWildcards`, `*` of `subject` only match `*` of `pattern`. */\nfunction covers(pattern: string, subject: string, starsAreWildcards: boolean): boolean {\n const p = collapseStars(pattern)\n const s = starsAreWildcards ? collapseStars(subject) : subject\n // previous[j]: p[0, i - 1) matches s[0, j)\n let previous: boolean[] = new Array<boolean>(s.length + 1).fill(false)\n previous[0] = true\n for (let i = 1; i <= p.length; i++) {\n const char = p[i - 1]\n const current: boolean[] = new Array<boolean>(s.length + 1).fill(false)\n current[0] = char === '*' && previous[0] === true\n for (let j = 1; j <= s.length; j++) {\n if (char === '*') {\n current[j] = previous[j] === true || current[j - 1] === true\n } else {\n const subjectChar = s[j - 1]\n current[j] = previous[j - 1] === true && subjectChar === char && !(starsAreWildcards && subjectChar === '*')\n }\n }\n previous = current\n }\n return previous[s.length] === true\n}\n\n/** `a**b` → `a*b` (same language). */\nfunction collapseStars(pattern: string): string {\n return pattern.replace(/\\*{2,}/g, '*')\n}\n","/**\n * Helpers on statically evaluated decorator arguments and their source locations.\n */\nimport type { ArgInfo, Location, Project, StaticValue } from '@znight/compiler'\n\ntype Expression = ArgInfo['node']\n\n/** An evaluated object literal (not an array, not a reference to an exported binding). */\nexport function isRecord(value: StaticValue): value is Readonly<Record<string, StaticValue>> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false\n const prototype: unknown = Object.getPrototypeOf(value)\n return prototype === Object.prototype || prototype === null\n}\n\n/** Short description of a value for messages (`\"orders\"`, `42`, `an array`...). */\nexport function describeValue(value: StaticValue): string {\n if (value === undefined) return 'undefined'\n if (value === null) return 'null'\n if (typeof value === 'string') return JSON.stringify(value)\n if (typeof value === 'bigint') return `${value}n`\n if (typeof value !== 'object') return String(value)\n if (Array.isArray(value)) return 'an array'\n return isRecord(value) ? 'an object' : `a reference to '${(value as { readonly text?: string }).text ?? '?'}'`\n}\n\n/**\n * Location of the property `key` of an object literal argument (`attempts: 0` in\n * `@Retry({ attempts: 0 })`), or of the whole argument when it is not an inline object literal.\n */\nexport function propertyLocation(project: Project, arg: ArgInfo, key: string): Location {\n let node: Expression = arg.node\n while (\n node.type === 'TSAsExpression' ||\n node.type === 'TSSatisfiesExpression' ||\n node.type === 'TSNonNullExpression' ||\n node.type === 'ParenthesizedExpression'\n ) {\n node = node.expression\n }\n if (node.type !== 'ObjectExpression') return arg.location\n for (const property of node.properties) {\n if (property.type !== 'Property' || property.computed) continue\n const { key: name } = property\n const found =\n name.type === 'Identifier' ? name.name : name.type === 'Literal' && typeof name.value === 'string' && name.value\n if (found === key) return project.getFile(arg.location.file)?.location(property) ?? arg.location\n }\n return arg.location\n}\n\n/** Closest candidate of `name` among `candidates` (typos: `attempt` → `attempts`), if any. */\nexport function closest(name: string, candidates: readonly string[]): string | undefined {\n let best: string | undefined\n let bestDistance = Math.max(2, Math.floor(name.length / 3)) + 1\n for (const candidate of candidates) {\n const distance = editDistance(name.toLowerCase(), candidate.toLowerCase())\n if (distance < bestDistance) {\n best = candidate\n bestDistance = distance\n }\n }\n return best\n}\n\nfunction editDistance(a: string, b: string): number {\n let previous = Array.from({ length: b.length + 1 }, (_, index) => index)\n for (let i = 1; i <= a.length; i++) {\n const current = [i]\n for (let j = 1; j <= b.length; j++) {\n const substitution = (previous[j - 1] ?? 0) + (a[i - 1] === b[j - 1] ? 0 : 1)\n current[j] = Math.min((previous[j] ?? 0) + 1, (current[j - 1] ?? 0) + 1, substitution)\n }\n previous = current\n }\n return previous[b.length] ?? 0\n}\n","/**\n * Compile-time validation and normalization of `@Retry` options. Mirrors the runtime\n * `normalizeRetry()` (same rules and defaults) so that invalid policies fail the build instead of the\n * boot; it also rejects unknown options (typos) and warns about options without effect.\n */\nimport type { AnalyzeContext, DecoratorInfo, StaticValue } from '@znight/compiler'\nimport type { MessagingData, RetryPolicyData } from './data.ts'\n\nimport {\n DEFAULT_BACKOFF,\n DEFAULT_RETRY_DELAY_MS,\n INVALID_CONSUMER,\n INVALID_DECORATOR,\n MAX_RETRY_ATTEMPTS,\n} from './constants.ts'\nimport { closest, describeValue, isRecord, propertyLocation } from './values.ts'\n\nconst RETRY_OPTIONS: readonly string[] = ['attempts', 'backoff', 'delay', 'maxDelay']\n\n/**\n * Validates the argument of a `@Retry` decorator and fills the runtime defaults. Returns `undefined`\n * (after reporting the problems) when the options are invalid.\n *\n * @param where the handler (`OrderConsumer.placed()`), used in messages\n */\nexport function normalizeRetryDecorator(\n decorator: DecoratorInfo,\n where: string,\n ctx: AnalyzeContext<MessagingData>,\n): RetryPolicyData | undefined {\n if (!decorator.called) return undefined // `@Retry` without call: already reported\n const arg = decorator.args[0]\n if (arg === undefined) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@Retry on ${where} requires options: @Retry({ attempts: 3 })`,\n location: decorator.location,\n hints: ['attempts counts the first delivery: { attempts: 3 } means 1 delivery + 2 retries'],\n })\n return undefined\n }\n if (!arg.evaluated) return undefined // not statically evaluable: already reported\n const options = arg.value\n if (!isRecord(options)) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@Retry on ${where} expects an options object ({ attempts, backoff?, delay?, maxDelay? }), got ${describeValue(options)}`,\n location: arg.location,\n })\n return undefined\n }\n\n let valid = true\n const fail = (key: string, message: string, hints?: readonly string[]): void => {\n valid = false\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `@Retry on ${where}: ${message}`,\n location: propertyLocation(ctx.project, arg, key),\n ...(hints === undefined ? {} : { hints }),\n })\n }\n\n for (const key of Object.keys(options)) {\n if (RETRY_OPTIONS.includes(key)) continue\n const suggestion = closest(key, RETRY_OPTIONS)\n fail(key, `unknown option \"${key}\"`, [\n suggestion === undefined\n ? `Valid options: ${RETRY_OPTIONS.join(', ')}`\n : `Did you mean \"${suggestion}\"? Valid options: ${RETRY_OPTIONS.join(', ')}`,\n ])\n }\n\n const attempts = options['attempts']\n if (attempts === undefined) {\n fail('attempts', '\"attempts\" is required', [\n 'attempts counts the first delivery: { attempts: 3 } means 1 delivery + 2 retries',\n ])\n } else if (!isInteger(attempts) || attempts < 1 || attempts > MAX_RETRY_ATTEMPTS) {\n fail(\n 'attempts',\n `\"attempts\" must be an integer between 1 and ${MAX_RETRY_ATTEMPTS}, got ${describeValue(attempts)}`,\n ['attempts counts the first delivery: { attempts: 3 } means 1 delivery + 2 retries'],\n )\n }\n\n const rawBackoff = options['backoff']\n const backoff = rawBackoff === undefined ? DEFAULT_BACKOFF : rawBackoff\n if (backoff !== 'fixed' && backoff !== 'exponential') {\n fail('backoff', `\"backoff\" must be 'fixed' or 'exponential', got ${describeValue(backoff)}`)\n }\n\n const rawDelay = options['delay']\n const delay = rawDelay === undefined ? DEFAULT_RETRY_DELAY_MS : rawDelay\n const delayValid = isDuration(delay)\n if (!delayValid) {\n fail('delay', `\"delay\" must be a finite number of milliseconds >= 0, got ${describeValue(delay)}`)\n }\n\n const maxDelay = options['maxDelay']\n if (maxDelay !== undefined) {\n if (!isDuration(maxDelay) || (delayValid && maxDelay < delay)) {\n fail(\n 'maxDelay',\n `\"maxDelay\" must be a finite number of milliseconds >= delay${delayValid ? ` (${delay})` : ''}, got ${describeValue(maxDelay)}`,\n )\n } else if (backoff === 'fixed') {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'warning',\n message: `@Retry on ${where}: \"maxDelay\" has no effect with backoff 'fixed' (every retry waits \"delay\")`,\n location: propertyLocation(ctx.project, arg, 'maxDelay'),\n hints: [\"Remove maxDelay, or use backoff: 'exponential'\"],\n })\n }\n }\n\n if (!valid || !isInteger(attempts) || (backoff !== 'fixed' && backoff !== 'exponential') || !isDuration(delay)) {\n return undefined\n }\n const policy: RetryPolicyData = isDuration(maxDelay)\n ? { attempts, backoff, delay, maxDelay }\n : { attempts, backoff, delay }\n return Object.freeze(policy)\n}\n\nfunction isInteger(value: StaticValue): value is number {\n return typeof value === 'number' && Number.isInteger(value)\n}\n\nfunction isDuration(value: StaticValue): value is number {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0\n}\n","/**\n * `analyzeClass` of the messaging extension: reads `@Consumer` classes, their `@OnMessage` handlers\n * (`@Retry`, parameters), their `@OnError` method, registers the consumer provider and reports every\n * problem that can be detected on one class (ZNIGHT005, ZNIGHT011, ZNIGHT017).\n *\n * Handlers may be declared on base classes: the consumer inherits the messaging methods of its\n * analysable base classes (the nearest declaration of a method carrying messaging decorators wins, an\n * override without decorators keeps the inherited handler).\n */\nimport type {\n AnalyzeContext,\n ClassInfo,\n DecoratorInfo,\n Location,\n MethodInfo,\n ParameterInfo,\n StaticValue,\n TypeHelpers,\n TypeInfo,\n ValueRef,\n} from '@znight/compiler'\nimport type { Scope } from '@znight/core'\nimport type { HandlerData, HandlerParamData, MessagingData, RetryPolicyData } from './data.ts'\n\nimport {\n CONSUMER_SCOPES,\n EXTENSION_NAME,\n INBOUND_MESSAGE_IDENTITY,\n INVALID_CONSUMER,\n INVALID_DECORATOR,\n METHOD_DECORATORS,\n MessagingDecorator,\n PARAMETER_DECORATORS,\n RUNTIME_MODULE,\n UNVALIDATED_INPUT,\n} from './constants.ts'\nimport { isPattern, patternCovers } from './patterns.ts'\nimport { normalizeRetryDecorator } from './retry.ts'\nimport { describeValue, isRecord, propertyLocation } from './values.ts'\n\ntype Context = AnalyzeContext<MessagingData>\n\n/** The messaging declarations of one method. */\ninterface MemberAnalysis {\n readonly method: string\n readonly declaredBy: string\n /** Number of `@OnMessage` decorators (valid or not). */\n readonly onMessage: number\n /** One entry per valid `@OnMessage` decorator. */\n readonly handlers: readonly HandlerData[]\n /** Location of the `@OnError` decorator when the method is the error handler. */\n readonly errorHandler: Location | undefined\n}\n\n/** Types injected as is by `@Message()` without being \"unvalidated input\" (binary payloads). */\nconst BINARY_TYPES: ReadonlySet<string> = new Set([\n 'globalThis#Uint8Array',\n 'globalThis#ArrayBuffer',\n 'globalThis#Buffer',\n 'node:buffer#Buffer',\n 'buffer#Buffer',\n])\n\n/** Maximum depth of the base class chain walked for inherited handlers. */\nconst MAX_CHAIN = 32\n\n/** Analyses a class carrying at least one decorator of the extension. */\nexport function analyzeMessagingClass(cls: ClassInfo, ctx: Context): void {\n const own = analyzeMembers(cls, ctx)\n const consumers = cls.decorators.filter(decorator => decorator.identity === MessagingDecorator.Consumer)\n const consumer = consumers[0]\n if (consumer === undefined) {\n const decorators = cls.methods.flatMap(method =>\n method.decorators\n .filter(decorator => decorator.identity !== undefined && METHOD_DECORATORS.has(decorator.identity))\n .map(decorator => ({ name: decorator.name, location: decorator.location })),\n )\n if (decorators.length > 0) {\n ctx.store({\n kind: 'members',\n identity: cls.identity,\n displayName: cls.displayName,\n abstract: cls.abstract,\n decorators,\n })\n }\n return\n }\n for (const duplicate of consumers.slice(1)) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@${duplicate.name} is applied several times on ${cls.displayName}`,\n location: duplicate.location,\n hints: [`Keep a single @${duplicate.name}: a class consumes one queue`],\n })\n }\n\n const options = readConsumerOptions(consumer, cls, ctx)\n const token = ctx.registerProvider(cls, { scope: options.scope })\n const chain = classChain(cls, ctx)\n\n // messaging methods of the class and its bases: the nearest declaration wins, at the position of\n // the first declaration (base classes first)\n const merged = new Map<string, MemberAnalysis>()\n for (let index = chain.length - 1; index >= 0; index--) {\n const owner = chain[index] as ClassInfo\n for (const [name, member] of index === 0 ? own : analyzeMembers(owner, ctx)) merged.set(name, member)\n }\n const members = [...merged.values()]\n const handlers = members.flatMap(member => member.handlers)\n\n if (!members.some(member => member.onMessage > 0)) {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `@Consumer ${cls.displayName} has no @OnMessage handler`,\n location: consumer.location,\n hints: ['Decorate at least one public method with @OnMessage() (default handler) or @OnMessage(\"type\")'],\n })\n }\n checkHandlerTypes(cls.displayName, handlers, ctx)\n\n const errorHandlers = members.filter(member => member.errorHandler !== undefined)\n const errorHandler = errorHandlers[0]\n for (const extra of errorHandlers.slice(1)) {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `@Consumer ${cls.displayName} has several @OnError methods: ${errorHandlers.map(member => `${member.declaredBy}.${member.method}()`).join(', ')}`,\n location: extra.errorHandler as Location,\n hints: ['Keep a single @OnError method per consumer'],\n related: [{ message: 'First @OnError method', location: errorHandler?.errorHandler as Location }],\n })\n }\n\n ctx.store({\n kind: 'consumer',\n token,\n identity: cls.identity,\n displayName: cls.displayName,\n queue: options.queue,\n options: options.options,\n handlers,\n errorHandler: errorHandler?.method,\n chain: chain.map(owner => owner.identity),\n location: consumer.location,\n })\n}\n\n// ------------------------------------------------------------------------------------------ consumer\n\ninterface ConsumerOptions {\n /** Empty when invalid (reported). */\n readonly queue: string\n readonly scope: Scope\n readonly options: Readonly<Record<string, StaticValue>> | undefined\n}\n\n/** `@Consumer(queue)` / `@Consumer({ queue, scope?, concurrency?, deadLetter?, ...driver options })`. */\nfunction readConsumerOptions(decorator: DecoratorInfo, cls: ClassInfo, ctx: Context): ConsumerOptions {\n const invalid: ConsumerOptions = { queue: '', scope: 'singleton', options: undefined }\n const prefix = `@Consumer ${cls.displayName}`\n if (!decorator.called) return invalid // `@Consumer` without call: already reported\n const arg = decorator.args[0]\n if (arg === undefined) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `${prefix}: the queue to consume is required`,\n location: decorator.location,\n hints: [\"Write @Consumer('orders') or @Consumer({ queue: 'orders', concurrency: 5 })\"],\n })\n return invalid\n }\n if (!arg.evaluated) return invalid // not statically evaluable: already reported\n const value = arg.value\n if (typeof value === 'string') {\n if (value === '') {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `${prefix}: the queue must be a non-empty string`,\n location: arg.location,\n })\n }\n return { queue: value, scope: 'singleton', options: undefined }\n }\n if (!isRecord(value)) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `${prefix}: expected a queue name or an options object ({ queue, scope?, concurrency?, deadLetter? }), got ${describeValue(value)}`,\n location: arg.location,\n })\n return invalid\n }\n\n const fail = (key: string, message: string, hints?: readonly string[]): void => {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `${prefix}: ${message}`,\n location: propertyLocation(ctx.project, arg, key),\n ...(hints === undefined ? {} : { hints }),\n })\n }\n\n let queue = ''\n const rawQueue = value['queue']\n if (rawQueue === undefined) {\n fail('queue', 'the \"queue\" option is required', [\"Write @Consumer({ queue: 'orders', ... })\"])\n } else if (typeof rawQueue !== 'string' || rawQueue === '') {\n fail('queue', `\"queue\" must be a non-empty string, got ${describeValue(rawQueue)}`)\n } else {\n queue = rawQueue\n }\n\n let scope: Scope = 'singleton'\n const rawScope = value['scope']\n if (rawScope !== undefined) {\n if (typeof rawScope === 'string' && CONSUMER_SCOPES.includes(rawScope)) {\n scope = rawScope as Scope\n } else {\n fail('scope', `\"scope\" must be 'singleton', 'request' or 'transient', got ${describeValue(rawScope)}`)\n }\n }\n\n const concurrency = value['concurrency']\n if (\n concurrency !== undefined &&\n !(typeof concurrency === 'number' && Number.isSafeInteger(concurrency) && concurrency > 0)\n ) {\n fail('concurrency', `\"concurrency\" must be a positive integer, got ${describeValue(concurrency)}`)\n }\n\n const deadLetter = value['deadLetter']\n if (deadLetter !== undefined && deadLetter !== false && (typeof deadLetter !== 'string' || deadLetter === '')) {\n fail('deadLetter', `\"deadLetter\" must be a queue name or false, got ${describeValue(deadLetter)}`)\n } else if (deadLetter === queue && queue !== '') {\n fail('deadLetter', `the dead-letter queue cannot be the consumed queue \"${queue}\"`, [\n 'Use another queue (default: the driver naming, e.g. \"orders.dlq\"), or false to disable dead-lettering',\n ])\n }\n\n const options: Record<string, StaticValue> = {}\n for (const [key, option] of Object.entries(value)) {\n if (key === 'queue' || key === 'scope' || option === undefined) continue\n options[key] = option\n }\n return { queue, scope, options: Object.keys(options).length === 0 ? undefined : Object.freeze(options) }\n}\n\n/** The class and its analysable base classes (nearest first). */\nfunction classChain(cls: ClassInfo, ctx: Context): ClassInfo[] {\n const chain = [cls]\n const seen = new Set([cls.identity])\n let current = cls\n while (current.superClass !== undefined && chain.length < MAX_CHAIN) {\n const base = ctx.classInfo(current.superClass.identity)\n if (base === undefined || seen.has(base.identity)) break\n chain.push(base)\n seen.add(base.identity)\n current = base\n }\n return chain\n}\n\n/**\n * Handler selection checks, mirroring the runtime (`consumers.ts`): exact types first, then patterns\n * in declaration order, then the single default handler.\n */\nfunction checkHandlerTypes(consumer: string, handlers: readonly HandlerData[], ctx: Context): void {\n let fallback: HandlerData | undefined\n const exact = new Map<string, HandlerData>()\n const patterns: (HandlerData & { readonly type: string })[] = []\n const label = (handler: HandlerData): string => `${handler.declaredBy}.${handler.method}()`\n for (const handler of handlers) {\n const type = handler.type\n if (type === undefined) {\n if (fallback === undefined) {\n fallback = handler\n continue\n }\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `@Consumer ${consumer}: ${label(fallback)} and ${label(handler)} are both default @OnMessage() handlers`,\n location: handler.location,\n hints: ['Give one of them a message type: @OnMessage(\"order.created\")'],\n related: [{ message: 'First default handler', location: fallback.location }],\n })\n continue\n }\n const previous = isPattern(type) ? patterns.find(pattern => pattern.type === type) : exact.get(type)\n if (previous !== undefined) {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `@Consumer ${consumer}: several @OnMessage handlers for type \"${type}\" (${label(previous)} and ${label(handler)})`,\n location: handler.location,\n hints: ['A message type is handled by a single method: merge the handlers'],\n related: [{ message: `First handler of \"${type}\"`, location: previous.location }],\n })\n continue\n }\n if (!isPattern(type)) {\n exact.set(type, handler)\n continue\n }\n const covering = patterns.find(pattern => patternCovers(pattern.type, type))\n if (covering !== undefined) {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `@Consumer ${consumer}: the pattern \"${type}\" of ${label(handler)} never matches: every type it matches is matched first by \"${covering.type}\" (${label(covering)})`,\n location: handler.location,\n hints: ['Patterns are tried in declaration order (after exact types): declare the more specific pattern first'],\n related: [{ message: `Pattern \"${covering.type}\"`, location: covering.location }],\n })\n }\n patterns.push({ ...handler, type })\n }\n}\n\n// ------------------------------------------------------------------------------------------- members\n\n/** Messaging methods declared by `cls` itself, by name, in declaration order. */\nfunction analyzeMembers(cls: ClassInfo, ctx: Context): Map<string, MemberAnalysis> {\n const members = new Map<string, MemberAnalysis>()\n for (const method of cls.methods) {\n const member = analyzeMethod(cls, method, ctx)\n if (member !== undefined) members.set(method.name, member)\n }\n return members\n}\n\nfunction analyzeMethod(cls: ClassInfo, method: MethodInfo, ctx: Context): MemberAnalysis | undefined {\n const onMessage = decoratorsOf(method.decorators, MessagingDecorator.OnMessage)\n const retry = decoratorsOf(method.decorators, MessagingDecorator.Retry)\n const onError = decoratorsOf(method.decorators, MessagingDecorator.OnError)\n const decoratedParams = method.params.some(param => param.decorators.some(isParameterDecorator))\n if (onMessage.length === 0 && retry.length === 0 && onError.length === 0 && !decoratedParams) return undefined\n\n const where = `${cls.displayName}.${method.name}()`\n const primary = onMessage[0] ?? onError[0]\n if (primary !== undefined) checkMethodShape(method, primary, where, ctx)\n for (const duplicate of [...retry.slice(1), ...onError.slice(1)]) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@${duplicate.name} is applied several times on ${where}`,\n location: duplicate.location,\n hints: [`Keep a single @${duplicate.name}`],\n })\n }\n if (onMessage.length > 0 && onError[0] !== undefined) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `${where} cannot be both an @OnMessage handler and the @OnError method`,\n location: onError[0].location,\n hints: ['Declare the error handler in a separate method'],\n })\n }\n if (onMessage.length === 0 && retry[0] !== undefined) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@Retry has no effect on ${where}: it is not an @OnMessage handler`,\n location: retry[0].location,\n hints: ['Add @OnMessage() to the method, or remove @Retry'],\n })\n }\n\n let handlers: HandlerData[] = []\n if (onMessage.length > 0) {\n const policy: RetryPolicyData | undefined =\n retry[0] === undefined ? undefined : normalizeRetryDecorator(retry[0], where, ctx)\n const params = analyzeHandlerParams(method, where, ctx)\n handlers = onMessage.flatMap(decorator => {\n const type = messageType(decorator, where, ctx)\n if (type === false) return []\n return [\n Object.freeze({\n method: method.name,\n type,\n retry: policy,\n params,\n declaredBy: cls.displayName,\n location: decorator.location,\n }),\n ]\n })\n } else {\n reportStrayParameterDecorators(method, where, onError.length > 0, ctx)\n }\n\n const errorHandler = onMessage.length === 0 ? onError[0] : undefined\n if (errorHandler !== undefined) checkErrorHandler(method, errorHandler, where, ctx)\n return {\n method: method.name,\n declaredBy: cls.displayName,\n onMessage: onMessage.length,\n handlers,\n errorHandler: errorHandler?.location,\n }\n}\n\n/** Handlers are called by the generated code: `consumer.method(...)`. */\nfunction checkMethodShape(method: MethodInfo, decorator: DecoratorInfo, where: string, ctx: Context): void {\n const name = `@${decorator.name}`\n let problem: { message: string; hint: string } | undefined\n if (method.kind !== 'method') {\n problem = { message: `${name} cannot be applied to the accessor ${where}`, hint: 'Use a regular method' }\n } else if (method.static) {\n problem = {\n message: `${name} cannot be applied to the static method ${where}`,\n hint: 'Handlers are called on the consumer instance: remove `static`',\n }\n } else if (method.privateName) {\n problem = {\n message: `${name} cannot be applied to the #private method ${where}`,\n hint: 'Use a public method: the generated code calls it',\n }\n } else if (method.visibility !== 'public') {\n problem = {\n message: `${where} must be public: ${name} methods are called by the generated code`,\n hint: `Remove the '${method.visibility}' modifier`,\n }\n } else if (method.computed) {\n problem = {\n message: `${name} cannot be applied to ${where}: computed method names are not supported`,\n hint: 'Use a plain method name',\n }\n } else if (method.generator) {\n problem = {\n message: `${name} cannot be applied to the generator method ${where}`,\n hint: 'Use a regular (or async) method',\n }\n }\n if (problem !== undefined) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: problem.message,\n location: decorator.location,\n hints: [problem.hint],\n })\n }\n}\n\n/** Type of an `@OnMessage` decorator: a string, `undefined` (default handler) or `false` (invalid). */\nfunction messageType(decorator: DecoratorInfo, where: string, ctx: Context): string | undefined | false {\n const arg = decorator.args[0]\n if (arg === undefined || (arg.evaluated && arg.value === undefined)) return undefined\n if (!arg.evaluated) return false // not statically evaluable: already reported\n if (typeof arg.value !== 'string') {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@OnMessage on ${where} expects a message type (a string), got ${describeValue(arg.value)}`,\n location: arg.location,\n hints: ['Use @OnMessage() for the default handler'],\n })\n return false\n }\n if (arg.value === '') {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `The @OnMessage type of ${where} must be a non-empty string`,\n location: arg.location,\n hints: ['Use @OnMessage() for the default handler'],\n })\n return false\n }\n return arg.value\n}\n\n/** The `@OnError` method is called as `consumer[method](error, message)`. */\nfunction checkErrorHandler(method: MethodInfo, decorator: DecoratorInfo, where: string, ctx: Context): void {\n const required = method.params.filter(param => !param.optional && !param.hasDefault && !param.rest).length\n if (required > 2) {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `The @OnError method ${where} has ${required} required parameters: it is called with (error, message)`,\n location: method.location,\n hints: ['Declare onError(error: unknown, message: InboundMessage)'],\n })\n }\n if (method.returnType !== undefined && !isErrorHandlerResult(ctx.types.awaited(method.returnType))) {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `The @OnError method ${where} returns '${ctx.types.format(method.returnType)}': return 'ack' to acknowledge the message, or nothing to dead-letter it`,\n location: decorator.location,\n hints: [\"Declare the return type `'ack' | undefined` (or `void`)\"],\n })\n }\n}\n\n// ---------------------------------------------------------------------------------------- parameters\n\nfunction analyzeHandlerParams(method: MethodInfo, where: string, ctx: Context): readonly HandlerParamData[] {\n return Object.freeze(method.params.map(param => analyzeHandlerParam(param, where, ctx)))\n}\n\nfunction analyzeHandlerParam(param: ParameterInfo, where: string, ctx: Context): HandlerParamData {\n const decorators = parameterDecorators(param)\n const decorator = decorators[0]\n if (decorator === undefined) {\n const foreign = foreignParameterDecorator(param)\n if (foreign !== undefined) {\n // e.g. `Headers` auto-imported from '@znight/http': one precise error instead of \"no decorator\"\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@${foreign.decorator.name} on parameter '${param.name}' of ${where} is imported from '${foreign.module}': @OnMessage handler parameters use ${foreign.name} from '${RUNTIME_MODULE}'`,\n location: foreign.decorator.location,\n hints: [`Import it from '${RUNTIME_MODULE}': import { ${foreign.name} } from '${RUNTIME_MODULE}'`],\n })\n return { kind: 'undefined' }\n }\n if (param.optional || param.hasDefault || param.rest) return { kind: 'undefined' }\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `Parameter '${param.name}' of ${where} has no @Message(), @Headers() or @Ctx() decorator`,\n location: param.location,\n hints: [\n 'Every handler parameter is extracted from the message: @Message(schema?) for the payload, @Headers(name?) for the headers, @Ctx() for the InboundMessage',\n ],\n })\n return { kind: 'undefined' }\n }\n if (decorators.length > 1) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `Parameter '${param.name}' of ${where} has several messaging decorators (${decorators.map(found => `@${found.name}`).join(', ')})`,\n location: (decorators[1] as DecoratorInfo).location,\n hints: ['Keep a single one'],\n })\n }\n if (param.rest) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@${decorator.name} cannot be applied to the rest parameter '...${param.name}' of ${where}`,\n location: decorator.location,\n })\n return { kind: 'undefined' }\n }\n switch (decorator.identity) {\n case MessagingDecorator.Message:\n return messageParam(param, decorator, where, ctx)\n case MessagingDecorator.Headers:\n return headersParam(param, decorator, where, ctx)\n default:\n return { kind: 'message', narrow: narrowsPayload(param.type, ctx.types) }\n }\n}\n\n/** `@Message()` / `@Message(schema)`. */\nfunction messageParam(param: ParameterInfo, decorator: DecoratorInfo, where: string, ctx: Context): HandlerParamData {\n const arg = decorator.args[0]\n if (arg === undefined || (arg.evaluated && arg.value === undefined)) {\n checkUnvalidated(param, decorator, where, ctx)\n return { kind: 'payload' }\n }\n if (arg.ref !== undefined) {\n if (isClassReference(arg.ref)) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@Message(${arg.text}) on ${where}: '${arg.ref.name}' is a class, not a Standard Schema`,\n location: arg.location,\n hints: [\n 'Pass a Standard Schema (Zod, Valibot, ArkType...): export const OrderPlaced = z.object({ ... })',\n 'Or inject the raw payload with @Message() and validate it in the handler',\n ],\n })\n return { kind: 'undefined' }\n }\n return { kind: 'validated', schema: arg.ref }\n }\n if (!arg.evaluated) return { kind: 'undefined' } // unexported or invalid reference: already reported\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@Message on ${where} expects a Standard Schema (Zod, Valibot, ArkType...), got ${describeValue(arg.value)}`,\n location: arg.location,\n hints: [\n 'Declare the schema with `export const OrderPlaced = z.object({ ... })` and pass it: @Message(OrderPlaced)',\n ],\n })\n return { kind: 'undefined' }\n}\n\n/** `@Headers()` / `@Headers(name)`. */\nfunction headersParam(param: ParameterInfo, decorator: DecoratorInfo, where: string, ctx: Context): HandlerParamData {\n const arg = decorator.args[0]\n if (arg === undefined || (arg.evaluated && arg.value === undefined)) return { kind: 'headers' }\n if (!arg.evaluated) return { kind: 'undefined' } // not statically evaluable: already reported\n const name = arg.value\n if (typeof name !== 'string' || name === '') {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@Headers on ${where} expects a header name (a non-empty string), got ${describeValue(name)}`,\n location: arg.location,\n hints: ['Use @Headers() to inject every header'],\n })\n return { kind: 'undefined' }\n }\n if (!param.optional && !param.hasDefault && !acceptsUndefined(param.type)) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'warning',\n message: `@Headers(${JSON.stringify(name)}) injects 'string | undefined' (the header may be missing) but parameter '${param.name}' of ${where} is typed '${ctx.types.format(param.type)}'`,\n location: param.typeLocation,\n hints: [`Declare it '${param.name}?: string' or '${param.name}: string | undefined', or give it a default value`],\n })\n }\n return { kind: 'header', name }\n}\n\n/** ZNIGHT017: a structured payload injected without schema is trusted blindly. */\nfunction checkUnvalidated(param: ParameterInfo, decorator: DecoratorInfo, where: string, ctx: Context): void {\n const { type } = ctx.types.stripNullish(param.type)\n if (isSafePayloadType(type)) return\n const typed =\n type.kind === 'opaque' && type.reason === 'missing-annotation'\n ? 'has no type annotation'\n : `is typed '${ctx.types.format(param.type)}'`\n ctx.report({\n code: UNVALIDATED_INPUT,\n severity: ctx.options.strictValidation ? 'error' : 'warning',\n message: `Unvalidated message payload: parameter '${param.name}' of ${where} ${typed} but @Message() has no schema`,\n location: decorator.location,\n hints: [\n 'Validate it with a Standard Schema (Zod, Valibot, ArkType...): @Message(OrderPlaced)',\n \"Or declare the parameter as 'unknown' and check it in the handler\",\n ],\n })\n}\n\n/** Methods whose parameters carry messaging decorators without being `@OnMessage` handlers. */\nfunction reportStrayParameterDecorators(method: MethodInfo, where: string, errorHandler: boolean, ctx: Context): void {\n // a method handled by another extension (an HTTP route...): the decorator comes from the wrong package\n const owner = errorHandler ? undefined : foreignHandler(method)\n for (const param of method.params) {\n for (const decorator of parameterDecorators(param)) {\n let hint = 'Add @OnMessage() to the method, or remove the decorator'\n if (errorHandler) hint = '@OnError methods are called with (error, message): remove the decorator'\n else if (owner !== undefined) {\n hint = `${where} is a @${owner.decorator.name} handler: use the parameter decorators of '${owner.module}'`\n }\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message:\n owner === undefined\n ? `@${decorator.name} has no effect on parameter '${param.name}' of ${where}: it is not an @OnMessage handler`\n : `@${decorator.name} (from '${RUNTIME_MODULE}') has no effect on parameter '${param.name}' of ${where}: it is not an @OnMessage handler`,\n location: decorator.location,\n hints: [hint],\n })\n }\n }\n}\n\n/** A decorator, with the module and the export name of its identity (`'@znight/http#Get'`). */\ninterface ForeignDecorator {\n readonly decorator: DecoratorInfo\n readonly module: string\n readonly name: string\n}\n\nfunction splitIdentity(decorator: DecoratorInfo): ForeignDecorator | undefined {\n const identity = decorator.identity\n const separator = identity?.lastIndexOf('#') ?? -1\n if (identity === undefined || separator <= 0) return undefined\n return { decorator, module: identity.slice(0, separator), name: identity.slice(separator + 1) }\n}\n\n/**\n * A parameter decorator named like a messaging one (`Headers`, `Ctx`, `Message`) but imported from\n * another package (`@znight/http` has `Headers` and `Ctx` too).\n */\nfunction foreignParameterDecorator(param: ParameterInfo): ForeignDecorator | undefined {\n for (const decorator of param.decorators) {\n const split = splitIdentity(decorator)\n if (split === undefined || split.module === RUNTIME_MODULE) continue\n if (PARAMETER_DECORATORS.has(`${RUNTIME_MODULE}#${split.name}`)) return split\n }\n return undefined\n}\n\n/** The decorator through which another extension handles the method (`@Get` of `@znight/http`...). */\nfunction foreignHandler(method: MethodInfo): ForeignDecorator | undefined {\n for (const decorator of method.decorators) {\n const owner = decorator.owner\n if (owner === undefined || owner === EXTENSION_NAME || owner === 'core' || owner === 'manifest') continue\n const split = splitIdentity(decorator)\n if (split !== undefined) return split\n }\n return undefined\n}\n\n// ------------------------------------------------------------------------------------------- helpers\n\nfunction decoratorsOf(decorators: readonly DecoratorInfo[], identity: string): DecoratorInfo[] {\n return decorators.filter(decorator => decorator.identity === identity)\n}\n\n/**\n * Messaging decorators of a parameter. De-duplicated by position: the compiler (0.1) reports the\n * decorators of a parameter with a default value (`@Headers('x') x = 'a'`) twice.\n */\nfunction parameterDecorators(param: ParameterInfo): DecoratorInfo[] {\n const seen = new Set<number>()\n return param.decorators.filter(decorator => {\n if (!isParameterDecorator(decorator) || seen.has(decorator.location.start)) return false\n seen.add(decorator.location.start)\n return true\n })\n}\n\nfunction isParameterDecorator(decorator: DecoratorInfo): boolean {\n return decorator.identity !== undefined && PARAMETER_DECORATORS.has(decorator.identity)\n}\n\n/** A reference to a class declaration (`@Message(OrderDto)`). */\nfunction isClassReference(ref: ValueRef): boolean {\n const symbol = ref.symbol\n return symbol.kind === 'declaration' && symbol.declaration.kind === 'class'\n}\n\n/** Primitive and binary payload types need no schema (`unknown` is honest, `any` is not). */\nfunction isSafePayloadType(type: TypeInfo): boolean {\n switch (type.kind) {\n case 'primitive':\n return type.name !== 'any' && type.name !== 'object'\n case 'literal':\n return true\n case 'union':\n return type.types.every(isSafePayloadType)\n case 'reference':\n return BINARY_TYPES.has(type.identity)\n default:\n return false\n }\n}\n\n/** Whether `undefined` is assignable to the type (unknown types are given the benefit of the doubt). */\nfunction acceptsUndefined(type: TypeInfo): boolean {\n switch (type.kind) {\n case 'primitive':\n return type.name === 'any' || type.name === 'unknown' || type.name === 'undefined' || type.name === 'void'\n case 'union':\n return type.types.some(acceptsUndefined)\n case 'opaque':\n case 'typeParameter':\n return true\n default:\n return false\n }\n}\n\n/** Valid results of an `@OnError` method: `'ack'`, nothing (`void`, `undefined`), or unknown types. */\nfunction isErrorHandlerResult(type: TypeInfo): boolean {\n switch (type.kind) {\n case 'primitive':\n return ['void', 'undefined', 'any', 'unknown', 'never'].includes(type.name)\n case 'literal':\n return type.value === 'ack'\n case 'union':\n return type.types.every(isErrorHandlerResult)\n case 'promise':\n return isErrorHandlerResult(type.inner)\n case 'opaque':\n case 'typeParameter':\n return true\n default:\n return false\n }\n}\n\n/** `@Ctx() message: InboundMessage<Order>` narrows the payload: the invoker casts `m`. */\nfunction narrowsPayload(type: TypeInfo, types: TypeHelpers): boolean {\n const { type: inner } = types.stripNullish(type)\n if (inner.kind !== 'reference' || inner.identity !== INBOUND_MESSAGE_IDENTITY) return false\n const payload = inner.typeArgs[0]\n return (\n payload !== undefined && !(payload.kind === 'primitive' && (payload.name === 'unknown' || payload.name === 'any'))\n )\n}\n","/**\n * `generate` of the messaging extension: `metadata.extensions.messaging` (README \"Compiler contract\",\n * spec §9.2). Consumers are sorted by token; handlers keep their declaration order.\n *\n * ```ts\n * {\n * consumers: [{\n * token: 'src/orders/order.consumer.ts#OrderConsumer',\n * queue: 'orders',\n * handlers: [{\n * method: 'placed',\n * type: 'order.placed',\n * retry: { attempts: 5, backoff: 'exponential', delay: 500, maxDelay: 30000 },\n * invoke: async (c: OrderConsumer, m: InboundMessage) => c.placed(await validateMessage(OrderPlaced, m.payload)),\n * }],\n * errorHandler: 'onError',\n * }],\n * }\n * ```\n */\nimport type { GenerateContext, GenInput, GenNode } from '@znight/compiler'\nimport type { ConsumerData, HandlerData, HandlerParamData, MessagingData } from './data.ts'\n\nimport { compareStrings, RUNTIME_MODULE } from './constants.ts'\n\ntype Context = GenerateContext<MessagingData>\n\n/**\n * Imports of the runtime helpers, created on first use only: an import the module does not use would\n * break `noUnusedLocals`.\n */\ninterface Helpers {\n inboundMessage(): GenNode\n validateMessage(): GenNode\n messageHeader(): GenNode\n}\n\n/** Builds the messaging section; `undefined` (no section) when the application has no consumer. */\nexport function generateMessaging(ctx: Context): GenNode | undefined {\n const consumers = ctx.stored\n .filter((data): data is ConsumerData => data.kind === 'consumer')\n .sort((a, b) => compareStrings(a.token, b.token))\n if (consumers.length === 0) return undefined\n const helpers = lazyHelpers(ctx)\n return ctx.obj([['consumers', ctx.arr(consumers.map(consumer => consumerNode(ctx, consumer, helpers)))]])\n}\n\nfunction consumerNode(ctx: Context, consumer: ConsumerData, helpers: Helpers): GenNode {\n let classType: GenNode | undefined\n const consumerType = (): GenNode => {\n classType ??= ctx.importType(consumer.identity)\n return classType\n }\n const entries: [string, GenInput][] = [\n ['token', consumer.token],\n ['queue', consumer.queue],\n ]\n if (consumer.options !== undefined) entries.push(['options', ctx.lit(consumer.options)])\n entries.push([\n 'handlers',\n ctx.arr(consumer.handlers.map(handler => handlerNode(ctx, handler, consumerType, helpers))),\n ])\n if (consumer.errorHandler !== undefined) entries.push(['errorHandler', consumer.errorHandler])\n return ctx.obj(entries)\n}\n\nfunction handlerNode(ctx: Context, handler: HandlerData, consumerType: () => GenNode, helpers: Helpers): GenNode {\n const entries: [string, GenInput][] = [['method', handler.method]]\n if (handler.type !== undefined) entries.push(['type', handler.type])\n if (handler.retry !== undefined) entries.push(['retry', ctx.lit({ ...handler.retry })])\n entries.push(['invoke', invokeNode(ctx, handler, consumerType, helpers)])\n return ctx.obj(entries)\n}\n\n/**\n * `(c: Consumer, m: InboundMessage) => c.method(...args)`, `async` only when it awaits a schema\n * validation. `m` is omitted when no argument uses it (`noUnusedParameters`).\n */\nfunction invokeNode(ctx: Context, handler: HandlerData, consumerType: () => GenNode, helpers: Helpers): GenNode {\n const params = [...handler.params]\n while (params.length > 0 && params[params.length - 1]?.kind === 'undefined') params.pop()\n if (params.length === 0) {\n return ctx.arrow([['c', consumerType()]], c => ctx.call(ctx.member(c, handler.method)))\n }\n return ctx.arrow(\n [\n ['c', consumerType()],\n ['m', helpers.inboundMessage()],\n ],\n (c, m) =>\n ctx.call(\n ctx.member(c, handler.method),\n params.map(param => argumentNode(ctx, param, m as GenNode, helpers)),\n ),\n { async: params.some(param => param.kind === 'validated') },\n )\n}\n\nfunction argumentNode(ctx: Context, param: HandlerParamData, m: GenNode, helpers: Helpers): GenNode {\n switch (param.kind) {\n case 'payload':\n return ctx.code`${ctx.member(m, 'payload')} as never`\n case 'validated':\n return ctx.code`await ${ctx.call(helpers.validateMessage(), [ctx.importValue(param.schema), ctx.member(m, 'payload')])}`\n case 'headers':\n return ctx.member(m, 'headers')\n case 'header':\n return ctx.call(helpers.messageHeader(), [m, param.name])\n case 'message':\n return param.narrow ? ctx.code`${m} as ${helpers.inboundMessage()}<never>` : m\n case 'undefined':\n return ctx.lit(undefined)\n }\n}\n\nfunction lazyHelpers(ctx: Context): Helpers {\n const cache = new Map<string, GenNode>()\n const get = (name: string, type: boolean): GenNode => {\n let node = cache.get(name)\n if (node === undefined) {\n node = ctx.importFrom(RUNTIME_MODULE, name, type ? { type: true } : {})\n cache.set(name, node)\n }\n return node\n }\n return {\n inboundMessage: () => get('InboundMessage', true),\n validateMessage: () => get('validateMessage', false),\n messageHeader: () => get('messageHeader', false),\n }\n}\n","/**\n * `validate` of the messaging extension: checks that need every consumer of the application.\n */\nimport type { ValidateContext } from '@znight/compiler'\nimport type { ConsumerData, MemberClassData, MessagingData } from './data.ts'\n\nimport { compareStrings, INVALID_CONSUMER, INVALID_DECORATOR } from './constants.ts'\n\n/** Cross-consumer checks: one consumer per queue, messaging decorators outside of consumers. */\nexport function validateMessaging(ctx: ValidateContext<MessagingData>): void {\n const consumers = ctx.stored\n .filter((data): data is ConsumerData => data.kind === 'consumer')\n .sort((a, b) => compareStrings(a.token, b.token))\n\n // a queue is consumed by a single @Consumer class (the plugin refuses to boot otherwise)\n const byQueue = new Map<string, ConsumerData>()\n for (const consumer of consumers) {\n if (consumer.queue === '') continue\n const first = byQueue.get(consumer.queue)\n if (first === undefined) {\n byQueue.set(consumer.queue, consumer)\n continue\n }\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `${first.displayName} and ${consumer.displayName} both consume \"${consumer.queue}\"`,\n location: consumer.location,\n hints: [\n 'A queue is consumed by a single @Consumer class: merge the handlers, or route by type with @OnMessage(type)',\n ],\n related: [{ message: `${first.displayName} consumes \"${consumer.queue}\"`, location: first.location }],\n })\n }\n\n // @OnMessage / @OnError / @Retry on a class that is neither a consumer nor one of its base classes\n const bases = new Set(consumers.flatMap(consumer => consumer.chain))\n for (const data of ctx.stored) {\n if (data.kind !== 'members' || data.abstract || bases.has(data.identity)) continue\n reportNotAConsumer(data, ctx)\n }\n}\n\nfunction reportNotAConsumer(data: MemberClassData, ctx: ValidateContext<MessagingData>): void {\n for (const decorator of data.decorators) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@${decorator.name} has no effect: ${data.displayName} is not a @Consumer`,\n location: decorator.location,\n hints: [\n `Add @Consumer('queue') to ${data.displayName}, or extend it from a @Consumer class`,\n 'Base classes holding shared handlers should be abstract',\n ],\n })\n }\n}\n","/**\n * `@znight/messaging/compiler`: the compiler extension of `@znight/messaging` (spec §5, §6.5, §9.2).\n *\n * Loaded by `@znight/compiler` through the package manifest (`package.json#znight.compiler`). It reads\n * `@Consumer` classes and their `@OnMessage` / `@Retry` / `@OnError` methods and `@Message` /\n * `@Headers` / `@Ctx` parameters, registers consumers as providers, reports invalid consumers at build\n * time and generates `metadata.extensions.messaging`.\n *\n * This entry only `import type`s from `@znight/compiler` and never loads the messaging runtime.\n */\nimport type { CompilerExtension, DecoratorSpec } from '@znight/compiler'\nimport type { MessagingData } from './data.ts'\n\nimport { analyzeMessagingClass } from './analyze.ts'\nimport { EXTENSION_NAME, MessagingDecorator } from './constants.ts'\nimport { generateMessaging } from './generate.ts'\nimport { validateMessaging } from './validate.ts'\n\nexport type {\n ConsumerData,\n HandlerData,\n HandlerParamData,\n MemberClassData,\n MessagingData,\n RetryPolicyData,\n} from './data.ts'\n\n/**\n * Decorators owned by the extension. `static` arguments must be statically evaluable (queue names,\n * types, retry options, header names); the `@Message` schema is a `value` (an exported binding).\n */\nconst decorators: Readonly<Record<string, DecoratorSpec>> = Object.freeze({\n [MessagingDecorator.Consumer]: { targets: ['class'], params: ['static'] },\n [MessagingDecorator.OnMessage]: { targets: ['method'], params: ['static'] },\n [MessagingDecorator.Retry]: { targets: ['method'], params: ['static'] },\n [MessagingDecorator.OnError]: { targets: ['method'], params: [] },\n [MessagingDecorator.Message]: { targets: ['parameter'], params: ['value'] },\n [MessagingDecorator.Headers]: { targets: ['parameter'], params: ['static'] },\n [MessagingDecorator.Ctx]: { targets: ['parameter'], params: [] },\n} satisfies Record<string, DecoratorSpec>)\n\n/** The `@znight/messaging` compiler extension. */\nexport const messagingCompilerExtension: CompilerExtension<MessagingData> = Object.freeze({\n apiVersion: 1,\n name: EXTENSION_NAME,\n decorators,\n analyzeClass: analyzeMessagingClass,\n validate: validateMessaging,\n generate: generateMessaging,\n})\n\nexport default messagingCompilerExtension\n"],"mappings":";;AAOA,MAAa,iBAAiB;;AAG9B,MAAa,iBAAiB;;AAG9B,MAAa,qBAQT,OAAO,OAAO;CAChB,UAAU;CACV,WAAW;CACX,OAAO;CACP,SAAS;CACT,SAAS;CACT,SAAS;CACT,KAAK;AACP,CAAC;;AAMD,MAAa,oCAAyC,IAAI,IAAI;CAC5D,mBAAmB;CACnB,mBAAmB;CACnB,mBAAmB;AACrB,CAAC;;AAGD,MAAa,uCAA4C,IAAI,IAAI;CAC/D,mBAAmB;CACnB,mBAAmB;CACnB,mBAAmB;AACrB,CAAC;;AAGD,MAAa,oBAA+B;;AAE5C,MAAa,mBAA8B;;AAE3C,MAAa,oBAA+B;;;;;AAM5C,MAAa,kBAAkB;;AAE/B,MAAa,yBAAyB;;AAEtC,MAAa,qBAAqB;;AAGlC,MAAa,kBAAqC;CAAC;CAAa;CAAW;AAAW;;AAGtF,SAAgB,eAAe,GAAW,GAAmB;CAC3D,IAAI,MAAM,GAAG,OAAO;CACpB,OAAO,IAAI,IAAI,KAAK;AACtB;;;;;;;;ACjEA,SAAgB,UAAU,MAAuB;CAC/C,OAAO,KAAK,SAAS,GAAG;AAC1B;;;;;;;AAaA,SAAgB,cAAc,OAAe,OAAwB;CACnE,OAAO,OAAO,OAAO,OAAO,IAAI;AAClC;;AAGA,SAAS,OAAO,SAAiB,SAAiB,mBAAqC;CACrF,MAAM,IAAI,cAAc,OAAO;CAC/B,MAAM,IAAI,oBAAoB,cAAc,OAAO,IAAI;CAEvD,IAAI,WAAsB,IAAI,MAAe,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,KAAK;CACrE,SAAS,KAAK;CACd,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE,QAAQ,KAAK;EAClC,MAAM,OAAO,EAAE,IAAI;EACnB,MAAM,UAAqB,IAAI,MAAe,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,KAAK;EACtE,QAAQ,KAAK,SAAS,OAAO,SAAS,OAAO;EAC7C,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE,QAAQ,KAC7B,IAAI,SAAS,KACX,QAAQ,KAAK,SAAS,OAAO,QAAQ,QAAQ,IAAI,OAAO;OACnD;GACL,MAAM,cAAc,EAAE,IAAI;GAC1B,QAAQ,KAAK,SAAS,IAAI,OAAO,QAAQ,gBAAgB,QAAQ,EAAE,qBAAqB,gBAAgB;EAC1G;EAEF,WAAW;CACb;CACA,OAAO,SAAS,EAAE,YAAY;AAChC;;AAGA,SAAS,cAAc,SAAyB;CAC9C,OAAO,QAAQ,QAAQ,WAAW,GAAG;AACvC;;;AC7CA,SAAgB,SAAS,OAAoE;CAC3F,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG,OAAO;CAChF,MAAM,YAAqB,OAAO,eAAe,KAAK;CACtD,OAAO,cAAc,OAAO,aAAa,cAAc;AACzD;;AAGA,SAAgB,cAAc,OAA4B;CACxD,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,IAAI,UAAU,MAAM,OAAO;CAC3B,IAAI,OAAO,UAAU,UAAU,OAAO,KAAK,UAAU,KAAK;CAC1D,IAAI,OAAO,UAAU,UAAU,OAAO,GAAG,MAAM;CAC/C,IAAI,OAAO,UAAU,UAAU,OAAO,OAAO,KAAK;CAClD,IAAI,MAAM,QAAQ,KAAK,GAAG,OAAO;CACjC,OAAO,SAAS,KAAK,IAAI,cAAc,mBAAoB,MAAqC,QAAQ,IAAI;AAC9G;;;;;AAMA,SAAgB,iBAAiB,SAAkB,KAAc,KAAuB;CACtF,IAAI,OAAmB,IAAI;CAC3B,OACE,KAAK,SAAS,oBACd,KAAK,SAAS,2BACd,KAAK,SAAS,yBACd,KAAK,SAAS,2BAEd,OAAO,KAAK;CAEd,IAAI,KAAK,SAAS,oBAAoB,OAAO,IAAI;CACjD,KAAK,MAAM,YAAY,KAAK,YAAY;EACtC,IAAI,SAAS,SAAS,cAAc,SAAS,UAAU;EACvD,MAAM,EAAE,KAAK,SAAS;EAGtB,KADE,KAAK,SAAS,eAAe,KAAK,OAAO,KAAK,SAAS,aAAa,OAAO,KAAK,UAAU,YAAY,KAAK,WAC/F,KAAK,OAAO,QAAQ,QAAQ,IAAI,SAAS,IAAI,CAAC,EAAE,SAAS,QAAQ,KAAK,IAAI;CAC1F;CACA,OAAO,IAAI;AACb;;AAGA,SAAgB,QAAQ,MAAc,YAAmD;CACvF,IAAI;CACJ,IAAI,eAAe,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,IAAI;CAC9D,KAAK,MAAM,aAAa,YAAY;EAClC,MAAM,WAAW,aAAa,KAAK,YAAY,GAAG,UAAU,YAAY,CAAC;EACzE,IAAI,WAAW,cAAc;GAC3B,OAAO;GACP,eAAe;EACjB;CACF;CACA,OAAO;AACT;AAEA,SAAS,aAAa,GAAW,GAAmB;CAClD,IAAI,WAAW,MAAM,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,GAAG,UAAU,KAAK;CACvE,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE,QAAQ,KAAK;EAClC,MAAM,UAAU,CAAC,CAAC;EAClB,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE,QAAQ,KAAK;GAClC,MAAM,gBAAgB,SAAS,IAAI,MAAM,MAAM,EAAE,IAAI,OAAO,EAAE,IAAI,KAAK,IAAI;GAC3E,QAAQ,KAAK,KAAK,KAAK,SAAS,MAAM,KAAK,IAAI,QAAQ,IAAI,MAAM,KAAK,GAAG,YAAY;EACvF;EACA,WAAW;CACb;CACA,OAAO,SAAS,EAAE,WAAW;AAC/B;;AC1DA,MAAM,gBAAmC;CAAC;CAAY;CAAW;CAAS;AAAU;;;;;;;AAQpF,SAAgB,wBACd,WACA,OACA,KAC6B;CAC7B,IAAI,CAAC,UAAU,QAAQ,OAAO,KAAA;CAC9B,MAAM,MAAM,UAAU,KAAK;CAC3B,IAAI,QAAQ,KAAA,GAAW;EACrB,IAAI,OAAO;GACT,MAAM;GACN,UAAU;GACV,SAAS,aAAa,MAAM;GAC5B,UAAU,UAAU;GACpB,OAAO,CAAC,kFAAkF;EAC5F,CAAC;EACD;CACF;CACA,IAAI,CAAC,IAAI,WAAW,OAAO,KAAA;CAC3B,MAAM,UAAU,IAAI;CACpB,IAAI,CAAC,SAAS,OAAO,GAAG;EACtB,IAAI,OAAO;GACT,MAAM;GACN,UAAU;GACV,SAAS,aAAa,MAAM,8EAA8E,cAAc,OAAO;GAC/H,UAAU,IAAI;EAChB,CAAC;EACD;CACF;CAEA,IAAI,QAAQ;CACZ,MAAM,QAAQ,KAAa,SAAiB,UAAoC;EAC9E,QAAQ;EACR,IAAI,OAAO;GACT,MAAM;GACN,UAAU;GACV,SAAS,aAAa,MAAM,IAAI;GAChC,UAAU,iBAAiB,IAAI,SAAS,KAAK,GAAG;GAChD,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;EACzC,CAAC;CACH;CAEA,KAAK,MAAM,OAAO,OAAO,KAAK,OAAO,GAAG;EACtC,IAAI,cAAc,SAAS,GAAG,GAAG;EACjC,MAAM,aAAa,QAAQ,KAAK,aAAa;EAC7C,KAAK,KAAK,mBAAmB,IAAI,IAAI,CACnC,eAAe,KAAA,IACX,kBAAkB,cAAc,KAAK,IAAI,MACzC,iBAAiB,WAAW,oBAAoB,cAAc,KAAK,IAAI,GAC7E,CAAC;CACH;CAEA,MAAM,WAAW,QAAQ;CACzB,IAAI,aAAa,KAAA,GACf,KAAK,YAAY,4BAA0B,CACzC,kFACF,CAAC;MACI,IAAI,CAAC,UAAU,QAAQ,KAAK,WAAW,KAAK,WAAA,KACjD,KACE,YACA,+CAA+C,mBAAmB,QAAQ,cAAc,QAAQ,KAChG,CAAC,kFAAkF,CACrF;CAGF,MAAM,aAAa,QAAQ;CAC3B,MAAM,UAAU,eAAe,KAAA,IAAY,kBAAkB;CAC7D,IAAI,YAAY,WAAW,YAAY,eACrC,KAAK,WAAW,mDAAmD,cAAc,OAAO,GAAG;CAG7F,MAAM,WAAW,QAAQ;CACzB,MAAM,QAAQ,aAAa,KAAA,IAAY,yBAAyB;CAChE,MAAM,aAAa,WAAW,KAAK;CACnC,IAAI,CAAC,YACH,KAAK,SAAS,6DAA6D,cAAc,KAAK,GAAG;CAGnG,MAAM,WAAW,QAAQ;CACzB,IAAI,aAAa,KAAA,GAAW;EAC1B,IAAI,CAAC,WAAW,QAAQ,KAAM,cAAc,WAAW,OACrD,KACE,YACA,8DAA8D,aAAa,KAAK,MAAM,KAAK,GAAG,QAAQ,cAAc,QAAQ,GAC9H;OACK,IAAI,YAAY,SACrB,IAAI,OAAO;GACT,MAAM;GACN,UAAU;GACV,SAAS,aAAa,MAAM;GAC5B,UAAU,iBAAiB,IAAI,SAAS,KAAK,UAAU;GACvD,OAAO,CAAC,gDAAgD;EAC1D,CAAC;CAEL;CAEA,IAAI,CAAC,SAAS,CAAC,UAAU,QAAQ,KAAM,YAAY,WAAW,YAAY,iBAAkB,CAAC,WAAW,KAAK,GAC3G;CAEF,MAAM,SAA0B,WAAW,QAAQ,IAC/C;EAAE;EAAU;EAAS;EAAO;CAAS,IACrC;EAAE;EAAU;EAAS;CAAM;CAC/B,OAAO,OAAO,OAAO,MAAM;AAC7B;AAEA,SAAS,UAAU,OAAqC;CACtD,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU,KAAK;AAC5D;AAEA,SAAS,WAAW,OAAqC;CACvD,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,SAAS;AACzE;;;AChFA,MAAM,+BAAoC,IAAI,IAAI;CAChD;CACA;CACA;CACA;CACA;AACF,CAAC;;AAGD,MAAM,YAAY;;AAGlB,SAAgB,sBAAsB,KAAgB,KAAoB;CACxE,MAAM,MAAM,eAAe,KAAK,GAAG;CACnC,MAAM,YAAY,IAAI,WAAW,QAAO,cAAa,UAAU,aAAa,mBAAmB,QAAQ;CACvG,MAAM,WAAW,UAAU;CAC3B,IAAI,aAAa,KAAA,GAAW;EAC1B,MAAM,aAAa,IAAI,QAAQ,SAAQ,WACrC,OAAO,WACJ,QAAO,cAAa,UAAU,aAAa,KAAA,KAAa,kBAAkB,IAAI,UAAU,QAAQ,CAAC,CAAC,CAClG,KAAI,eAAc;GAAE,MAAM,UAAU;GAAM,UAAU,UAAU;EAAS,EAAE,CAC9E;EACA,IAAI,WAAW,SAAS,GACtB,IAAI,MAAM;GACR,MAAM;GACN,UAAU,IAAI;GACd,aAAa,IAAI;GACjB,UAAU,IAAI;GACd;EACF,CAAC;EAEH;CACF;CACA,KAAK,MAAM,aAAa,UAAU,MAAM,CAAC,GACvC,IAAI,OAAO;EACT,MAAM;EACN,UAAU;EACV,SAAS,IAAI,UAAU,KAAK,+BAA+B,IAAI;EAC/D,UAAU,UAAU;EACpB,OAAO,CAAC,kBAAkB,UAAU,KAAK,6BAA6B;CACxE,CAAC;CAGH,MAAM,UAAU,oBAAoB,UAAU,KAAK,GAAG;CACtD,MAAM,QAAQ,IAAI,iBAAiB,KAAK,EAAE,OAAO,QAAQ,MAAM,CAAC;CAChE,MAAM,QAAQ,WAAW,KAAK,GAAG;CAIjC,MAAM,yBAAS,IAAI,IAA4B;CAC/C,KAAK,IAAI,QAAQ,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS;EACtD,MAAM,QAAQ,MAAM;EACpB,KAAK,MAAM,CAAC,MAAM,WAAW,UAAU,IAAI,MAAM,eAAe,OAAO,GAAG,GAAG,OAAO,IAAI,MAAM,MAAM;CACtG;CACA,MAAM,UAAU,CAAC,GAAG,OAAO,OAAO,CAAC;CACnC,MAAM,WAAW,QAAQ,SAAQ,WAAU,OAAO,QAAQ;CAE1D,IAAI,CAAC,QAAQ,MAAK,WAAU,OAAO,YAAY,CAAC,GAC9C,IAAI,OAAO;EACT,MAAM;EACN,UAAU;EACV,SAAS,aAAa,IAAI,YAAY;EACtC,UAAU,SAAS;EACnB,OAAO,CAAC,iGAA+F;CACzG,CAAC;CAEH,kBAAkB,IAAI,aAAa,UAAU,GAAG;CAEhD,MAAM,gBAAgB,QAAQ,QAAO,WAAU,OAAO,iBAAiB,KAAA,CAAS;CAChF,MAAM,eAAe,cAAc;CACnC,KAAK,MAAM,SAAS,cAAc,MAAM,CAAC,GACvC,IAAI,OAAO;EACT,MAAM;EACN,UAAU;EACV,SAAS,aAAa,IAAI,YAAY,iCAAiC,cAAc,KAAI,WAAU,GAAG,OAAO,WAAW,GAAG,OAAO,OAAO,GAAG,CAAC,CAAC,KAAK,IAAI;EACvJ,UAAU,MAAM;EAChB,OAAO,CAAC,4CAA4C;EACpD,SAAS,CAAC;GAAE,SAAS;GAAyB,UAAU,cAAc;EAAyB,CAAC;CAClG,CAAC;CAGH,IAAI,MAAM;EACR,MAAM;EACN;EACA,UAAU,IAAI;EACd,aAAa,IAAI;EACjB,OAAO,QAAQ;EACf,SAAS,QAAQ;EACjB;EACA,cAAc,cAAc;EAC5B,OAAO,MAAM,KAAI,UAAS,MAAM,QAAQ;EACxC,UAAU,SAAS;CACrB,CAAC;AACH;;AAYA,SAAS,oBAAoB,WAA0B,KAAgB,KAA+B;CACpG,MAAM,UAA2B;EAAE,OAAO;EAAI,OAAO;EAAa,SAAS,KAAA;CAAU;CACrF,MAAM,SAAS,aAAa,IAAI;CAChC,IAAI,CAAC,UAAU,QAAQ,OAAO;CAC9B,MAAM,MAAM,UAAU,KAAK;CAC3B,IAAI,QAAQ,KAAA,GAAW;EACrB,IAAI,OAAO;GACT,MAAM;GACN,UAAU;GACV,SAAS,GAAG,OAAO;GACnB,UAAU,UAAU;GACpB,OAAO,CAAC,6EAA6E;EACvF,CAAC;EACD,OAAO;CACT;CACA,IAAI,CAAC,IAAI,WAAW,OAAO;CAC3B,MAAM,QAAQ,IAAI;CAClB,IAAI,OAAO,UAAU,UAAU;EAC7B,IAAI,UAAU,IACZ,IAAI,OAAO;GACT,MAAM;GACN,UAAU;GACV,SAAS,GAAG,OAAO;GACnB,UAAU,IAAI;EAChB,CAAC;EAEH,OAAO;GAAE,OAAO;GAAO,OAAO;GAAa,SAAS,KAAA;EAAU;CAChE;CACA,IAAI,CAAC,SAAS,KAAK,GAAG;EACpB,IAAI,OAAO;GACT,MAAM;GACN,UAAU;GACV,SAAS,GAAG,OAAO,mGAAmG,cAAc,KAAK;GACzI,UAAU,IAAI;EAChB,CAAC;EACD,OAAO;CACT;CAEA,MAAM,QAAQ,KAAa,SAAiB,UAAoC;EAC9E,IAAI,OAAO;GACT,MAAM;GACN,UAAU;GACV,SAAS,GAAG,OAAO,IAAI;GACvB,UAAU,iBAAiB,IAAI,SAAS,KAAK,GAAG;GAChD,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;EACzC,CAAC;CACH;CAEA,IAAI,QAAQ;CACZ,MAAM,WAAW,MAAM;CACvB,IAAI,aAAa,KAAA,GACf,KAAK,SAAS,oCAAkC,CAAC,2CAA2C,CAAC;MACxF,IAAI,OAAO,aAAa,YAAY,aAAa,IACtD,KAAK,SAAS,2CAA2C,cAAc,QAAQ,GAAG;MAElF,QAAQ;CAGV,IAAI,QAAe;CACnB,MAAM,WAAW,MAAM;CACvB,IAAI,aAAa,KAAA,GAAW;EAC1B,IAAI,OAAO,aAAa,YAAY,gBAAgB,SAAS,QAAQ,GACnE,QAAQ;OAER,KAAK,SAAS,8DAA8D,cAAc,QAAQ,GAAG;CAEzG;CAEA,MAAM,cAAc,MAAM;CAC1B,IACE,gBAAgB,KAAA,KAChB,EAAE,OAAO,gBAAgB,YAAY,OAAO,cAAc,WAAW,KAAK,cAAc,IAExF,KAAK,eAAe,iDAAiD,cAAc,WAAW,GAAG;CAGnG,MAAM,aAAa,MAAM;CACzB,IAAI,eAAe,KAAA,KAAa,eAAe,UAAU,OAAO,eAAe,YAAY,eAAe,KACxG,KAAK,cAAc,mDAAmD,cAAc,UAAU,GAAG;MAC5F,IAAI,eAAe,SAAS,UAAU,IAC3C,KAAK,cAAc,uDAAuD,MAAM,IAAI,CAClF,yGACF,CAAC;CAGH,MAAM,UAAuC,CAAC;CAC9C,KAAK,MAAM,CAAC,KAAK,WAAW,OAAO,QAAQ,KAAK,GAAG;EACjD,IAAI,QAAQ,WAAW,QAAQ,WAAW,WAAW,KAAA,GAAW;EAChE,QAAQ,OAAO;CACjB;CACA,OAAO;EAAE;EAAO;EAAO,SAAS,OAAO,KAAK,OAAO,CAAC,CAAC,WAAW,IAAI,KAAA,IAAY,OAAO,OAAO,OAAO;CAAE;AACzG;;AAGA,SAAS,WAAW,KAAgB,KAA2B;CAC7D,MAAM,QAAQ,CAAC,GAAG;CAClB,MAAM,uBAAO,IAAI,IAAI,CAAC,IAAI,QAAQ,CAAC;CACnC,IAAI,UAAU;CACd,OAAO,QAAQ,eAAe,KAAA,KAAa,MAAM,SAAS,WAAW;EACnE,MAAM,OAAO,IAAI,UAAU,QAAQ,WAAW,QAAQ;EACtD,IAAI,SAAS,KAAA,KAAa,KAAK,IAAI,KAAK,QAAQ,GAAG;EACnD,MAAM,KAAK,IAAI;EACf,KAAK,IAAI,KAAK,QAAQ;EACtB,UAAU;CACZ;CACA,OAAO;AACT;;;;;AAMA,SAAS,kBAAkB,UAAkB,UAAkC,KAAoB;CACjG,IAAI;CACJ,MAAM,wBAAQ,IAAI,IAAyB;CAC3C,MAAM,WAAwD,CAAC;CAC/D,MAAM,SAAS,YAAiC,GAAG,QAAQ,WAAW,GAAG,QAAQ,OAAO;CACxF,KAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,OAAO,QAAQ;EACrB,IAAI,SAAS,KAAA,GAAW;GACtB,IAAI,aAAa,KAAA,GAAW;IAC1B,WAAW;IACX;GACF;GACA,IAAI,OAAO;IACT,MAAM;IACN,UAAU;IACV,SAAS,aAAa,SAAS,IAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,OAAO,EAAE;IACzE,UAAU,QAAQ;IAClB,OAAO,CAAC,gEAA8D;IACtE,SAAS,CAAC;KAAE,SAAS;KAAyB,UAAU,SAAS;IAAS,CAAC;GAC7E,CAAC;GACD;EACF;EACA,MAAM,WAAW,UAAU,IAAI,IAAI,SAAS,MAAK,YAAW,QAAQ,SAAS,IAAI,IAAI,MAAM,IAAI,IAAI;EACnG,IAAI,aAAa,KAAA,GAAW;GAC1B,IAAI,OAAO;IACT,MAAM;IACN,UAAU;IACV,SAAS,aAAa,SAAS,0CAA0C,KAAK,KAAK,MAAM,QAAQ,EAAE,OAAO,MAAM,OAAO,EAAE;IACzH,UAAU,QAAQ;IAClB,OAAO,CAAC,kEAAkE;IAC1E,SAAS,CAAC;KAAE,SAAS,qBAAqB,KAAK;KAAI,UAAU,SAAS;IAAS,CAAC;GAClF,CAAC;GACD;EACF;EACA,IAAI,CAAC,UAAU,IAAI,GAAG;GACpB,MAAM,IAAI,MAAM,OAAO;GACvB;EACF;EACA,MAAM,WAAW,SAAS,MAAK,YAAW,cAAc,QAAQ,MAAM,IAAI,CAAC;EAC3E,IAAI,aAAa,KAAA,GACf,IAAI,OAAO;GACT,MAAM;GACN,UAAU;GACV,SAAS,aAAa,SAAS,iBAAiB,KAAK,OAAO,MAAM,OAAO,EAAE,6DAA6D,SAAS,KAAK,KAAK,MAAM,QAAQ,EAAE;GAC3K,UAAU,QAAQ;GAClB,OAAO,CAAC,sGAAsG;GAC9G,SAAS,CAAC;IAAE,SAAS,YAAY,SAAS,KAAK;IAAI,UAAU,SAAS;GAAS,CAAC;EAClF,CAAC;EAEH,SAAS,KAAK;GAAE,GAAG;GAAS;EAAK,CAAC;CACpC;AACF;;AAKA,SAAS,eAAe,KAAgB,KAA2C;CACjF,MAAM,0BAAU,IAAI,IAA4B;CAChD,KAAK,MAAM,UAAU,IAAI,SAAS;EAChC,MAAM,SAAS,cAAc,KAAK,QAAQ,GAAG;EAC7C,IAAI,WAAW,KAAA,GAAW,QAAQ,IAAI,OAAO,MAAM,MAAM;CAC3D;CACA,OAAO;AACT;AAEA,SAAS,cAAc,KAAgB,QAAoB,KAA0C;CACnG,MAAM,YAAY,aAAa,OAAO,YAAY,mBAAmB,SAAS;CAC9E,MAAM,QAAQ,aAAa,OAAO,YAAY,mBAAmB,KAAK;CACtE,MAAM,UAAU,aAAa,OAAO,YAAY,mBAAmB,OAAO;CAC1E,MAAM,kBAAkB,OAAO,OAAO,MAAK,UAAS,MAAM,WAAW,KAAK,oBAAoB,CAAC;CAC/F,IAAI,UAAU,WAAW,KAAK,MAAM,WAAW,KAAK,QAAQ,WAAW,KAAK,CAAC,iBAAiB,OAAO,KAAA;CAErG,MAAM,QAAQ,GAAG,IAAI,YAAY,GAAG,OAAO,KAAK;CAChD,MAAM,UAAU,UAAU,MAAM,QAAQ;CACxC,IAAI,YAAY,KAAA,GAAW,iBAAiB,QAAQ,SAAS,OAAO,GAAG;CACvE,KAAK,MAAM,aAAa,CAAC,GAAG,MAAM,MAAM,CAAC,GAAG,GAAG,QAAQ,MAAM,CAAC,CAAC,GAC7D,IAAI,OAAO;EACT,MAAM;EACN,UAAU;EACV,SAAS,IAAI,UAAU,KAAK,+BAA+B;EAC3D,UAAU,UAAU;EACpB,OAAO,CAAC,kBAAkB,UAAU,MAAM;CAC5C,CAAC;CAEH,IAAI,UAAU,SAAS,KAAK,QAAQ,OAAO,KAAA,GACzC,IAAI,OAAO;EACT,MAAM;EACN,UAAU;EACV,SAAS,GAAG,MAAM;EAClB,UAAU,QAAQ,EAAE,CAAC;EACrB,OAAO,CAAC,gDAAgD;CAC1D,CAAC;CAEH,IAAI,UAAU,WAAW,KAAK,MAAM,OAAO,KAAA,GACzC,IAAI,OAAO;EACT,MAAM;EACN,UAAU;EACV,SAAS,2BAA2B,MAAM;EAC1C,UAAU,MAAM,EAAE,CAAC;EACnB,OAAO,CAAC,kDAAkD;CAC5D,CAAC;CAGH,IAAI,WAA0B,CAAC;CAC/B,IAAI,UAAU,SAAS,GAAG;EACxB,MAAM,SACJ,MAAM,OAAO,KAAA,IAAY,KAAA,IAAY,wBAAwB,MAAM,IAAI,OAAO,GAAG;EACnF,MAAM,SAAS,qBAAqB,QAAQ,OAAO,GAAG;EACtD,WAAW,UAAU,SAAQ,cAAa;GACxC,MAAM,OAAO,YAAY,WAAW,OAAO,GAAG;GAC9C,IAAI,SAAS,OAAO,OAAO,CAAC;GAC5B,OAAO,CACL,OAAO,OAAO;IACZ,QAAQ,OAAO;IACf;IACA,OAAO;IACP;IACA,YAAY,IAAI;IAChB,UAAU,UAAU;GACtB,CAAC,CACH;EACF,CAAC;CACH,OACE,+BAA+B,QAAQ,OAAO,QAAQ,SAAS,GAAG,GAAG;CAGvE,MAAM,eAAe,UAAU,WAAW,IAAI,QAAQ,KAAK,KAAA;CAC3D,IAAI,iBAAiB,KAAA,GAAW,kBAAkB,QAAQ,cAAc,OAAO,GAAG;CAClF,OAAO;EACL,QAAQ,OAAO;EACf,YAAY,IAAI;EAChB,WAAW,UAAU;EACrB;EACA,cAAc,cAAc;CAC9B;AACF;;AAGA,SAAS,iBAAiB,QAAoB,WAA0B,OAAe,KAAoB;CACzG,MAAM,OAAO,IAAI,UAAU;CAC3B,IAAI;CACJ,IAAI,OAAO,SAAS,UAClB,UAAU;EAAE,SAAS,GAAG,KAAK,qCAAqC;EAAS,MAAM;CAAuB;MACnG,IAAI,OAAO,QAChB,UAAU;EACR,SAAS,GAAG,KAAK,0CAA0C;EAC3D,MAAM;CACR;MACK,IAAI,OAAO,aAChB,UAAU;EACR,SAAS,GAAG,KAAK,4CAA4C;EAC7D,MAAM;CACR;MACK,IAAI,OAAO,eAAe,UAC/B,UAAU;EACR,SAAS,GAAG,MAAM,mBAAmB,KAAK;EAC1C,MAAM,eAAe,OAAO,WAAW;CACzC;MACK,IAAI,OAAO,UAChB,UAAU;EACR,SAAS,GAAG,KAAK,wBAAwB,MAAM;EAC/C,MAAM;CACR;MACK,IAAI,OAAO,WAChB,UAAU;EACR,SAAS,GAAG,KAAK,6CAA6C;EAC9D,MAAM;CACR;CAEF,IAAI,YAAY,KAAA,GACd,IAAI,OAAO;EACT,MAAM;EACN,UAAU;EACV,SAAS,QAAQ;EACjB,UAAU,UAAU;EACpB,OAAO,CAAC,QAAQ,IAAI;CACtB,CAAC;AAEL;;AAGA,SAAS,YAAY,WAA0B,OAAe,KAA0C;CACtG,MAAM,MAAM,UAAU,KAAK;CAC3B,IAAI,QAAQ,KAAA,KAAc,IAAI,aAAa,IAAI,UAAU,KAAA,GAAY,OAAO,KAAA;CAC5E,IAAI,CAAC,IAAI,WAAW,OAAO;CAC3B,IAAI,OAAO,IAAI,UAAU,UAAU;EACjC,IAAI,OAAO;GACT,MAAM;GACN,UAAU;GACV,SAAS,iBAAiB,MAAM,0CAA0C,cAAc,IAAI,KAAK;GACjG,UAAU,IAAI;GACd,OAAO,CAAC,0CAA0C;EACpD,CAAC;EACD,OAAO;CACT;CACA,IAAI,IAAI,UAAU,IAAI;EACpB,IAAI,OAAO;GACT,MAAM;GACN,UAAU;GACV,SAAS,0BAA0B,MAAM;GACzC,UAAU,IAAI;GACd,OAAO,CAAC,0CAA0C;EACpD,CAAC;EACD,OAAO;CACT;CACA,OAAO,IAAI;AACb;;AAGA,SAAS,kBAAkB,QAAoB,WAA0B,OAAe,KAAoB;CAC1G,MAAM,WAAW,OAAO,OAAO,QAAO,UAAS,CAAC,MAAM,YAAY,CAAC,MAAM,cAAc,CAAC,MAAM,IAAI,CAAC,CAAC;CACpG,IAAI,WAAW,GACb,IAAI,OAAO;EACT,MAAM;EACN,UAAU;EACV,SAAS,uBAAuB,MAAM,OAAO,SAAS;EACtD,UAAU,OAAO;EACjB,OAAO,CAAC,0DAA0D;CACpE,CAAC;CAEH,IAAI,OAAO,eAAe,KAAA,KAAa,CAAC,qBAAqB,IAAI,MAAM,QAAQ,OAAO,UAAU,CAAC,GAC/F,IAAI,OAAO;EACT,MAAM;EACN,UAAU;EACV,SAAS,uBAAuB,MAAM,YAAY,IAAI,MAAM,OAAO,OAAO,UAAU,EAAE;EACtF,UAAU,UAAU;EACpB,OAAO,CAAC,yDAAyD;CACnE,CAAC;AAEL;AAIA,SAAS,qBAAqB,QAAoB,OAAe,KAA2C;CAC1G,OAAO,OAAO,OAAO,OAAO,OAAO,KAAI,UAAS,oBAAoB,OAAO,OAAO,GAAG,CAAC,CAAC;AACzF;AAEA,SAAS,oBAAoB,OAAsB,OAAe,KAAgC;CAChG,MAAM,aAAa,oBAAoB,KAAK;CAC5C,MAAM,YAAY,WAAW;CAC7B,IAAI,cAAc,KAAA,GAAW;EAC3B,MAAM,UAAU,0BAA0B,KAAK;EAC/C,IAAI,YAAY,KAAA,GAAW;GAEzB,IAAI,OAAO;IACT,MAAM;IACN,UAAU;IACV,SAAS,IAAI,QAAQ,UAAU,KAAK,iBAAiB,MAAM,KAAK,OAAO,MAAM,qBAAqB,QAAQ,OAAO,uCAAuC,QAAQ,KAAK,SAAS,eAAe;IAC7L,UAAU,QAAQ,UAAU;IAC5B,OAAO,CAAC,mBAAmB,eAAe,cAAc,QAAQ,KAAK,WAAW,eAAe,EAAE;GACnG,CAAC;GACD,OAAO,EAAE,MAAM,YAAY;EAC7B;EACA,IAAI,MAAM,YAAY,MAAM,cAAc,MAAM,MAAM,OAAO,EAAE,MAAM,YAAY;EACjF,IAAI,OAAO;GACT,MAAM;GACN,UAAU;GACV,SAAS,cAAc,MAAM,KAAK,OAAO,MAAM;GAC/C,UAAU,MAAM;GAChB,OAAO,CACL,0JACF;EACF,CAAC;EACD,OAAO,EAAE,MAAM,YAAY;CAC7B;CACA,IAAI,WAAW,SAAS,GACtB,IAAI,OAAO;EACT,MAAM;EACN,UAAU;EACV,SAAS,cAAc,MAAM,KAAK,OAAO,MAAM,qCAAqC,WAAW,KAAI,UAAS,IAAI,MAAM,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE;EACzI,UAAW,WAAW,EAAE,CAAmB;EAC3C,OAAO,CAAC,mBAAmB;CAC7B,CAAC;CAEH,IAAI,MAAM,MAAM;EACd,IAAI,OAAO;GACT,MAAM;GACN,UAAU;GACV,SAAS,IAAI,UAAU,KAAK,+CAA+C,MAAM,KAAK,OAAO;GAC7F,UAAU,UAAU;EACtB,CAAC;EACD,OAAO,EAAE,MAAM,YAAY;CAC7B;CACA,QAAQ,UAAU,UAAlB;EACE,KAAK,mBAAmB,SACtB,OAAO,aAAa,OAAO,WAAW,OAAO,GAAG;EAClD,KAAK,mBAAmB,SACtB,OAAO,aAAa,OAAO,WAAW,OAAO,GAAG;EAClD,SACE,OAAO;GAAE,MAAM;GAAW,QAAQ,eAAe,MAAM,MAAM,IAAI,KAAK;EAAE;CAC5E;AACF;;AAGA,SAAS,aAAa,OAAsB,WAA0B,OAAe,KAAgC;CACnH,MAAM,MAAM,UAAU,KAAK;CAC3B,IAAI,QAAQ,KAAA,KAAc,IAAI,aAAa,IAAI,UAAU,KAAA,GAAY;EACnE,iBAAiB,OAAO,WAAW,OAAO,GAAG;EAC7C,OAAO,EAAE,MAAM,UAAU;CAC3B;CACA,IAAI,IAAI,QAAQ,KAAA,GAAW;EACzB,IAAI,iBAAiB,IAAI,GAAG,GAAG;GAC7B,IAAI,OAAO;IACT,MAAM;IACN,UAAU;IACV,SAAS,YAAY,IAAI,KAAK,OAAO,MAAM,KAAK,IAAI,IAAI,KAAK;IAC7D,UAAU,IAAI;IACd,OAAO,CACL,mGACA,0EACF;GACF,CAAC;GACD,OAAO,EAAE,MAAM,YAAY;EAC7B;EACA,OAAO;GAAE,MAAM;GAAa,QAAQ,IAAI;EAAI;CAC9C;CACA,IAAI,CAAC,IAAI,WAAW,OAAO,EAAE,MAAM,YAAY;CAC/C,IAAI,OAAO;EACT,MAAM;EACN,UAAU;EACV,SAAS,eAAe,MAAM,6DAA6D,cAAc,IAAI,KAAK;EAClH,UAAU,IAAI;EACd,OAAO,CACL,2GACF;CACF,CAAC;CACD,OAAO,EAAE,MAAM,YAAY;AAC7B;;AAGA,SAAS,aAAa,OAAsB,WAA0B,OAAe,KAAgC;CACnH,MAAM,MAAM,UAAU,KAAK;CAC3B,IAAI,QAAQ,KAAA,KAAc,IAAI,aAAa,IAAI,UAAU,KAAA,GAAY,OAAO,EAAE,MAAM,UAAU;CAC9F,IAAI,CAAC,IAAI,WAAW,OAAO,EAAE,MAAM,YAAY;CAC/C,MAAM,OAAO,IAAI;CACjB,IAAI,OAAO,SAAS,YAAY,SAAS,IAAI;EAC3C,IAAI,OAAO;GACT,MAAM;GACN,UAAU;GACV,SAAS,eAAe,MAAM,mDAAmD,cAAc,IAAI;GACnG,UAAU,IAAI;GACd,OAAO,CAAC,uCAAuC;EACjD,CAAC;EACD,OAAO,EAAE,MAAM,YAAY;CAC7B;CACA,IAAI,CAAC,MAAM,YAAY,CAAC,MAAM,cAAc,CAAC,iBAAiB,MAAM,IAAI,GACtE,IAAI,OAAO;EACT,MAAM;EACN,UAAU;EACV,SAAS,YAAY,KAAK,UAAU,IAAI,EAAE,4EAA4E,MAAM,KAAK,OAAO,MAAM,aAAa,IAAI,MAAM,OAAO,MAAM,IAAI,EAAE;EACxL,UAAU,MAAM;EAChB,OAAO,CAAC,eAAe,MAAM,KAAK,iBAAiB,MAAM,KAAK,kDAAkD;CAClH,CAAC;CAEH,OAAO;EAAE,MAAM;EAAU;CAAK;AAChC;;AAGA,SAAS,iBAAiB,OAAsB,WAA0B,OAAe,KAAoB;CAC3G,MAAM,EAAE,SAAS,IAAI,MAAM,aAAa,MAAM,IAAI;CAClD,IAAI,kBAAkB,IAAI,GAAG;CAC7B,MAAM,QACJ,KAAK,SAAS,YAAY,KAAK,WAAW,uBACtC,2BACA,aAAa,IAAI,MAAM,OAAO,MAAM,IAAI,EAAE;CAChD,IAAI,OAAO;EACT,MAAM;EACN,UAAU,IAAI,QAAQ,mBAAmB,UAAU;EACnD,SAAS,2CAA2C,MAAM,KAAK,OAAO,MAAM,GAAG,MAAM;EACrF,UAAU,UAAU;EACpB,OAAO,CACL,wFACA,mEACF;CACF,CAAC;AACH;;AAGA,SAAS,+BAA+B,QAAoB,OAAe,cAAuB,KAAoB;CAEpH,MAAM,QAAQ,eAAe,KAAA,IAAY,eAAe,MAAM;CAC9D,KAAK,MAAM,SAAS,OAAO,QACzB,KAAK,MAAM,aAAa,oBAAoB,KAAK,GAAG;EAClD,IAAI,OAAO;EACX,IAAI,cAAc,OAAO;OACpB,IAAI,UAAU,KAAA,GACjB,OAAO,GAAG,MAAM,SAAS,MAAM,UAAU,KAAK,6CAA6C,MAAM,OAAO;EAE1G,IAAI,OAAO;GACT,MAAM;GACN,UAAU;GACV,SACE,UAAU,KAAA,IACN,IAAI,UAAU,KAAK,+BAA+B,MAAM,KAAK,OAAO,MAAM,qCAC1E,IAAI,UAAU,KAAK,UAAU,eAAe,iCAAiC,MAAM,KAAK,OAAO,MAAM;GAC3G,UAAU,UAAU;GACpB,OAAO,CAAC,IAAI;EACd,CAAC;CACH;AAEJ;AASA,SAAS,cAAc,WAAwD;CAC7E,MAAM,WAAW,UAAU;CAC3B,MAAM,YAAY,UAAU,YAAY,GAAG,KAAK;CAChD,IAAI,aAAa,KAAA,KAAa,aAAa,GAAG,OAAO,KAAA;CACrD,OAAO;EAAE;EAAW,QAAQ,SAAS,MAAM,GAAG,SAAS;EAAG,MAAM,SAAS,MAAM,YAAY,CAAC;CAAE;AAChG;;;;;AAMA,SAAS,0BAA0B,OAAoD;CACrF,KAAK,MAAM,aAAa,MAAM,YAAY;EACxC,MAAM,QAAQ,cAAc,SAAS;EACrC,IAAI,UAAU,KAAA,KAAa,MAAM,WAAA,qBAA2B;EAC5D,IAAI,qBAAqB,IAAI,qBAAqB,MAAM,MAAM,GAAG,OAAO;CAC1E;AAEF;;AAGA,SAAS,eAAe,QAAkD;CACxE,KAAK,MAAM,aAAa,OAAO,YAAY;EACzC,MAAM,QAAQ,UAAU;EACxB,IAAI,UAAU,KAAA,KAAa,UAAA,eAA4B,UAAU,UAAU,UAAU,YAAY;EACjG,MAAM,QAAQ,cAAc,SAAS;EACrC,IAAI,UAAU,KAAA,GAAW,OAAO;CAClC;AAEF;AAIA,SAAS,aAAa,YAAsC,UAAmC;CAC7F,OAAO,WAAW,QAAO,cAAa,UAAU,aAAa,QAAQ;AACvE;;;;;AAMA,SAAS,oBAAoB,OAAuC;CAClE,MAAM,uBAAO,IAAI,IAAY;CAC7B,OAAO,MAAM,WAAW,QAAO,cAAa;EAC1C,IAAI,CAAC,qBAAqB,SAAS,KAAK,KAAK,IAAI,UAAU,SAAS,KAAK,GAAG,OAAO;EACnF,KAAK,IAAI,UAAU,SAAS,KAAK;EACjC,OAAO;CACT,CAAC;AACH;AAEA,SAAS,qBAAqB,WAAmC;CAC/D,OAAO,UAAU,aAAa,KAAA,KAAa,qBAAqB,IAAI,UAAU,QAAQ;AACxF;;AAGA,SAAS,iBAAiB,KAAwB;CAChD,MAAM,SAAS,IAAI;CACnB,OAAO,OAAO,SAAS,iBAAiB,OAAO,YAAY,SAAS;AACtE;;AAGA,SAAS,kBAAkB,MAAyB;CAClD,QAAQ,KAAK,MAAb;EACE,KAAK,aACH,OAAO,KAAK,SAAS,SAAS,KAAK,SAAS;EAC9C,KAAK,WACH,OAAO;EACT,KAAK,SACH,OAAO,KAAK,MAAM,MAAM,iBAAiB;EAC3C,KAAK,aACH,OAAO,aAAa,IAAI,KAAK,QAAQ;EACvC,SACE,OAAO;CACX;AACF;;AAGA,SAAS,iBAAiB,MAAyB;CACjD,QAAQ,KAAK,MAAb;EACE,KAAK,aACH,OAAO,KAAK,SAAS,SAAS,KAAK,SAAS,aAAa,KAAK,SAAS,eAAe,KAAK,SAAS;EACtG,KAAK,SACH,OAAO,KAAK,MAAM,KAAK,gBAAgB;EACzC,KAAK;EACL,KAAK,iBACH,OAAO;EACT,SACE,OAAO;CACX;AACF;;AAGA,SAAS,qBAAqB,MAAyB;CACrD,QAAQ,KAAK,MAAb;EACE,KAAK,aACH,OAAO;GAAC;GAAQ;GAAa;GAAO;GAAW;EAAO,CAAC,CAAC,SAAS,KAAK,IAAI;EAC5E,KAAK,WACH,OAAO,KAAK,UAAU;EACxB,KAAK,SACH,OAAO,KAAK,MAAM,MAAM,oBAAoB;EAC9C,KAAK,WACH,OAAO,qBAAqB,KAAK,KAAK;EACxC,KAAK;EACL,KAAK,iBACH,OAAO;EACT,SACE,OAAO;CACX;AACF;;AAGA,SAAS,eAAe,MAAgB,OAA6B;CACnE,MAAM,EAAE,MAAM,UAAU,MAAM,aAAa,IAAI;CAC/C,IAAI,MAAM,SAAS,eAAe,MAAM,aAAA,oCAAuC,OAAO;CACtF,MAAM,UAAU,MAAM,SAAS;CAC/B,OACE,YAAY,KAAA,KAAa,EAAE,QAAQ,SAAS,gBAAgB,QAAQ,SAAS,aAAa,QAAQ,SAAS;AAE/G;;;ACzvBA,SAAgB,kBAAkB,KAAmC;CACnE,MAAM,YAAY,IAAI,OACnB,QAAQ,SAA+B,KAAK,SAAS,UAAU,CAAC,CAChE,MAAM,GAAG,MAAM,eAAe,EAAE,OAAO,EAAE,KAAK,CAAC;CAClD,IAAI,UAAU,WAAW,GAAG,OAAO,KAAA;CACnC,MAAM,UAAU,YAAY,GAAG;CAC/B,OAAO,IAAI,IAAI,CAAC,CAAC,aAAa,IAAI,IAAI,UAAU,KAAI,aAAY,aAAa,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1G;AAEA,SAAS,aAAa,KAAc,UAAwB,SAA2B;CACrF,IAAI;CACJ,MAAM,qBAA8B;EAClC,cAAc,IAAI,WAAW,SAAS,QAAQ;EAC9C,OAAO;CACT;CACA,MAAM,UAAgC,CACpC,CAAC,SAAS,SAAS,KAAK,GACxB,CAAC,SAAS,SAAS,KAAK,CAC1B;CACA,IAAI,SAAS,YAAY,KAAA,GAAW,QAAQ,KAAK,CAAC,WAAW,IAAI,IAAI,SAAS,OAAO,CAAC,CAAC;CACvF,QAAQ,KAAK,CACX,YACA,IAAI,IAAI,SAAS,SAAS,KAAI,YAAW,YAAY,KAAK,SAAS,cAAc,OAAO,CAAC,CAAC,CAC5F,CAAC;CACD,IAAI,SAAS,iBAAiB,KAAA,GAAW,QAAQ,KAAK,CAAC,gBAAgB,SAAS,YAAY,CAAC;CAC7F,OAAO,IAAI,IAAI,OAAO;AACxB;AAEA,SAAS,YAAY,KAAc,SAAsB,cAA6B,SAA2B;CAC/G,MAAM,UAAgC,CAAC,CAAC,UAAU,QAAQ,MAAM,CAAC;CACjE,IAAI,QAAQ,SAAS,KAAA,GAAW,QAAQ,KAAK,CAAC,QAAQ,QAAQ,IAAI,CAAC;CACnE,IAAI,QAAQ,UAAU,KAAA,GAAW,QAAQ,KAAK,CAAC,SAAS,IAAI,IAAI,EAAE,GAAG,QAAQ,MAAM,CAAC,CAAC,CAAC;CACtF,QAAQ,KAAK,CAAC,UAAU,WAAW,KAAK,SAAS,cAAc,OAAO,CAAC,CAAC;CACxE,OAAO,IAAI,IAAI,OAAO;AACxB;;;;;AAMA,SAAS,WAAW,KAAc,SAAsB,cAA6B,SAA2B;CAC9G,MAAM,SAAS,CAAC,GAAG,QAAQ,MAAM;CACjC,OAAO,OAAO,SAAS,KAAK,OAAO,OAAO,SAAS,EAAE,EAAE,SAAS,aAAa,OAAO,IAAI;CACxF,IAAI,OAAO,WAAW,GACpB,OAAO,IAAI,MAAM,CAAC,CAAC,KAAK,aAAa,CAAC,CAAC,IAAG,MAAK,IAAI,KAAK,IAAI,OAAO,GAAG,QAAQ,MAAM,CAAC,CAAC;CAExF,OAAO,IAAI,MACT,CACE,CAAC,KAAK,aAAa,CAAC,GACpB,CAAC,KAAK,QAAQ,eAAe,CAAC,CAChC,IACC,GAAG,MACF,IAAI,KACF,IAAI,OAAO,GAAG,QAAQ,MAAM,GAC5B,OAAO,KAAI,UAAS,aAAa,KAAK,OAAO,GAAc,OAAO,CAAC,CACrE,GACF,EAAE,OAAO,OAAO,MAAK,UAAS,MAAM,SAAS,WAAW,EAAE,CAC5D;AACF;AAEA,SAAS,aAAa,KAAc,OAAyB,GAAY,SAA2B;CAClG,QAAQ,MAAM,MAAd;EACE,KAAK,WACH,OAAO,IAAI,IAAI,GAAG,IAAI,OAAO,GAAG,SAAS,EAAE;EAC7C,KAAK,aACH,OAAO,IAAI,IAAI,SAAS,IAAI,KAAK,QAAQ,gBAAgB,GAAG,CAAC,IAAI,YAAY,MAAM,MAAM,GAAG,IAAI,OAAO,GAAG,SAAS,CAAC,CAAC;EACvH,KAAK,WACH,OAAO,IAAI,OAAO,GAAG,SAAS;EAChC,KAAK,UACH,OAAO,IAAI,KAAK,QAAQ,cAAc,GAAG,CAAC,GAAG,MAAM,IAAI,CAAC;EAC1D,KAAK,WACH,OAAO,MAAM,SAAS,IAAI,IAAI,GAAG,EAAE,MAAM,QAAQ,eAAe,EAAE,WAAW;EAC/E,KAAK,aACH,OAAO,IAAI,IAAI,KAAA,CAAS;CAC5B;AACF;AAEA,SAAS,YAAY,KAAuB;CAC1C,MAAM,wBAAQ,IAAI,IAAqB;CACvC,MAAM,OAAO,MAAc,SAA2B;EACpD,IAAI,OAAO,MAAM,IAAI,IAAI;EACzB,IAAI,SAAS,KAAA,GAAW;GACtB,OAAO,IAAI,WAAW,gBAAgB,MAAM,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC;GACtE,MAAM,IAAI,MAAM,IAAI;EACtB;EACA,OAAO;CACT;CACA,OAAO;EACL,sBAAsB,IAAI,kBAAkB,IAAI;EAChD,uBAAuB,IAAI,mBAAmB,KAAK;EACnD,qBAAqB,IAAI,iBAAiB,KAAK;CACjD;AACF;;;ACzHA,SAAgB,kBAAkB,KAA2C;CAC3E,MAAM,YAAY,IAAI,OACnB,QAAQ,SAA+B,KAAK,SAAS,UAAU,CAAC,CAChE,MAAM,GAAG,MAAM,eAAe,EAAE,OAAO,EAAE,KAAK,CAAC;CAGlD,MAAM,0BAAU,IAAI,IAA0B;CAC9C,KAAK,MAAM,YAAY,WAAW;EAChC,IAAI,SAAS,UAAU,IAAI;EAC3B,MAAM,QAAQ,QAAQ,IAAI,SAAS,KAAK;EACxC,IAAI,UAAU,KAAA,GAAW;GACvB,QAAQ,IAAI,SAAS,OAAO,QAAQ;GACpC;EACF;EACA,IAAI,OAAO;GACT,MAAM;GACN,UAAU;GACV,SAAS,GAAG,MAAM,YAAY,OAAO,SAAS,YAAY,iBAAiB,SAAS,MAAM;GAC1F,UAAU,SAAS;GACnB,OAAO,CACL,6GACF;GACA,SAAS,CAAC;IAAE,SAAS,GAAG,MAAM,YAAY,aAAa,SAAS,MAAM;IAAI,UAAU,MAAM;GAAS,CAAC;EACtG,CAAC;CACH;CAGA,MAAM,QAAQ,IAAI,IAAI,UAAU,SAAQ,aAAY,SAAS,KAAK,CAAC;CACnE,KAAK,MAAM,QAAQ,IAAI,QAAQ;EAC7B,IAAI,KAAK,SAAS,aAAa,KAAK,YAAY,MAAM,IAAI,KAAK,QAAQ,GAAG;EAC1E,mBAAmB,MAAM,GAAG;CAC9B;AACF;AAEA,SAAS,mBAAmB,MAAuB,KAA2C;CAC5F,KAAK,MAAM,aAAa,KAAK,YAC3B,IAAI,OAAO;EACT,MAAM;EACN,UAAU;EACV,SAAS,IAAI,UAAU,KAAK,kBAAkB,KAAK,YAAY;EAC/D,UAAU,UAAU;EACpB,OAAO,CACL,6BAA6B,KAAK,YAAY,wCAC9C,yDACF;CACF,CAAC;AAEL;;;;;;ACzBA,MAAM,aAAsD,OAAO,OAAO;EACvE,mBAAmB,WAAW;EAAE,SAAS,CAAC,OAAO;EAAG,QAAQ,CAAC,QAAQ;CAAE;EACvE,mBAAmB,YAAY;EAAE,SAAS,CAAC,QAAQ;EAAG,QAAQ,CAAC,QAAQ;CAAE;EACzE,mBAAmB,QAAQ;EAAE,SAAS,CAAC,QAAQ;EAAG,QAAQ,CAAC,QAAQ;CAAE;EACrE,mBAAmB,UAAU;EAAE,SAAS,CAAC,QAAQ;EAAG,QAAQ,CAAC;CAAE;EAC/D,mBAAmB,UAAU;EAAE,SAAS,CAAC,WAAW;EAAG,QAAQ,CAAC,OAAO;CAAE;EACzE,mBAAmB,UAAU;EAAE,SAAS,CAAC,WAAW;EAAG,QAAQ,CAAC,QAAQ;CAAE;EAC1E,mBAAmB,MAAM;EAAE,SAAS,CAAC,WAAW;EAAG,QAAQ,CAAC;CAAE;AACjE,CAAyC;;AAGzC,MAAa,6BAA+D,OAAO,OAAO;CACxF,YAAY;CACZ,MAAM;CACN;CACA,cAAc;CACd,UAAU;CACV,UAAU;AACZ,CAAC"}
1
+ {"version":3,"file":"compiler.mjs","names":[],"sources":["../src/compiler/constants.ts","../src/compiler/patterns.ts","../src/compiler/values.ts","../src/compiler/retry.ts","../src/compiler/analyze.ts","../src/compiler/generate.ts","../src/compiler/validate.ts","../src/compiler/index.ts"],"sourcesContent":["/**\n * Constants shared by the compiler extension modules. This module must stay free of runtime imports:\n * the extension entry is loaded by the compiler, which must never load the messaging runtime (spec §2).\n */\nimport type { ErrorCode } from '@znight/core'\n\n/** Name of the extension, also the key of `metadata.extensions.messaging`. */\nexport const EXTENSION_NAME = 'messaging'\n\n/** Module the generated code imports its helpers and types from. */\nexport const RUNTIME_MODULE = '@znight/messaging'\n\n/** Canonical identities of the decorators owned by the extension. */\nexport const MessagingDecorator: {\n readonly Consumer: '@znight/messaging#Consumer'\n readonly OnMessage: '@znight/messaging#OnMessage'\n readonly Retry: '@znight/messaging#Retry'\n readonly OnError: '@znight/messaging#OnError'\n readonly Message: '@znight/messaging#Message'\n readonly Headers: '@znight/messaging#Headers'\n readonly Ctx: '@znight/messaging#Ctx'\n} = Object.freeze({\n Consumer: '@znight/messaging#Consumer',\n OnMessage: '@znight/messaging#OnMessage',\n Retry: '@znight/messaging#Retry',\n OnError: '@znight/messaging#OnError',\n Message: '@znight/messaging#Message',\n Headers: '@znight/messaging#Headers',\n Ctx: '@znight/messaging#Ctx',\n})\n\n/** Identity of the `InboundMessage` interface (`@Ctx()` parameters). */\nexport const INBOUND_MESSAGE_IDENTITY = '@znight/messaging#InboundMessage'\n\n/** Decorators applied to methods. */\nexport const METHOD_DECORATORS: ReadonlySet<string> = new Set([\n MessagingDecorator.OnMessage,\n MessagingDecorator.Retry,\n MessagingDecorator.OnError,\n])\n\n/** Decorators applied to handler parameters. */\nexport const PARAMETER_DECORATORS: ReadonlySet<string> = new Set([\n MessagingDecorator.Message,\n MessagingDecorator.Headers,\n MessagingDecorator.Ctx,\n])\n\n/** ZNIGHT005: invalid decorator usage (target, arguments, several decorators...). */\nexport const INVALID_DECORATOR: ErrorCode = 'ZNIGHT005'\n/** ZNIGHT011: invalid message consumer (no handler, overlapping types, retry options...). */\nexport const INVALID_CONSUMER: ErrorCode = 'ZNIGHT011'\n/** ZNIGHT017: non-primitive `@Message()` payload without schema. */\nexport const UNVALIDATED_INPUT: ErrorCode = 'ZNIGHT017'\n\n/**\n * Default backoff of `@Retry` (must equal the runtime `DEFAULT_BACKOFF`; checked by the tests, the\n * runtime module cannot be imported here).\n */\nexport const DEFAULT_BACKOFF = 'exponential'\n/** Default base delay of `@Retry`, in milliseconds (the runtime `DEFAULT_RETRY_DELAY_MS`). */\nexport const DEFAULT_RETRY_DELAY_MS = 1000\n/** Largest `attempts` accepted by the runtime (`normalizeRetry`). */\nexport const MAX_RETRY_ATTEMPTS = 10_000\n\n/** Scopes a consumer provider may have. */\nexport const CONSUMER_SCOPES: readonly string[] = ['singleton', 'request', 'transient']\n\n/** Deterministic string comparison (never `localeCompare`). */\nexport function compareStrings(a: string, b: string): number {\n if (a === b) return 0\n return a < b ? -1 : 1\n}\n","/**\n * Message type patterns of `@OnMessage(type)`, with the semantics of the runtime handler selection\n * (`consumers.ts`): a type containing `*` is a pattern where `*` matches any sequence of characters;\n * any other type is matched exactly. Exact types are tried first, then patterns in declaration order.\n */\n\n/** Whether `type` is a pattern (contains `*`). */\nexport function isPattern(type: string): boolean {\n return type.includes('*')\n}\n\n/** Whether `type` matches `pattern` (`*` matches any sequence of characters, the runtime semantics). */\nexport function matchesPattern(pattern: string, type: string): boolean {\n return covers(pattern, type, false)\n}\n\n/**\n * Whether every message type matched by `inner` is also matched by `outer`, so that `inner`, tried\n * after `outer`, can never be selected. The check is sound (never reports a pattern that can be\n * selected): `outer` must match `inner` where each `*` of `inner` can only be consumed by a `*` of\n * `outer`.\n */\nexport function patternCovers(outer: string, inner: string): boolean {\n return covers(outer, inner, true)\n}\n\n/** Glob matching of `subject` by `pattern`; with `starsAreWildcards`, `*` of `subject` only match `*` of `pattern`. */\nfunction covers(pattern: string, subject: string, starsAreWildcards: boolean): boolean {\n const p = collapseStars(pattern)\n const s = starsAreWildcards ? collapseStars(subject) : subject\n // previous[j]: p[0, i - 1) matches s[0, j)\n let previous: boolean[] = new Array<boolean>(s.length + 1).fill(false)\n previous[0] = true\n for (let i = 1; i <= p.length; i++) {\n const char = p[i - 1]\n const current: boolean[] = new Array<boolean>(s.length + 1).fill(false)\n current[0] = char === '*' && previous[0] === true\n for (let j = 1; j <= s.length; j++) {\n if (char === '*') {\n current[j] = previous[j] === true || current[j - 1] === true\n } else {\n const subjectChar = s[j - 1]\n current[j] = previous[j - 1] === true && subjectChar === char && !(starsAreWildcards && subjectChar === '*')\n }\n }\n previous = current\n }\n return previous[s.length] === true\n}\n\n/** `a**b` → `a*b` (same language). */\nfunction collapseStars(pattern: string): string {\n return pattern.replace(/\\*{2,}/g, '*')\n}\n","/**\n * Helpers on statically evaluated decorator arguments and their source locations.\n */\nimport type { ArgInfo, Location, Project, StaticValue } from '@znight/compiler'\n\ntype Expression = ArgInfo['node']\n\n/** An evaluated object literal (not an array, not a reference to an exported binding). */\nexport function isRecord(value: StaticValue): value is Readonly<Record<string, StaticValue>> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false\n const prototype: unknown = Object.getPrototypeOf(value)\n return prototype === Object.prototype || prototype === null\n}\n\n/** Short description of a value for messages (`\"orders\"`, `42`, `an array`...). */\nexport function describeValue(value: StaticValue): string {\n if (value === undefined) return 'undefined'\n if (value === null) return 'null'\n if (typeof value === 'string') return JSON.stringify(value)\n if (typeof value === 'bigint') return `${value}n`\n if (typeof value !== 'object') return String(value)\n if (Array.isArray(value)) return 'an array'\n return isRecord(value) ? 'an object' : `a reference to '${(value as { readonly text?: string }).text ?? '?'}'`\n}\n\n/**\n * Location of the property `key` of an object literal argument (`attempts: 0` in\n * `@Retry({ attempts: 0 })`), or of the whole argument when it is not an inline object literal.\n */\nexport function propertyLocation(project: Project, arg: ArgInfo, key: string): Location {\n let node: Expression = arg.node\n while (\n node.type === 'TSAsExpression' ||\n node.type === 'TSSatisfiesExpression' ||\n node.type === 'TSNonNullExpression' ||\n node.type === 'ParenthesizedExpression'\n ) {\n node = node.expression\n }\n if (node.type !== 'ObjectExpression') return arg.location\n for (const property of node.properties) {\n if (property.type !== 'Property' || property.computed) continue\n const { key: name } = property\n const found =\n name.type === 'Identifier' ? name.name : name.type === 'Literal' && typeof name.value === 'string' && name.value\n if (found === key) return project.getFile(arg.location.file)?.location(property) ?? arg.location\n }\n return arg.location\n}\n\n/** Closest candidate of `name` among `candidates` (typos: `attempt` → `attempts`), if any. */\nexport function closest(name: string, candidates: readonly string[]): string | undefined {\n let best: string | undefined\n let bestDistance = Math.max(2, Math.floor(name.length / 3)) + 1\n for (const candidate of candidates) {\n const distance = editDistance(name.toLowerCase(), candidate.toLowerCase())\n if (distance < bestDistance) {\n best = candidate\n bestDistance = distance\n }\n }\n return best\n}\n\nfunction editDistance(a: string, b: string): number {\n let previous = Array.from({ length: b.length + 1 }, (_, index) => index)\n for (let i = 1; i <= a.length; i++) {\n const current = [i]\n for (let j = 1; j <= b.length; j++) {\n const substitution = (previous[j - 1] ?? 0) + (a[i - 1] === b[j - 1] ? 0 : 1)\n current[j] = Math.min((previous[j] ?? 0) + 1, (current[j - 1] ?? 0) + 1, substitution)\n }\n previous = current\n }\n return previous[b.length] ?? 0\n}\n","/**\n * Compile-time validation and normalization of `@Retry` options. Mirrors the runtime\n * `normalizeRetry()` (same rules and defaults) so that invalid policies fail the build instead of the\n * boot; it also rejects unknown options (typos) and warns about options without effect.\n */\nimport type { AnalyzeContext, DecoratorInfo, StaticValue } from '@znight/compiler'\nimport type { MessagingData, RetryPolicyData } from './data.ts'\n\nimport {\n DEFAULT_BACKOFF,\n DEFAULT_RETRY_DELAY_MS,\n INVALID_CONSUMER,\n INVALID_DECORATOR,\n MAX_RETRY_ATTEMPTS,\n} from './constants.ts'\nimport { closest, describeValue, isRecord, propertyLocation } from './values.ts'\n\nconst RETRY_OPTIONS: readonly string[] = ['attempts', 'backoff', 'delay', 'maxDelay']\n\n/**\n * Validates the argument of a `@Retry` decorator and fills the runtime defaults. Returns `undefined`\n * (after reporting the problems) when the options are invalid.\n *\n * @param where the handler (`OrderConsumer.placed()`), used in messages\n */\nexport function normalizeRetryDecorator(\n decorator: DecoratorInfo,\n where: string,\n ctx: AnalyzeContext<MessagingData>,\n): RetryPolicyData | undefined {\n if (!decorator.called) return undefined // `@Retry` without call: already reported\n const arg = decorator.args[0]\n if (arg === undefined) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@Retry on ${where} requires options: @Retry({ attempts: 3 })`,\n location: decorator.location,\n hints: ['attempts counts the first delivery: { attempts: 3 } means 1 delivery + 2 retries'],\n })\n return undefined\n }\n if (!arg.evaluated) return undefined // not statically evaluable: already reported\n const options = arg.value\n if (!isRecord(options)) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@Retry on ${where} expects an options object ({ attempts, backoff?, delay?, maxDelay? }), got ${describeValue(options)}`,\n location: arg.location,\n })\n return undefined\n }\n\n let valid = true\n const fail = (key: string, message: string, hints?: readonly string[]): void => {\n valid = false\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `@Retry on ${where}: ${message}`,\n location: propertyLocation(ctx.project, arg, key),\n ...(hints === undefined ? {} : { hints }),\n })\n }\n\n for (const key of Object.keys(options)) {\n if (RETRY_OPTIONS.includes(key)) continue\n const suggestion = closest(key, RETRY_OPTIONS)\n fail(key, `unknown option \"${key}\"`, [\n suggestion === undefined\n ? `Valid options: ${RETRY_OPTIONS.join(', ')}`\n : `Did you mean \"${suggestion}\"? Valid options: ${RETRY_OPTIONS.join(', ')}`,\n ])\n }\n\n const attempts = options['attempts']\n if (attempts === undefined) {\n fail('attempts', '\"attempts\" is required', [\n 'attempts counts the first delivery: { attempts: 3 } means 1 delivery + 2 retries',\n ])\n } else if (!isInteger(attempts) || attempts < 1 || attempts > MAX_RETRY_ATTEMPTS) {\n fail(\n 'attempts',\n `\"attempts\" must be an integer between 1 and ${MAX_RETRY_ATTEMPTS}, got ${describeValue(attempts)}`,\n ['attempts counts the first delivery: { attempts: 3 } means 1 delivery + 2 retries'],\n )\n }\n\n const rawBackoff = options['backoff']\n const backoff = rawBackoff === undefined ? DEFAULT_BACKOFF : rawBackoff\n if (backoff !== 'fixed' && backoff !== 'exponential') {\n fail('backoff', `\"backoff\" must be 'fixed' or 'exponential', got ${describeValue(backoff)}`)\n }\n\n const rawDelay = options['delay']\n const delay = rawDelay === undefined ? DEFAULT_RETRY_DELAY_MS : rawDelay\n const delayValid = isDuration(delay)\n if (!delayValid) {\n fail('delay', `\"delay\" must be a finite number of milliseconds >= 0, got ${describeValue(delay)}`)\n }\n\n const maxDelay = options['maxDelay']\n if (maxDelay !== undefined) {\n if (!isDuration(maxDelay) || (delayValid && maxDelay < delay)) {\n fail(\n 'maxDelay',\n `\"maxDelay\" must be a finite number of milliseconds >= delay${delayValid ? ` (${delay})` : ''}, got ${describeValue(maxDelay)}`,\n )\n } else if (backoff === 'fixed') {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'warning',\n message: `@Retry on ${where}: \"maxDelay\" has no effect with backoff 'fixed' (every retry waits \"delay\")`,\n location: propertyLocation(ctx.project, arg, 'maxDelay'),\n hints: [\"Remove maxDelay, or use backoff: 'exponential'\"],\n })\n }\n }\n\n if (!valid || !isInteger(attempts) || (backoff !== 'fixed' && backoff !== 'exponential') || !isDuration(delay)) {\n return undefined\n }\n const policy: RetryPolicyData = isDuration(maxDelay)\n ? { attempts, backoff, delay, maxDelay }\n : { attempts, backoff, delay }\n return Object.freeze(policy)\n}\n\nfunction isInteger(value: StaticValue): value is number {\n return typeof value === 'number' && Number.isInteger(value)\n}\n\nfunction isDuration(value: StaticValue): value is number {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0\n}\n","/**\n * `analyzeClass` of the messaging extension: reads `@Consumer` classes, their `@OnMessage` handlers\n * (`@Retry`, parameters), their `@OnError` method, registers the consumer provider and reports every\n * problem that can be detected on one class (ZNIGHT005, ZNIGHT011, ZNIGHT017).\n *\n * Handlers may be declared on base classes: the consumer inherits the messaging methods of its\n * analysable base classes (the nearest declaration of a method carrying messaging decorators wins, an\n * override without decorators keeps the inherited handler).\n */\nimport type {\n AnalyzeContext,\n ClassInfo,\n DecoratorInfo,\n Location,\n MethodInfo,\n ParameterInfo,\n StaticValue,\n TypeHelpers,\n TypeInfo,\n ValueRef,\n} from '@znight/compiler'\nimport type { Scope } from '@znight/core'\nimport type { HandlerData, HandlerParamData, MessagingData, RetryPolicyData } from './data.ts'\n\nimport {\n CONSUMER_SCOPES,\n EXTENSION_NAME,\n INBOUND_MESSAGE_IDENTITY,\n INVALID_CONSUMER,\n INVALID_DECORATOR,\n METHOD_DECORATORS,\n MessagingDecorator,\n PARAMETER_DECORATORS,\n RUNTIME_MODULE,\n UNVALIDATED_INPUT,\n} from './constants.ts'\nimport { isPattern, patternCovers } from './patterns.ts'\nimport { normalizeRetryDecorator } from './retry.ts'\nimport { describeValue, isRecord, propertyLocation } from './values.ts'\n\ntype Context = AnalyzeContext<MessagingData>\n\n/** The messaging declarations of one method. */\ninterface MemberAnalysis {\n readonly method: string\n readonly declaredBy: string\n /** Number of `@OnMessage` decorators (valid or not). */\n readonly onMessage: number\n /** One entry per valid `@OnMessage` decorator. */\n readonly handlers: readonly HandlerData[]\n /** Location of the `@OnError` decorator when the method is the error handler. */\n readonly errorHandler: Location | undefined\n}\n\n/** Types injected as is by `@Message()` without being \"unvalidated input\" (binary payloads). */\nconst BINARY_TYPES: ReadonlySet<string> = new Set([\n 'globalThis#Uint8Array',\n 'globalThis#ArrayBuffer',\n 'globalThis#Buffer',\n 'node:buffer#Buffer',\n 'buffer#Buffer',\n])\n\n/** Maximum depth of the base class chain walked for inherited handlers. */\nconst MAX_CHAIN = 32\n\n/** Analyses a class carrying at least one decorator of the extension. */\nexport function analyzeMessagingClass(cls: ClassInfo, ctx: Context): void {\n const own = analyzeMembers(cls, ctx)\n const consumers = cls.decorators.filter(decorator => decorator.identity === MessagingDecorator.Consumer)\n const consumer = consumers[0]\n if (consumer === undefined) {\n const decorators = cls.methods.flatMap(method =>\n method.decorators\n .filter(decorator => decorator.identity !== undefined && METHOD_DECORATORS.has(decorator.identity))\n .map(decorator => ({ name: decorator.name, location: decorator.location })),\n )\n if (decorators.length > 0) {\n ctx.store({\n kind: 'members',\n identity: cls.identity,\n displayName: cls.displayName,\n abstract: cls.abstract,\n decorators,\n })\n }\n return\n }\n for (const duplicate of consumers.slice(1)) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@${duplicate.name} is applied several times on ${cls.displayName}`,\n location: duplicate.location,\n hints: [`Keep a single @${duplicate.name}: a class consumes one queue`],\n })\n }\n\n const options = readConsumerOptions(consumer, cls, ctx)\n const token = ctx.registerProvider(cls, { scope: options.scope })\n const chain = classChain(cls, ctx)\n\n // messaging methods of the class and its bases: the nearest declaration wins, at the position of\n // the first declaration (base classes first)\n const merged = new Map<string, MemberAnalysis>()\n for (let index = chain.length - 1; index >= 0; index--) {\n const owner = chain[index] as ClassInfo\n for (const [name, member] of index === 0 ? own : analyzeMembers(owner, ctx)) merged.set(name, member)\n }\n const members = [...merged.values()]\n const handlers = members.flatMap(member => member.handlers)\n\n if (!members.some(member => member.onMessage > 0)) {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `@Consumer ${cls.displayName} has no @OnMessage handler`,\n location: consumer.location,\n hints: ['Decorate at least one public method with @OnMessage() (default handler) or @OnMessage(\"type\")'],\n })\n }\n checkHandlerTypes(cls.displayName, handlers, ctx)\n\n const errorHandlers = members.filter(member => member.errorHandler !== undefined)\n const errorHandler = errorHandlers[0]\n for (const extra of errorHandlers.slice(1)) {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `@Consumer ${cls.displayName} has several @OnError methods: ${errorHandlers.map(member => `${member.declaredBy}.${member.method}()`).join(', ')}`,\n location: extra.errorHandler as Location,\n hints: ['Keep a single @OnError method per consumer'],\n related: [{ message: 'First @OnError method', location: errorHandler?.errorHandler as Location }],\n })\n }\n\n ctx.store({\n kind: 'consumer',\n token,\n identity: cls.identity,\n displayName: cls.displayName,\n queue: options.queue,\n options: options.options,\n handlers,\n errorHandler: errorHandler?.method,\n chain: chain.map(owner => owner.identity),\n location: consumer.location,\n })\n}\n\n// ------------------------------------------------------------------------------------------ consumer\n\ninterface ConsumerOptions {\n /** Empty when invalid (reported). */\n readonly queue: string\n readonly scope: Scope\n readonly options: Readonly<Record<string, StaticValue>> | undefined\n}\n\n/** `@Consumer(queue)` / `@Consumer({ queue, scope?, concurrency?, deadLetter?, ...driver options })`. */\nfunction readConsumerOptions(decorator: DecoratorInfo, cls: ClassInfo, ctx: Context): ConsumerOptions {\n const invalid: ConsumerOptions = { queue: '', scope: 'singleton', options: undefined }\n const prefix = `@Consumer ${cls.displayName}`\n if (!decorator.called) return invalid // `@Consumer` without call: already reported\n const arg = decorator.args[0]\n if (arg === undefined) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `${prefix}: the queue to consume is required`,\n location: decorator.location,\n hints: [\"Write @Consumer('orders') or @Consumer({ queue: 'orders', concurrency: 5 })\"],\n })\n return invalid\n }\n if (!arg.evaluated) return invalid // not statically evaluable: already reported\n const value = arg.value\n if (typeof value === 'string') {\n if (value === '') {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `${prefix}: the queue must be a non-empty string`,\n location: arg.location,\n })\n }\n return { queue: value, scope: 'singleton', options: undefined }\n }\n if (!isRecord(value)) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `${prefix}: expected a queue name or an options object ({ queue, scope?, concurrency?, deadLetter? }), got ${describeValue(value)}`,\n location: arg.location,\n })\n return invalid\n }\n\n const fail = (key: string, message: string, hints?: readonly string[]): void => {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `${prefix}: ${message}`,\n location: propertyLocation(ctx.project, arg, key),\n ...(hints === undefined ? {} : { hints }),\n })\n }\n\n let queue = ''\n const rawQueue = value['queue']\n if (rawQueue === undefined) {\n fail('queue', 'the \"queue\" option is required', [\"Write @Consumer({ queue: 'orders', ... })\"])\n } else if (typeof rawQueue !== 'string' || rawQueue === '') {\n fail('queue', `\"queue\" must be a non-empty string, got ${describeValue(rawQueue)}`)\n } else {\n queue = rawQueue\n }\n\n let scope: Scope = 'singleton'\n const rawScope = value['scope']\n if (rawScope !== undefined) {\n if (typeof rawScope === 'string' && CONSUMER_SCOPES.includes(rawScope)) {\n scope = rawScope as Scope\n } else {\n fail('scope', `\"scope\" must be 'singleton', 'request' or 'transient', got ${describeValue(rawScope)}`)\n }\n }\n\n const concurrency = value['concurrency']\n if (\n concurrency !== undefined &&\n !(typeof concurrency === 'number' && Number.isSafeInteger(concurrency) && concurrency > 0)\n ) {\n fail('concurrency', `\"concurrency\" must be a positive integer, got ${describeValue(concurrency)}`)\n }\n\n const deadLetter = value['deadLetter']\n if (deadLetter !== undefined && deadLetter !== false && (typeof deadLetter !== 'string' || deadLetter === '')) {\n fail('deadLetter', `\"deadLetter\" must be a queue name or false, got ${describeValue(deadLetter)}`)\n } else if (deadLetter === queue && queue !== '') {\n fail('deadLetter', `the dead-letter queue cannot be the consumed queue \"${queue}\"`, [\n 'Use another queue (default: the driver naming, e.g. \"orders.dlq\"), or false to disable dead-lettering',\n ])\n }\n\n const options: Record<string, StaticValue> = {}\n for (const [key, option] of Object.entries(value)) {\n if (key === 'queue' || key === 'scope' || option === undefined) continue\n options[key] = option\n }\n return { queue, scope, options: Object.keys(options).length === 0 ? undefined : Object.freeze(options) }\n}\n\n/** The class and its analysable base classes (nearest first). */\nfunction classChain(cls: ClassInfo, ctx: Context): ClassInfo[] {\n const chain = [cls]\n const seen = new Set([cls.identity])\n let current = cls\n while (current.superClass !== undefined && chain.length < MAX_CHAIN) {\n const base = ctx.classInfo(current.superClass.identity)\n if (base === undefined || seen.has(base.identity)) break\n chain.push(base)\n seen.add(base.identity)\n current = base\n }\n return chain\n}\n\n/**\n * Handler selection checks, mirroring the runtime (`consumers.ts`): exact types first, then patterns\n * in declaration order, then the single default handler.\n */\nfunction checkHandlerTypes(consumer: string, handlers: readonly HandlerData[], ctx: Context): void {\n let fallback: HandlerData | undefined\n const exact = new Map<string, HandlerData>()\n const patterns: (HandlerData & { readonly type: string })[] = []\n const label = (handler: HandlerData): string => `${handler.declaredBy}.${handler.method}()`\n for (const handler of handlers) {\n const type = handler.type\n if (type === undefined) {\n if (fallback === undefined) {\n fallback = handler\n continue\n }\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `@Consumer ${consumer}: ${label(fallback)} and ${label(handler)} are both default @OnMessage() handlers`,\n location: handler.location,\n hints: ['Give one of them a message type: @OnMessage(\"order.created\")'],\n related: [{ message: 'First default handler', location: fallback.location }],\n })\n continue\n }\n const previous = isPattern(type) ? patterns.find(pattern => pattern.type === type) : exact.get(type)\n if (previous !== undefined) {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `@Consumer ${consumer}: several @OnMessage handlers for type \"${type}\" (${label(previous)} and ${label(handler)})`,\n location: handler.location,\n hints: ['A message type is handled by a single method: merge the handlers'],\n related: [{ message: `First handler of \"${type}\"`, location: previous.location }],\n })\n continue\n }\n if (!isPattern(type)) {\n exact.set(type, handler)\n continue\n }\n const covering = patterns.find(pattern => patternCovers(pattern.type, type))\n if (covering !== undefined) {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `@Consumer ${consumer}: the pattern \"${type}\" of ${label(handler)} never matches: every type it matches is matched first by \"${covering.type}\" (${label(covering)})`,\n location: handler.location,\n hints: ['Patterns are tried in declaration order (after exact types): declare the more specific pattern first'],\n related: [{ message: `Pattern \"${covering.type}\"`, location: covering.location }],\n })\n }\n patterns.push({ ...handler, type })\n }\n}\n\n// ------------------------------------------------------------------------------------------- members\n\n/** Messaging methods declared by `cls` itself, by name, in declaration order. */\nfunction analyzeMembers(cls: ClassInfo, ctx: Context): Map<string, MemberAnalysis> {\n const members = new Map<string, MemberAnalysis>()\n for (const method of cls.methods) {\n const member = analyzeMethod(cls, method, ctx)\n if (member !== undefined) members.set(method.name, member)\n }\n return members\n}\n\nfunction analyzeMethod(cls: ClassInfo, method: MethodInfo, ctx: Context): MemberAnalysis | undefined {\n const onMessage = decoratorsOf(method.decorators, MessagingDecorator.OnMessage)\n const retry = decoratorsOf(method.decorators, MessagingDecorator.Retry)\n const onError = decoratorsOf(method.decorators, MessagingDecorator.OnError)\n const decoratedParams = method.params.some(param => param.decorators.some(isParameterDecorator))\n if (onMessage.length === 0 && retry.length === 0 && onError.length === 0 && !decoratedParams) return undefined\n\n const where = `${cls.displayName}.${method.name}()`\n const primary = onMessage[0] ?? onError[0]\n if (primary !== undefined) checkMethodShape(method, primary, where, ctx)\n for (const duplicate of [...retry.slice(1), ...onError.slice(1)]) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@${duplicate.name} is applied several times on ${where}`,\n location: duplicate.location,\n hints: [`Keep a single @${duplicate.name}`],\n })\n }\n if (onMessage.length > 0 && onError[0] !== undefined) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `${where} cannot be both an @OnMessage handler and the @OnError method`,\n location: onError[0].location,\n hints: ['Declare the error handler in a separate method'],\n })\n }\n if (onMessage.length === 0 && retry[0] !== undefined) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@Retry has no effect on ${where}: it is not an @OnMessage handler`,\n location: retry[0].location,\n hints: ['Add @OnMessage() to the method, or remove @Retry'],\n })\n }\n\n let handlers: HandlerData[] = []\n if (onMessage.length > 0) {\n const policy: RetryPolicyData | undefined =\n retry[0] === undefined ? undefined : normalizeRetryDecorator(retry[0], where, ctx)\n const params = analyzeHandlerParams(cls, method, where, ctx)\n handlers = onMessage.flatMap(decorator => {\n const type = messageType(decorator, where, ctx)\n if (type === false) return []\n return [\n Object.freeze({\n method: method.name,\n type,\n retry: policy,\n params,\n declaredBy: cls.displayName,\n location: decorator.location,\n }),\n ]\n })\n } else {\n reportStrayParameterDecorators(method, where, onError.length > 0, ctx)\n }\n\n const errorHandler = onMessage.length === 0 ? onError[0] : undefined\n if (errorHandler !== undefined) checkErrorHandler(method, errorHandler, where, ctx)\n return {\n method: method.name,\n declaredBy: cls.displayName,\n onMessage: onMessage.length,\n handlers,\n errorHandler: errorHandler?.location,\n }\n}\n\n/** Handlers are called by the generated code: `consumer.method(...)`. */\nfunction checkMethodShape(method: MethodInfo, decorator: DecoratorInfo, where: string, ctx: Context): void {\n const name = `@${decorator.name}`\n let problem: { message: string; hint: string } | undefined\n if (method.kind !== 'method') {\n problem = { message: `${name} cannot be applied to the accessor ${where}`, hint: 'Use a regular method' }\n } else if (method.static) {\n problem = {\n message: `${name} cannot be applied to the static method ${where}`,\n hint: 'Handlers are called on the consumer instance: remove `static`',\n }\n } else if (method.privateName) {\n problem = {\n message: `${name} cannot be applied to the #private method ${where}`,\n hint: 'Use a public method: the generated code calls it',\n }\n } else if (method.visibility !== 'public') {\n problem = {\n message: `${where} must be public: ${name} methods are called by the generated code`,\n hint: `Remove the '${method.visibility}' modifier`,\n }\n } else if (method.computed) {\n problem = {\n message: `${name} cannot be applied to ${where}: computed method names are not supported`,\n hint: 'Use a plain method name',\n }\n } else if (method.generator) {\n problem = {\n message: `${name} cannot be applied to the generator method ${where}`,\n hint: 'Use a regular (or async) method',\n }\n }\n if (problem !== undefined) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: problem.message,\n location: decorator.location,\n hints: [problem.hint],\n })\n }\n}\n\n/** Type of an `@OnMessage` decorator: a string, `undefined` (default handler) or `false` (invalid). */\nfunction messageType(decorator: DecoratorInfo, where: string, ctx: Context): string | undefined | false {\n const arg = decorator.args[0]\n if (arg === undefined || (arg.evaluated && arg.value === undefined)) return undefined\n if (!arg.evaluated) return false // not statically evaluable: already reported\n if (typeof arg.value !== 'string') {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@OnMessage on ${where} expects a message type (a string), got ${describeValue(arg.value)}`,\n location: arg.location,\n hints: ['Use @OnMessage() for the default handler'],\n })\n return false\n }\n if (arg.value === '') {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `The @OnMessage type of ${where} must be a non-empty string`,\n location: arg.location,\n hints: ['Use @OnMessage() for the default handler'],\n })\n return false\n }\n return arg.value\n}\n\n/** The `@OnError` method is called as `consumer[method](error, message)`. */\nfunction checkErrorHandler(method: MethodInfo, decorator: DecoratorInfo, where: string, ctx: Context): void {\n const required = method.params.filter(param => !param.optional && !param.hasDefault && !param.rest).length\n if (required > 2) {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `The @OnError method ${where} has ${required} required parameters: it is called with (error, message)`,\n location: method.location,\n hints: ['Declare onError(error: unknown, message: InboundMessage)'],\n })\n }\n if (method.returnType !== undefined && !isErrorHandlerResult(ctx.types.awaited(method.returnType))) {\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `The @OnError method ${where} returns '${ctx.types.format(method.returnType)}': return 'ack' to acknowledge the message, or nothing to dead-letter it`,\n location: decorator.location,\n hints: [\"Declare the return type `'ack' | undefined` (or `void`)\"],\n })\n }\n}\n\n// ---------------------------------------------------------------------------------------- parameters\n\nfunction analyzeHandlerParams(\n cls: ClassInfo,\n method: MethodInfo,\n where: string,\n ctx: Context,\n): readonly HandlerParamData[] {\n return Object.freeze(method.params.map(param => analyzeHandlerParam(cls, param, where, ctx)))\n}\n\nfunction analyzeHandlerParam(cls: ClassInfo, param: ParameterInfo, where: string, ctx: Context): HandlerParamData {\n const decorators = parameterDecorators(param)\n // custom parameter decorators (RFC 0010); compilers before it have no paramDecorator\n const custom = typeof ctx.paramDecorator === 'function' ? ctx.paramDecorator(param, 'messaging', cls) : undefined\n if (custom !== undefined) {\n for (const other of decorators) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `Parameter '${param.name}' of ${where} has several parameter decorators (@${custom.decorator.name} and @${other.name})`,\n location: other.location,\n hints: ['Keep a single parameter decorator'],\n })\n }\n if (!custom.ok || decorators.length > 0) return { kind: 'undefined' }\n const data = custom.data\n return {\n kind: 'custom',\n identity: custom.identity,\n name: custom.name,\n data: data === undefined ? undefined : { value: data.ref ?? (data.value as StaticValue) },\n resolver: custom.resolver.kind === 'class' ? custom.resolver.ref : undefined,\n ...(custom.resolver.kind === 'class' && custom.resolver.arity !== undefined\n ? { arity: custom.resolver.arity }\n : {}),\n cast: custom.cast,\n }\n }\n const decorator = decorators[0]\n if (decorator === undefined) {\n const foreign = foreignParameterDecorator(param)\n if (foreign !== undefined) {\n // e.g. `Headers` auto-imported from '@znight/http': one precise error instead of \"no decorator\"\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@${foreign.decorator.name} on parameter '${param.name}' of ${where} is imported from '${foreign.module}': @OnMessage handler parameters use ${foreign.name} from '${RUNTIME_MODULE}'`,\n location: foreign.decorator.location,\n hints: [`Import it from '${RUNTIME_MODULE}': import { ${foreign.name} } from '${RUNTIME_MODULE}'`],\n })\n return { kind: 'undefined' }\n }\n if (param.optional || param.hasDefault || param.rest) return { kind: 'undefined' }\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `Parameter '${param.name}' of ${where} has no @Message(), @Headers() or @Ctx() decorator`,\n location: param.location,\n hints: [\n 'Every handler parameter is extracted from the message: @Message(schema?) for the payload, @Headers(name?) for the headers, @Ctx() for the InboundMessage',\n ],\n })\n return { kind: 'undefined' }\n }\n if (decorators.length > 1) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `Parameter '${param.name}' of ${where} has several messaging decorators (${decorators.map(found => `@${found.name}`).join(', ')})`,\n location: (decorators[1] as DecoratorInfo).location,\n hints: ['Keep a single one'],\n })\n }\n if (param.rest) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@${decorator.name} cannot be applied to the rest parameter '...${param.name}' of ${where}`,\n location: decorator.location,\n })\n return { kind: 'undefined' }\n }\n switch (decorator.identity) {\n case MessagingDecorator.Message:\n return messageParam(param, decorator, where, ctx)\n case MessagingDecorator.Headers:\n return headersParam(param, decorator, where, ctx)\n default:\n return { kind: 'message', narrow: narrowsPayload(param.type, ctx.types) }\n }\n}\n\n/** `@Message()` / `@Message(schema)`. */\nfunction messageParam(param: ParameterInfo, decorator: DecoratorInfo, where: string, ctx: Context): HandlerParamData {\n const arg = decorator.args[0]\n if (arg === undefined || (arg.evaluated && arg.value === undefined)) {\n checkUnvalidated(param, decorator, where, ctx)\n return { kind: 'payload' }\n }\n if (arg.ref !== undefined) {\n if (isClassReference(arg.ref)) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@Message(${arg.text}) on ${where}: '${arg.ref.name}' is a class, not a Standard Schema`,\n location: arg.location,\n hints: [\n 'Pass a Standard Schema (Zod, Valibot, ArkType...): export const OrderPlaced = z.object({ ... })',\n 'Or inject the raw payload with @Message() and validate it in the handler',\n ],\n })\n return { kind: 'undefined' }\n }\n return { kind: 'validated', schema: arg.ref }\n }\n if (!arg.evaluated) return { kind: 'undefined' } // unexported or invalid reference: already reported\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@Message on ${where} expects a Standard Schema (Zod, Valibot, ArkType...), got ${describeValue(arg.value)}`,\n location: arg.location,\n hints: [\n 'Declare the schema with `export const OrderPlaced = z.object({ ... })` and pass it: @Message(OrderPlaced)',\n ],\n })\n return { kind: 'undefined' }\n}\n\n/** `@Headers()` / `@Headers(name)`. */\nfunction headersParam(param: ParameterInfo, decorator: DecoratorInfo, where: string, ctx: Context): HandlerParamData {\n const arg = decorator.args[0]\n if (arg === undefined || (arg.evaluated && arg.value === undefined)) return { kind: 'headers' }\n if (!arg.evaluated) return { kind: 'undefined' } // not statically evaluable: already reported\n const name = arg.value\n if (typeof name !== 'string' || name === '') {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@Headers on ${where} expects a header name (a non-empty string), got ${describeValue(name)}`,\n location: arg.location,\n hints: ['Use @Headers() to inject every header'],\n })\n return { kind: 'undefined' }\n }\n if (!param.optional && !param.hasDefault && !acceptsUndefined(param.type)) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'warning',\n message: `@Headers(${JSON.stringify(name)}) injects 'string | undefined' (the header may be missing) but parameter '${param.name}' of ${where} is typed '${ctx.types.format(param.type)}'`,\n location: param.typeLocation,\n hints: [`Declare it '${param.name}?: string' or '${param.name}: string | undefined', or give it a default value`],\n })\n }\n return { kind: 'header', name }\n}\n\n/** ZNIGHT017: a structured payload injected without schema is trusted blindly. */\nfunction checkUnvalidated(param: ParameterInfo, decorator: DecoratorInfo, where: string, ctx: Context): void {\n const { type } = ctx.types.stripNullish(param.type)\n if (isSafePayloadType(type)) return\n const typed =\n type.kind === 'opaque' && type.reason === 'missing-annotation'\n ? 'has no type annotation'\n : `is typed '${ctx.types.format(param.type)}'`\n ctx.report({\n code: UNVALIDATED_INPUT,\n severity: ctx.options.strictValidation ? 'error' : 'warning',\n message: `Unvalidated message payload: parameter '${param.name}' of ${where} ${typed} but @Message() has no schema`,\n location: decorator.location,\n hints: [\n 'Validate it with a Standard Schema (Zod, Valibot, ArkType...): @Message(OrderPlaced)',\n \"Or declare the parameter as 'unknown' and check it in the handler\",\n ],\n })\n}\n\n/** Methods whose parameters carry messaging decorators without being `@OnMessage` handlers. */\nfunction reportStrayParameterDecorators(method: MethodInfo, where: string, errorHandler: boolean, ctx: Context): void {\n // a method handled by another extension (an HTTP route...): the decorator comes from the wrong package\n const owner = errorHandler ? undefined : foreignHandler(method)\n for (const param of method.params) {\n for (const decorator of parameterDecorators(param)) {\n let hint = 'Add @OnMessage() to the method, or remove the decorator'\n if (errorHandler) hint = '@OnError methods are called with (error, message): remove the decorator'\n else if (owner !== undefined) {\n hint = `${where} is a @${owner.decorator.name} handler: use the parameter decorators of '${owner.module}'`\n }\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message:\n owner === undefined\n ? `@${decorator.name} has no effect on parameter '${param.name}' of ${where}: it is not an @OnMessage handler`\n : `@${decorator.name} (from '${RUNTIME_MODULE}') has no effect on parameter '${param.name}' of ${where}: it is not an @OnMessage handler`,\n location: decorator.location,\n hints: [hint],\n })\n }\n }\n}\n\n/** A decorator, with the module and the export name of its identity (`'@znight/http#Get'`). */\ninterface ForeignDecorator {\n readonly decorator: DecoratorInfo\n readonly module: string\n readonly name: string\n}\n\nfunction splitIdentity(decorator: DecoratorInfo): ForeignDecorator | undefined {\n const identity = decorator.identity\n const separator = identity?.lastIndexOf('#') ?? -1\n if (identity === undefined || separator <= 0) return undefined\n return { decorator, module: identity.slice(0, separator), name: identity.slice(separator + 1) }\n}\n\n/**\n * A parameter decorator named like a messaging one (`Headers`, `Ctx`, `Message`) but imported from\n * another package (`@znight/http` has `Headers` and `Ctx` too).\n */\nfunction foreignParameterDecorator(param: ParameterInfo): ForeignDecorator | undefined {\n for (const decorator of param.decorators) {\n const split = splitIdentity(decorator)\n if (split === undefined || split.module === RUNTIME_MODULE) continue\n if (PARAMETER_DECORATORS.has(`${RUNTIME_MODULE}#${split.name}`)) return split\n }\n return undefined\n}\n\n/** The decorator through which another extension handles the method (`@Get` of `@znight/http`...). */\nfunction foreignHandler(method: MethodInfo): ForeignDecorator | undefined {\n for (const decorator of method.decorators) {\n const owner = decorator.owner\n if (owner === undefined || owner === EXTENSION_NAME || owner === 'core' || owner === 'manifest') continue\n const split = splitIdentity(decorator)\n if (split !== undefined) return split\n }\n return undefined\n}\n\n// ------------------------------------------------------------------------------------------- helpers\n\nfunction decoratorsOf(decorators: readonly DecoratorInfo[], identity: string): DecoratorInfo[] {\n return decorators.filter(decorator => decorator.identity === identity)\n}\n\n/**\n * Messaging decorators of a parameter. De-duplicated by position: the compiler (0.1) reports the\n * decorators of a parameter with a default value (`@Headers('x') x = 'a'`) twice.\n */\nfunction parameterDecorators(param: ParameterInfo): DecoratorInfo[] {\n const seen = new Set<number>()\n return param.decorators.filter(decorator => {\n if (!isParameterDecorator(decorator) || seen.has(decorator.location.start)) return false\n seen.add(decorator.location.start)\n return true\n })\n}\n\nfunction isParameterDecorator(decorator: DecoratorInfo): boolean {\n return decorator.identity !== undefined && PARAMETER_DECORATORS.has(decorator.identity)\n}\n\n/** A reference to a class declaration (`@Message(OrderDto)`). */\nfunction isClassReference(ref: ValueRef): boolean {\n const symbol = ref.symbol\n return symbol.kind === 'declaration' && symbol.declaration.kind === 'class'\n}\n\n/** Primitive and binary payload types need no schema (`unknown` is honest, `any` is not). */\nfunction isSafePayloadType(type: TypeInfo): boolean {\n switch (type.kind) {\n case 'primitive':\n return type.name !== 'any' && type.name !== 'object'\n case 'literal':\n return true\n case 'union':\n return type.types.every(isSafePayloadType)\n case 'reference':\n return BINARY_TYPES.has(type.identity)\n default:\n return false\n }\n}\n\n/** Whether `undefined` is assignable to the type (unknown types are given the benefit of the doubt). */\nfunction acceptsUndefined(type: TypeInfo): boolean {\n switch (type.kind) {\n case 'primitive':\n return type.name === 'any' || type.name === 'unknown' || type.name === 'undefined' || type.name === 'void'\n case 'union':\n return type.types.some(acceptsUndefined)\n case 'opaque':\n case 'typeParameter':\n return true\n default:\n return false\n }\n}\n\n/** Valid results of an `@OnError` method: `'ack'`, nothing (`void`, `undefined`), or unknown types. */\nfunction isErrorHandlerResult(type: TypeInfo): boolean {\n switch (type.kind) {\n case 'primitive':\n return ['void', 'undefined', 'any', 'unknown', 'never'].includes(type.name)\n case 'literal':\n return type.value === 'ack'\n case 'union':\n return type.types.every(isErrorHandlerResult)\n case 'promise':\n return isErrorHandlerResult(type.inner)\n case 'opaque':\n case 'typeParameter':\n return true\n default:\n return false\n }\n}\n\n/** `@Ctx() message: InboundMessage<Order>` narrows the payload: the invoker casts `m`. */\nfunction narrowsPayload(type: TypeInfo, types: TypeHelpers): boolean {\n const { type: inner } = types.stripNullish(type)\n if (inner.kind !== 'reference' || inner.identity !== INBOUND_MESSAGE_IDENTITY) return false\n const payload = inner.typeArgs[0]\n return (\n payload !== undefined && !(payload.kind === 'primitive' && (payload.name === 'unknown' || payload.name === 'any'))\n )\n}\n","/**\n * `generate` of the messaging extension: `metadata.extensions.messaging` (README \"Compiler contract\",\n * spec §9.2). Consumers are sorted by token; handlers keep their declaration order.\n *\n * ```ts\n * {\n * consumers: [{\n * token: 'src/orders/order.consumer.ts#OrderConsumer',\n * queue: 'orders',\n * handlers: [{\n * method: 'placed',\n * type: 'order.placed',\n * retry: { attempts: 5, backoff: 'exponential', delay: 500, maxDelay: 30000 },\n * invoke: async (c: OrderConsumer, m: InboundMessage) => c.placed(await validateMessage(OrderPlaced, m.payload)),\n * }],\n * errorHandler: 'onError',\n * }],\n * }\n * ```\n */\nimport type { ClassRef, GenerateContext, GenInput, GenNode, StaticValue, ValueRef } from '@znight/compiler'\nimport type { ConsumerData, HandlerData, HandlerParamData, MessagingData } from './data.ts'\n\nimport { compareStrings, RUNTIME_MODULE } from './constants.ts'\n\ntype Context = GenerateContext<MessagingData>\n\n/**\n * Imports of the runtime helpers, created on first use only: an import the module does not use would\n * break `noUnusedLocals`.\n */\ninterface Helpers {\n inboundMessage(): GenNode\n validateMessage(): GenNode\n messageHeader(): GenNode\n paramFunctionOf(): GenNode\n}\n\n/** The class resolver instances of the handler being generated (`x`), with the position of each token. */\ninterface Resolvers {\n readonly x: GenNode | undefined\n readonly index: ReadonlyMap<string, number>\n}\n\n/** Builds the messaging section; `undefined` (no section) when the application has no consumer. */\nexport function generateMessaging(ctx: Context): GenNode | undefined {\n const consumers = ctx.stored\n .filter((data): data is ConsumerData => data.kind === 'consumer')\n .sort((a, b) => compareStrings(a.token, b.token))\n if (consumers.length === 0) return undefined\n const helpers = lazyHelpers(ctx)\n return ctx.obj([['consumers', ctx.arr(consumers.map(consumer => consumerNode(ctx, consumer, helpers)))]])\n}\n\nfunction consumerNode(ctx: Context, consumer: ConsumerData, helpers: Helpers): GenNode {\n let classType: GenNode | undefined\n const consumerType = (): GenNode => {\n classType ??= ctx.importType(consumer.identity)\n return classType\n }\n const entries: [string, GenInput][] = [\n ['token', consumer.token],\n ['queue', consumer.queue],\n ]\n if (consumer.options !== undefined) entries.push(['options', ctx.lit(consumer.options)])\n entries.push([\n 'handlers',\n ctx.arr(consumer.handlers.map(handler => handlerNode(ctx, handler, consumerType, helpers))),\n ])\n if (consumer.errorHandler !== undefined) entries.push(['errorHandler', consumer.errorHandler])\n return ctx.obj(entries)\n}\n\nfunction handlerNode(ctx: Context, handler: HandlerData, consumerType: () => GenNode, helpers: Helpers): GenNode {\n const entries: [string, GenInput][] = [['method', handler.method]]\n if (handler.type !== undefined) entries.push(['type', handler.type])\n if (handler.retry !== undefined) entries.push(['retry', ctx.lit({ ...handler.retry })])\n const resolvers = paramResolvers(handler)\n if (resolvers.length > 0) {\n entries.push(['paramResolvers', ctx.lit(resolvers.map(ref => ctx.tokenOf(ref) ?? ref.token))])\n }\n entries.push(['invoke', invokeNode(ctx, handler, consumerType, helpers, resolvers)])\n return ctx.obj(entries)\n}\n\n/** The provider classes resolving custom parameters, in order of first use (`x[i]`). */\nfunction paramResolvers(handler: HandlerData): ClassRef[] {\n const found = new Map<string, ClassRef>()\n for (const param of handler.params) {\n const resolver = param.kind === 'custom' ? param.resolver : undefined\n if (resolver !== undefined && !found.has(resolver.token)) found.set(resolver.token, resolver)\n }\n return [...found.values()]\n}\n\n/**\n * `(c: Consumer, m: InboundMessage) => c.method(...args)`, `async` only when it awaits a schema\n * validation or a custom parameter. `m` is omitted when no argument uses it (`noUnusedParameters`);\n * `x` (the class resolver instances) is declared only when the handler has class resolvers.\n */\nfunction invokeNode(\n ctx: Context,\n handler: HandlerData,\n consumerType: () => GenNode,\n helpers: Helpers,\n resolvers: readonly ClassRef[],\n): GenNode {\n const params = [...handler.params]\n while (params.length > 0 && params[params.length - 1]?.kind === 'undefined') params.pop()\n if (params.length === 0) {\n return ctx.arrow([['c', consumerType()]], c => ctx.call(ctx.member(c, handler.method)))\n }\n // `_m` when only class resolvers whose `resolve()` takes no parameter need arguments (`noUnusedParameters`)\n const readsMessage = params.some(\n param =>\n param.kind !== 'undefined' && (param.kind !== 'custom' || param.resolver === undefined || param.arity !== 0),\n )\n const arrowParams: [string, GenNode][] = [\n ['c', consumerType()],\n [readsMessage ? 'm' : '_m', helpers.inboundMessage()],\n ]\n if (resolvers.length > 0) {\n const types = resolvers.map(ref => ctx.importType(ref))\n const joined = types.slice(1).reduce((all, node) => ctx.code`${all}, ${node}`, types[0] as GenNode)\n arrowParams.push(['x', ctx.code`readonly [${joined}]`])\n }\n const index = new Map(resolvers.map((ref, position) => [ref.token, position]))\n return ctx.arrow(\n arrowParams,\n (c, m, x) =>\n ctx.call(\n ctx.member(c, handler.method),\n params.map(param => argumentNode(ctx, param, m as GenNode, helpers, { x, index })),\n ),\n { async: params.some(param => param.kind === 'validated' || param.kind === 'custom') },\n )\n}\n\nfunction argumentNode(\n ctx: Context,\n param: HandlerParamData,\n m: GenNode,\n helpers: Helpers,\n resolvers: Resolvers,\n): GenNode {\n switch (param.kind) {\n case 'custom':\n return customArgument(ctx, param, m, helpers, resolvers)\n case 'payload':\n return ctx.code`${ctx.member(m, 'payload')} as never`\n case 'validated':\n return ctx.code`await ${ctx.call(helpers.validateMessage(), [ctx.importValue(param.schema), ctx.member(m, 'payload')])}`\n case 'headers':\n return ctx.member(m, 'headers')\n case 'header':\n return ctx.call(helpers.messageHeader(), [m, param.name])\n case 'message':\n return param.narrow ? ctx.code`${m} as ${helpers.inboundMessage()}<never>` : m\n case 'undefined':\n return ctx.lit(undefined)\n }\n}\n\n/**\n * A custom parameter (RFC 0010), awaited (the invoke is `async`):\n * `await (D.resolvers.messaging as ParamFunctionOf<typeof D, 'messaging'>)(m, data)` or\n * `await x[i].resolve(m, data)`, cast with `as never` when the value type could not be checked.\n */\nfunction customArgument(\n ctx: Context,\n param: Extract<HandlerParamData, { kind: 'custom' }>,\n m: GenNode,\n helpers: Helpers,\n resolvers: Resolvers,\n): GenNode {\n const data = param.data === undefined ? ctx.lit(undefined) : dataNode(ctx, param.data.value)\n let node: GenNode\n if (param.resolver === undefined) {\n const decorator = ctx.importValue(param.identity)\n const type = ctx.code`${helpers.paramFunctionOf()}<typeof ${decorator}, 'messaging'>`\n node = ctx.call(ctx.code`${ctx.member(decorator, 'resolvers', 'messaging')} as ${type}`, [m, data])\n } else {\n const position = resolvers.index.get(param.resolver.token) as number\n if (param.arity === undefined) {\n // a `resolve` the compiler cannot read (inherited from a mixin...): the instance is cast to a\n // method taking both arguments (method parameters are bivariant), the value with `as never`\n const instance = ctx.code`${resolvers.x as GenNode}[${position}] as { resolve(message: unknown, data: unknown): unknown }`\n return ctx.code`(await (${instance}).resolve(${m}, ${data})) as never`\n }\n // a `resolve(message)` that ignores the data gets no data argument (TypeScript checks the arity)\n const arity = Math.min(param.arity, 2)\n let args = ctx.code``\n if (arity === 1) args = m\n else if (arity === 2) args = ctx.code`${m}, ${data}`\n node = ctx.code`${resolvers.x as GenNode}[${position}].resolve(${args})`\n }\n return param.cast ? ctx.code`(await ${node}) as never` : ctx.code`await ${node}`\n}\n\n/** The data argument of a custom parameter: a literal (references imported) or a reference. */\nfunction dataNode(ctx: Context, value: StaticValue): GenNode {\n return isValueRef(value) ? ctx.ref(value as ValueRef) : ctx.lit(value as never)\n}\n\n/** `true` for a {@link ValueRef} (the only non-plain object a static value can hold). */\nfunction isValueRef(value: unknown): boolean {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false\n const prototype = Object.getPrototypeOf(value)\n return prototype !== Object.prototype && prototype !== null && (value as { kind?: unknown }).kind === 'ref'\n}\n\nfunction lazyHelpers(ctx: Context): Helpers {\n const cache = new Map<string, GenNode>()\n const get = (name: string, type: boolean): GenNode => {\n let node = cache.get(name)\n if (node === undefined) {\n node = ctx.importFrom(RUNTIME_MODULE, name, type ? { type: true } : {})\n cache.set(name, node)\n }\n return node\n }\n return {\n inboundMessage: () => get('InboundMessage', true),\n validateMessage: () => get('validateMessage', false),\n messageHeader: () => get('messageHeader', false),\n paramFunctionOf: () => {\n let node = cache.get('@znight/core#ParamFunctionOf')\n if (node === undefined) {\n node = ctx.importFrom('@znight/core', 'ParamFunctionOf', { type: true })\n cache.set('@znight/core#ParamFunctionOf', node)\n }\n return node\n },\n }\n}\n","/**\n * `validate` of the messaging extension: checks that need every consumer of the application.\n */\nimport type { ValidateContext } from '@znight/compiler'\nimport type { ConsumerData, MemberClassData, MessagingData } from './data.ts'\n\nimport { compareStrings, INVALID_CONSUMER, INVALID_DECORATOR } from './constants.ts'\n\n/** Cross-consumer checks: one consumer per queue, messaging decorators outside of consumers. */\nexport function validateMessaging(ctx: ValidateContext<MessagingData>): void {\n const consumers = ctx.stored\n .filter((data): data is ConsumerData => data.kind === 'consumer')\n .sort((a, b) => compareStrings(a.token, b.token))\n\n // a queue is consumed by a single @Consumer class (the plugin refuses to boot otherwise)\n const byQueue = new Map<string, ConsumerData>()\n for (const consumer of consumers) {\n if (consumer.queue === '') continue\n const first = byQueue.get(consumer.queue)\n if (first === undefined) {\n byQueue.set(consumer.queue, consumer)\n continue\n }\n ctx.report({\n code: INVALID_CONSUMER,\n severity: 'error',\n message: `${first.displayName} and ${consumer.displayName} both consume \"${consumer.queue}\"`,\n location: consumer.location,\n hints: [\n 'A queue is consumed by a single @Consumer class: merge the handlers, or route by type with @OnMessage(type)',\n ],\n related: [{ message: `${first.displayName} consumes \"${consumer.queue}\"`, location: first.location }],\n })\n }\n\n // @OnMessage / @OnError / @Retry on a class that is neither a consumer nor one of its base classes\n const bases = new Set(consumers.flatMap(consumer => consumer.chain))\n for (const data of ctx.stored) {\n if (data.kind !== 'members' || data.abstract || bases.has(data.identity)) continue\n reportNotAConsumer(data, ctx)\n }\n}\n\nfunction reportNotAConsumer(data: MemberClassData, ctx: ValidateContext<MessagingData>): void {\n for (const decorator of data.decorators) {\n ctx.report({\n code: INVALID_DECORATOR,\n severity: 'error',\n message: `@${decorator.name} has no effect: ${data.displayName} is not a @Consumer`,\n location: decorator.location,\n hints: [\n `Add @Consumer('queue') to ${data.displayName}, or extend it from a @Consumer class`,\n 'Base classes holding shared handlers should be abstract',\n ],\n })\n }\n}\n","/**\n * `@znight/messaging/compiler`: the compiler extension of `@znight/messaging` (spec §5, §6.5, §9.2).\n *\n * Loaded by `@znight/compiler` through the package manifest (`package.json#znight.compiler`). It reads\n * `@Consumer` classes and their `@OnMessage` / `@Retry` / `@OnError` methods and `@Message` /\n * `@Headers` / `@Ctx` parameters, registers consumers as providers, reports invalid consumers at build\n * time and generates `metadata.extensions.messaging`.\n *\n * This entry only `import type`s from `@znight/compiler` and never loads the messaging runtime.\n */\nimport type { CompilerExtension, DecoratorSpec } from '@znight/compiler'\nimport type { MessagingData } from './data.ts'\n\nimport { analyzeMessagingClass } from './analyze.ts'\nimport { EXTENSION_NAME, MessagingDecorator } from './constants.ts'\nimport { generateMessaging } from './generate.ts'\nimport { validateMessaging } from './validate.ts'\n\nexport type {\n ConsumerData,\n HandlerData,\n HandlerParamData,\n MemberClassData,\n MessagingData,\n RetryPolicyData,\n} from './data.ts'\n\n/**\n * Decorators owned by the extension. `static` arguments must be statically evaluable (queue names,\n * types, retry options, header names); the `@Message` schema is a `value` (an exported binding).\n */\nconst decorators: Readonly<Record<string, DecoratorSpec>> = Object.freeze({\n [MessagingDecorator.Consumer]: { targets: ['class'], params: ['static'] },\n [MessagingDecorator.OnMessage]: { targets: ['method'], params: ['static'] },\n [MessagingDecorator.Retry]: { targets: ['method'], params: ['static'] },\n [MessagingDecorator.OnError]: { targets: ['method'], params: [] },\n [MessagingDecorator.Message]: { targets: ['parameter'], params: ['value'] },\n [MessagingDecorator.Headers]: { targets: ['parameter'], params: ['static'] },\n [MessagingDecorator.Ctx]: { targets: ['parameter'], params: [] },\n} satisfies Record<string, DecoratorSpec>)\n\n/** The `@znight/messaging` compiler extension. */\nexport const messagingCompilerExtension: CompilerExtension<MessagingData> = Object.freeze({\n apiVersion: 1,\n name: EXTENSION_NAME,\n decorators,\n analyzeClass: analyzeMessagingClass,\n validate: validateMessaging,\n generate: generateMessaging,\n})\n\nexport default messagingCompilerExtension\n"],"mappings":"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"}
@@ -1,4 +1,10 @@
1
1
  import { CoreLogger } from "@znight/core";
2
+ declare module "@znight/core" {
3
+ /** Custom parameter decorators (`createParamDecorator`) resolve handler parameters from the {@link InboundMessage}. */
4
+ interface ParamContexts {
5
+ messaging: InboundMessage;
6
+ }
7
+ }
2
8
  /**
3
9
  * A message being handled by a consumer. It is the value of the request-scoped external
4
10
  * `@znight/messaging#InboundMessage` during a delivery (inject it into request-scoped providers, or
@@ -213,4 +219,4 @@ interface MessagingDriver {
213
219
  deadLetterName(queue: string): string;
214
220
  }
215
221
  export { DriverDelivery as a, SubscribeOptions as c, InboundMessage as d, OutboundMessage as f, DriverContext as i, Subscription as l, PublishResult as m, DeliveryHandler as n, MessagingDriver as o, PublishOptions as p, DriverCapabilities as r, RetryRequest as s, DeadLetterRequest as t, DeadLetterReason as u };
216
- //# sourceMappingURL=driver-ZxLqy_Ap.d.mts.map
222
+ //# sourceMappingURL=driver-Dv38b74F.d.mts.map
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as DriverDelivery, c as SubscribeOptions, d as InboundMessage, f as OutboundMessage, i as DriverContext, l as Subscription, m as PublishResult, n as DeliveryHandler, o as MessagingDriver, p as PublishOptions, r as DriverCapabilities, s as RetryRequest, t as DeadLetterRequest, u as DeadLetterReason } from "./driver-ZxLqy_Ap.mjs";
1
+ import { a as DriverDelivery, c as SubscribeOptions, d as InboundMessage, f as OutboundMessage, i as DriverContext, l as Subscription, m as PublishResult, n as DeliveryHandler, o as MessagingDriver, p as PublishOptions, r as DriverCapabilities, s as RetryRequest, t as DeadLetterRequest, u as DeadLetterReason } from "./driver-Dv38b74F.mjs";
2
2
  import { ClassMarker, CoreLogger, MessagePublishEvent, MethodMarker, ParameterMarker, Plugin, PluginOptions, Scope, Token, TypedToken, ZnightError } from "@znight/core";
3
3
  /** Backoff strategy between attempts. */
4
4
  type BackoffStrategy = "fixed" | "exponential";
@@ -76,12 +76,18 @@ interface MessageHandlerDefinition {
76
76
  readonly type?: string;
77
77
  /** `@Retry` policy, normalized. Default: the plugin's `defaults.retry`. */
78
78
  readonly retry?: RetryPolicy;
79
+ /**
80
+ * Provider classes resolving custom parameters (`ParamResolver`, RFC 0010), in order of first use:
81
+ * the runtime resolves them in the delivery scope and passes the instances to `invoke` (`x`).
82
+ * Absent when there is none.
83
+ */
84
+ readonly paramResolvers?: readonly Token[];
79
85
  /**
80
86
  * Calls the handler: extracts and validates the parameters from the message
81
87
  * (`@Message(schema)` → `validateMessage(schema, m.payload)`, `@Headers(name)` →
82
- * `messageHeader(m, name)`, `@Ctx()` → `m`).
88
+ * `messageHeader(m, name)`, `@Ctx()` → `m`, a custom parameter → its resolver, awaited).
83
89
  */
84
- readonly invoke: (consumer: any, message: InboundMessage) => unknown;
90
+ readonly invoke: (consumer: any, message: InboundMessage, resolvers?: any) => unknown;
85
91
  }
86
92
  declare module "@znight/core" {
87
93
  interface ZnightExtensionsMetadata {
package/dist/index.mjs CHANGED
@@ -287,7 +287,7 @@ function prepareConsumer(definition, container, driver, defaults) {
287
287
  let maxAttempts = 1;
288
288
  const nativeDelays = /* @__PURE__ */ new Set();
289
289
  for (const handlerDefinition of handlers) {
290
- const handler = prepareHandler(handlerDefinition, name, driver, defaults.retry);
290
+ const handler = prepareHandler(handlerDefinition, name, driver, defaults.retry, container);
291
291
  maxAttempts = Math.max(maxAttempts, handler.policy.attempts);
292
292
  for (const delay of retryDelays(handler.policy)) if (!isInProcessDelay(delay, driver.capabilities)) nativeDelays.add(delay);
293
293
  const type = handlerDefinition.type;
@@ -332,7 +332,7 @@ function prepareConsumer(definition, container, driver, defaults) {
332
332
  }
333
333
  };
334
334
  }
335
- function prepareHandler(definition, consumer, driver, defaultPolicy) {
335
+ function prepareHandler(definition, consumer, driver, defaultPolicy, container) {
336
336
  if (definition === null || typeof definition !== "object" || typeof definition.method !== "string" || definition.method === "") throw consumerError(`@Consumer ${consumer}: invalid @OnMessage handler definition`);
337
337
  const where = `${consumer}.${definition.method}()`;
338
338
  if (typeof definition.invoke !== "function") throw consumerError(`${where}: the handler has no invoker`, ["Regenerate the metadata"]);
@@ -341,10 +341,19 @@ function prepareHandler(definition, consumer, driver, defaultPolicy) {
341
341
  assertRetrySupported(policy, driver.capabilities, driver.name, definition.retry === void 0 ? `${where} (default retry policy)` : `@Retry on ${where}`);
342
342
  return {
343
343
  definition,
344
+ invoke: handlerInvoke(definition, container, where),
344
345
  method: definition.method,
345
346
  policy
346
347
  };
347
348
  }
349
+ /** The generated invoke, or a function passing the parameter resolver instances (resolved per delivery). */
350
+ function handlerInvoke(definition, container, where) {
351
+ const invoke = definition.invoke;
352
+ const tokens = definition.paramResolvers;
353
+ if (tokens === void 0 || tokens.length === 0) return invoke;
354
+ for (const token of tokens) if (!container.has(token)) throw consumerError(`${where}: the parameter resolver ${token} is not a provider`, ["Regenerate the metadata"]);
355
+ return (consumer, message) => invoke(consumer, message, tokens.map((token) => container.get(token)));
356
+ }
348
357
  function duplicateType(consumer, type) {
349
358
  return consumerError(`@Consumer ${consumer}: several @OnMessage handlers for type "${type}"`);
350
359
  }
@@ -531,7 +540,7 @@ var ConsumerRuntime = class {
531
540
  if (message.attempt > message.maxAttempts) return this.#terminal(context, new AttemptsExhaustedError(message.attempt, message.maxAttempts), "max-attempts", false);
532
541
  try {
533
542
  const instance = this.#services.container.get(this.consumer.token);
534
- await handler.definition.invoke(instance, message);
543
+ await handler.invoke(instance, message);
535
544
  } catch (error) {
536
545
  return this.#failure(context, error, true);
537
546
  }