@codama/validators
Version:
Validator visitors for the Codama framework
1 lines • 23 kB
Source Map (JSON)
{"version":3,"sources":["../src/ValidationItem.ts","../src/getValidationItemsVisitor.ts","../src/throwValidatorItemsVisitor.ts"],"names":["LinkableDictionary","NodeStack","pipe","mergeVisitor","recordLinkablesOnFirstVisitVisitor","recordNodeStackVisitor","extendVisitor","getResolvedInstructionInputsVisitor","visit","getAllInstructionArguments","camelCase","isNode","mapVisitor","CodamaError","CODAMA_ERROR__VISITORS__FAILED_TO_VALIDATE_NODE"],"mappings":"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","file":"index.node.cjs","sourcesContent":["import { Node } from '@codama/nodes';\nimport { NodePath, NodeStack } from '@codama/visitors-core';\n\nexport const LOG_LEVELS = ['debug', 'trace', 'info', 'warn', 'error'] as const;\nexport type LogLevel = (typeof LOG_LEVELS)[number];\n\nexport type ValidationItem = {\n level: LogLevel;\n message: string;\n node: Node;\n path: NodePath;\n};\n\nexport function validationItem(\n level: LogLevel,\n message: string,\n node: Node,\n path: NodePath | NodeStack,\n): ValidationItem {\n return {\n level,\n message,\n node,\n path: Array.isArray(path) ? path : (path as NodeStack).getPath(),\n };\n}\n\nexport const getLevelIndex = (level: LogLevel): number => LOG_LEVELS.indexOf(level);\n","import { camelCase, getAllInstructionArguments, isNode } from '@codama/nodes';\nimport {\n extendVisitor,\n getResolvedInstructionInputsVisitor,\n LinkableDictionary,\n mergeVisitor,\n NodeStack,\n pipe,\n recordLinkablesOnFirstVisitVisitor,\n recordNodeStackVisitor,\n visit,\n Visitor,\n} from '@codama/visitors-core';\n\nimport { ValidationItem, validationItem } from './ValidationItem';\n\nexport function getValidationItemsVisitor(): Visitor<readonly ValidationItem[]> {\n const linkables = new LinkableDictionary();\n const stack = new NodeStack();\n\n return pipe(\n mergeVisitor(\n () => [] as readonly ValidationItem[],\n (_, items) => items.flat(),\n ),\n v => recordLinkablesOnFirstVisitVisitor(v, linkables),\n v => recordNodeStackVisitor(v, stack),\n v =>\n extendVisitor(v, {\n visitAccount(node, { next }) {\n const items = [] as ValidationItem[];\n if (!node.name) {\n items.push(validationItem('error', 'Account has no name.', node, stack));\n }\n return [...items, ...next(node)];\n },\n\n visitDefinedType(node, { next }) {\n const items = [] as ValidationItem[];\n if (!node.name) {\n items.push(validationItem('error', 'Defined type has no name.', node, stack));\n }\n return [...items, ...next(node)];\n },\n\n visitDefinedTypeLink(node, { next }) {\n const items = [] as ValidationItem[];\n if (!node.name) {\n items.push(validationItem('error', 'Pointing to a defined type with no name.', node, stack));\n } else if (!linkables.has(stack.getPath(node.kind))) {\n items.push(\n validationItem(\n 'error',\n `Pointing to a missing defined type named \"${node.name}\"`,\n node,\n stack,\n ),\n );\n }\n return [...items, ...next(node)];\n },\n\n visitEnumEmptyVariantType(node, { next }) {\n const items = [] as ValidationItem[];\n if (!node.name) {\n items.push(validationItem('error', 'Enum variant has no name.', node, stack));\n }\n return [...items, ...next(node)];\n },\n\n visitEnumStructVariantType(node, { next }) {\n const items = [] as ValidationItem[];\n if (!node.name) {\n items.push(validationItem('error', 'Enum variant has no name.', node, stack));\n }\n return [...items, ...next(node)];\n },\n\n visitEnumTupleVariantType(node, { next }) {\n const items = [] as ValidationItem[];\n if (!node.name) {\n items.push(validationItem('error', 'Enum variant has no name.', node, stack));\n }\n return [...items, ...next(node)];\n },\n\n visitEnumType(node, { next }) {\n const items = [] as ValidationItem[];\n if (node.variants.length === 0) {\n items.push(validationItem('warn', 'Enum has no variants.', node, stack));\n }\n node.variants.forEach(variant => {\n if (!variant.name) {\n items.push(validationItem('error', 'Enum variant has no name.', node, stack));\n }\n });\n return [...items, ...next(node)];\n },\n\n visitError(node, { next }) {\n const items = [] as ValidationItem[];\n if (!node.name) {\n items.push(validationItem('error', 'Error has no name.', node, stack));\n }\n if (typeof node.code !== 'number') {\n items.push(validationItem('error', 'Error has no code.', node, stack));\n }\n if (!node.message) {\n items.push(validationItem('warn', 'Error has no message.', node, stack));\n }\n return [...items, ...next(node)];\n },\n\n visitInstruction(node, { next }) {\n const items = [] as ValidationItem[];\n if (!node.name) {\n items.push(validationItem('error', 'Instruction has no name.', node, stack));\n }\n\n // Check for duplicate account names.\n const accountNameHistogram = new Map<string, number>();\n node.accounts.forEach(account => {\n if (!account.name) {\n items.push(validationItem('error', 'Instruction account has no name.', node, stack));\n return;\n }\n const count = (accountNameHistogram.get(account.name) ?? 0) + 1;\n accountNameHistogram.set(account.name, count);\n // Only throw an error once per duplicated names.\n if (count === 2) {\n items.push(\n validationItem(\n 'error',\n `Account name \"${account.name}\" is not unique in instruction \"${node.name}\".`,\n node,\n stack,\n ),\n );\n }\n });\n\n // Check for cyclic dependencies in account defaults.\n const cyclicCheckVisitor = getResolvedInstructionInputsVisitor();\n try {\n visit(node, cyclicCheckVisitor);\n } catch (error) {\n items.push(validationItem('error', (error as Error).message, node, stack));\n }\n\n // Check args.\n const names = getAllInstructionArguments(node).map(({ name }) => camelCase(name));\n const duplicates = names.filter((e, i, a) => a.indexOf(e) !== i);\n const uniqueDuplicates = [...new Set(duplicates)];\n const hasConflictingNames = uniqueDuplicates.length > 0;\n if (hasConflictingNames) {\n items.push(\n validationItem(\n 'error',\n `The names of the following instruction arguments are conflicting: ` +\n `[${uniqueDuplicates.join(', ')}].`,\n node,\n stack,\n ),\n );\n }\n\n // Check arg defaults.\n getAllInstructionArguments(node).forEach(argument => {\n const { defaultValue } = argument;\n if (isNode(defaultValue, 'accountBumpValueNode')) {\n const defaultAccount = node.accounts.find(account => account.name === defaultValue.name);\n if (defaultAccount && defaultAccount.isSigner !== false) {\n items.push(\n validationItem(\n 'error',\n `Argument ${argument.name} cannot default to the bump attribute of ` +\n `the [${defaultValue.name}] account as it may be a Signer.`,\n node,\n stack,\n ),\n );\n }\n }\n });\n\n return [...items, ...next(node)];\n },\n\n visitProgram(node, { next }) {\n const items = [] as ValidationItem[];\n if (!node.name) {\n items.push(validationItem('error', 'Program has no name.', node, stack));\n }\n if (!node.publicKey) {\n items.push(validationItem('error', 'Program has no public key.', node, stack));\n }\n if (!node.version) {\n items.push(validationItem('warn', 'Program has no version.', node, stack));\n }\n if (!node.origin) {\n items.push(validationItem('info', 'Program has no origin.', node, stack));\n }\n return [...items, ...next(node)];\n },\n\n visitStructFieldType(node, { next }) {\n const items = [] as ValidationItem[];\n if (!node.name) {\n items.push(validationItem('error', 'Struct field has no name.', node, stack));\n }\n return [...items, ...next(node)];\n },\n\n visitStructType(node, { next }) {\n const items = [] as ValidationItem[];\n\n // Check for duplicate field names.\n const fieldNameHistogram = new Map<string, number>();\n node.fields.forEach(field => {\n if (!field.name) return; // Handled by TypeStructField\n const count = (fieldNameHistogram.get(field.name) ?? 0) + 1;\n fieldNameHistogram.set(field.name, count);\n // Only throw an error once per duplicated names.\n if (count === 2) {\n items.push(\n validationItem(\n 'error',\n `Struct field name \"${field.name}\" is not unique.`,\n field,\n stack,\n ),\n );\n }\n });\n return [...items, ...next(node)];\n },\n\n visitTupleType(node, { next }) {\n const items = [] as ValidationItem[];\n if (node.items.length === 0) {\n items.push(validationItem('warn', 'Tuple has no items.', node, stack));\n }\n return [...items, ...next(node)];\n },\n }),\n );\n}\n","import { CODAMA_ERROR__VISITORS__FAILED_TO_VALIDATE_NODE, CodamaError } from '@codama/errors';\nimport { NodeKind } from '@codama/nodes';\nimport { mapVisitor, Visitor } from '@codama/visitors-core';\n\nimport { getLevelIndex, LogLevel, ValidationItem } from './ValidationItem';\n\nexport function throwValidatorItemsVisitor<TNodeKind extends NodeKind = NodeKind>(\n visitor: Visitor<readonly ValidationItem[], TNodeKind>,\n throwLevel: LogLevel = 'error',\n): Visitor<void, TNodeKind> {\n return mapVisitor(visitor, validationItems => {\n const levelHistogram = [...validationItems]\n .sort((a, b) => getLevelIndex(b.level) - getLevelIndex(a.level))\n .reduce(\n (acc, item) => {\n acc[item.level] = (acc[item.level] ?? 0) + 1;\n return acc;\n },\n {} as Record<LogLevel, number>,\n );\n const maxLevel = Object.keys(levelHistogram)\n .map(level => getLevelIndex(level as LogLevel))\n .sort((a, b) => b - a)[0];\n\n if (maxLevel >= getLevelIndex(throwLevel)) {\n const formattedHistogram = Object.keys(levelHistogram)\n .map(level => `${level}s: ${levelHistogram[level as LogLevel]}`)\n .join(', ');\n throw new CodamaError(CODAMA_ERROR__VISITORS__FAILED_TO_VALIDATE_NODE, {\n formattedHistogram,\n validationItems,\n });\n }\n });\n}\n"]}