UNPKG

@graphprotocol/graph-cli

Version:

CLI for building for and deploying to The Graph

85 lines (81 loc) 3.22 kB
import * as util from '../codegen/util.js'; /** * Map of value types that need to be changetype'd to their corresponding AssemblyScript type */ export const VALUE_TYPECAST_MAP = { 'address[]': 'Bytes[]', 'tuple[]': 'Bytes[]', }; export const generateFieldAssignment = (key, value, type) => { let rightSide = `event.params.${value.join('.')}`; const imports = []; if (type in VALUE_TYPECAST_MAP) { const castTo = VALUE_TYPECAST_MAP[type]; rightSide = `changetype<${castTo}>(${rightSide})`; imports.push(castTo.replace('[]', '')); } return { assignment: `entity.${key.join('_')} = ${rightSide}`, imports, }; }; export const generateFieldAssignments = ({ index, input, }) => { const fields = input.type === 'tuple' ? util .unrollTuple({ value: input, index, path: [input.name || `param${index}`] }) .map(({ path, type }) => generateFieldAssignment(path, path, type)) : [ generateFieldAssignment([(input.mappedName ?? input.name) || `param${index}`], [input.name || `param${index}`], input.type), ]; return { assignments: fields.map(a => a.assignment), imports: fields.map(a => a.imports).flat(), }; }; /** * Map of input names that are reserved so we do not use them as field names to avoid conflicts * see https://github.com/graphprotocol/graph-tooling/issues/710 * name => mappedName */ const NAMES_REMAP_DICTIONARY = { id: 'internal_id', _id: 'internal__id', }; export const renameNameIfNeeded = (name) => { return NAMES_REMAP_DICTIONARY[name] ?? name; }; export const generateEventFieldAssignments = (event, _contractName) => event.inputs.reduce((acc, input, index) => { input.mappedName = renameNameIfNeeded(input.name); const { assignments, imports } = generateFieldAssignments({ input, index }); return { assignments: acc.assignments.concat(assignments), imports: acc.imports.concat(imports), }; }, { assignments: [], imports: [] }); export const generateEventIndexingHandlers = (events, contractName) => { const eventFieldAssignments = events.map(event => ({ event, ...generateEventFieldAssignments(event, contractName), })); const allImports = [...new Set(eventFieldAssignments.map(({ imports }) => imports).flat())]; const eventHandlers = eventFieldAssignments.map(({ event, assignments }) => { return ` export function handle${event._alias}(event: ${event._alias}Event): void { let entity = new ${event._alias}(event.transaction.hash.concatI32(event.logIndex.toI32())) ${assignments.join('\n')} entity.blockNumber = event.block.number entity.blockTimestamp = event.block.timestamp entity.transactionHash = event.transaction.hash entity.save() } `; }); return ` import { ${events.map(event => `${event._alias} as ${event._alias}Event`)}} from '../generated/${contractName}/${contractName}' import { ${events.map(event => event._alias)} } from '../generated/schema' ${allImports.length > 0 ? `import { ${allImports.join(', ')} } from '@graphprotocol/graph-ts'` : ''} ${eventHandlers.join('\n')} `; };