UNPKG

@polkadot/typegen

Version:
218 lines (217 loc) • 9.59 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateDefaultLookup = generateDefaultLookup; exports.ignoreUnusedLookups = ignoreUnusedLookups; const tslib_1 = require("tslib"); const handlebars_1 = tslib_1.__importDefault(require("handlebars")); const node_path_1 = tslib_1.__importDefault(require("node:path")); const defaultDefinitions = tslib_1.__importStar(require("@polkadot/types/interfaces/definitions")); const asset_hub_kusama_hex_1 = tslib_1.__importDefault(require("@polkadot/types-support/metadata/v15/asset-hub-kusama-hex")); const asset_hub_polkadot_hex_1 = tslib_1.__importDefault(require("@polkadot/types-support/metadata/v15/asset-hub-polkadot-hex")); const kusama_hex_1 = tslib_1.__importDefault(require("@polkadot/types-support/metadata/v15/kusama-hex")); const polkadot_hex_1 = tslib_1.__importDefault(require("@polkadot/types-support/metadata/v15/polkadot-hex")); const substrate_hex_1 = tslib_1.__importDefault(require("@polkadot/types-support/metadata/v15/substrate-hex")); const util_1 = require("@polkadot/util"); const index_js_1 = require("../util/index.js"); const tsDef_js_1 = require("./tsDef.js"); const WITH_TYPEDEF = false; const generateLookupDefsTmpl = handlebars_1.default.compile((0, index_js_1.readTemplate)('lookup/defs')); const generateLookupDefsNamedTmpl = handlebars_1.default.compile((0, index_js_1.readTemplate)('lookup/defs-named')); const generateLookupIndexTmpl = handlebars_1.default.compile((0, index_js_1.readTemplate)('lookup/index')); const generateLookupTypesTmpl = handlebars_1.default.compile((0, index_js_1.readTemplate)('lookup/types')); const generateRegistryTmpl = handlebars_1.default.compile((0, index_js_1.readTemplate)('interfaceRegistry')); function generateParamType(registry, { name, type }) { if (type.isSome) { const link = registry.lookup.types[type.unwrap().toNumber()]; if (link.type.path.length) { return generateTypeDocs(registry, null, link.type.path, link.type.params); } } return name.toString(); } function generateTypeDocs(registry, id, path, params) { return `${id ? `${registry.createLookupType(id)}${path.length ? ': ' : ''}` : ''}${path.map((p) => p.toString()).join('::')}${params.length ? `<${params.map((p) => generateParamType(registry, p)).join(', ')}>` : ''}`; } function formatObject(lines) { const max = lines.length - 1; return [ '{', ...lines.map((l, index) => (l.endsWith(',') || l.endsWith('{') || index === max || lines[index + 1].endsWith('}') || lines[index + 1].endsWith('}')) ? l : `${l},`), '}' ]; } function expandSet(parsed) { return formatObject(Object.entries(parsed).reduce((all, [k, v]) => { all.push(`${k}: ${v}`); return all; }, [])); } function expandObject(parsed) { if (parsed._set) { return expandSet(parsed._set); } return formatObject(Object.entries(parsed).reduce((all, [k, v]) => { const inner = (0, util_1.isString)(v) ? expandType(v) : Array.isArray(v) ? [`[${v.map((e) => `'${e}'`).join(', ')}]`] : expandObject(v); inner.forEach((l, index) => { all.push(`${index === 0 ? `${k}: ${l}` : `${l}`}`); }); return all; }, [])); } function expandType(encoded) { if (!encoded.startsWith('{')) { return [`'${encoded}'`]; } return expandObject(JSON.parse(encoded)); } function expandDefToString({ lookupNameRoot, type }, indent) { if (lookupNameRoot) { return `'${lookupNameRoot}'`; } const lines = expandType(type); let inc = 0; return lines.map((l, index) => { let r; if (l.endsWith('{')) { r = index === 0 ? l : `${' '.padStart(indent + inc)}${l}`; inc += 2; } else { if (l.endsWith('},') || l.endsWith('}')) { inc -= 2; } r = index === 0 ? l : `${' '.padStart(indent + inc)}${l}`; } return r; }).join('\n'); } function getFilteredTypes(lookup, exclude = []) { const named = lookup.types.filter(({ id }) => !!lookup.getTypeDef(id).lookupName); const names = named.map(({ id }) => lookup.getName(id)); return named .filter((_, index) => !names.some((n, iindex) => index > iindex && n === names[index])) .map((p) => [p, lookup.getTypeDef(p.id)]) .filter(([, typeDef]) => !exclude.includes(typeDef.lookupName || '<invalid>')); } function generateLookupDefs(registry, filtered, destDir, subPath) { (0, index_js_1.writeFile)(node_path_1.default.join(destDir, `${subPath || 'definitions'}.ts`), () => { const all = filtered.map(([{ id, type: { params, path } }, typeDef]) => { const typeLookup = registry.createLookupType(id); const def = expandDefToString(typeDef, subPath ? 2 : 4); return { docs: [ generateTypeDocs(registry, id, path, params), WITH_TYPEDEF ? `@typeDef ${(0, util_1.stringify)(typeDef)}` : null ].filter((d) => !!d), type: { def, typeLookup, typeName: typeDef.lookupName } }; }); const max = all.length - 1; return (subPath ? generateLookupDefsNamedTmpl : generateLookupDefsTmpl)({ defs: all.map(({ docs, type }, i) => { const { def, typeLookup, typeName } = type; return { defs: [ [typeName || typeLookup, `${def}${i !== max ? ',' : ''}`] ].map(([n, t]) => `${n}: ${t}`), docs }; }), headerType: 'defs' }); }); } function generateLookupTypes(registry, filtered, destDir, subPath) { const imports = { ...(0, index_js_1.createImports)({ '@polkadot/types/interfaces': defaultDefinitions }, { types: {} }), interfaces: [] }; const items = filtered .map(([, typeDef]) => { typeDef.name = typeDef.lookupName; return typeDef.lookupNameRoot && typeDef.lookupName ? (0, index_js_1.exportInterface)(typeDef.lookupIndex, typeDef.lookupName, typeDef.lookupNameRoot) : tsDef_js_1.typeEncoders[typeDef.info](registry, imports.definitions, typeDef, imports); }) .filter((t) => !!t) .map((t) => t.replace(/\nexport /, '\n')); (0, index_js_1.writeFile)(node_path_1.default.join(destDir, `types${subPath ? `-${subPath}` : ''}.ts`), () => generateLookupTypesTmpl({ headerType: 'defs', imports, items: items.map((l) => l .split('\n') .map((l) => l.length ? ` ${l}` : '') .join('\n')), types: [ ...Object.keys(imports.localTypes).sort().map((packagePath) => ({ file: packagePath, types: Object.keys(imports.localTypes[packagePath]) })) ] }), true); (0, index_js_1.writeFile)(node_path_1.default.join(destDir, 'index.ts'), () => generateLookupIndexTmpl({ headerType: 'defs' }), true); } function generateRegistry(_registry, filtered, destDir, subPath) { (0, index_js_1.writeFile)(node_path_1.default.join(destDir, `${subPath}.ts`), () => { const items = filtered .map(([, { lookupName }]) => lookupName) .filter((n) => !!n) .sort() .reduce((all, n) => all.includes(n) ? all : all.concat(n), []); const imports = (0, index_js_1.createImports)({}, { types: {} }); imports.lookupTypes = items.reduce((all, n) => ({ ...all, [n]: true }), {}); return generateRegistryTmpl({ headerType: 'defs', imports, items, types: [] }); }, true); } function generateLookup(destDir, entries) { entries.reduce((exclude, [subPath, staticMeta]) => { const { lookup, registry } = (0, index_js_1.initMeta)(staticMeta).metadata.asLatest; const filtered = getFilteredTypes(lookup, exclude); generateLookupDefs(registry, filtered, destDir, subPath); generateLookupTypes(registry, filtered, destDir, subPath); generateRegistry(registry, filtered, destDir, subPath === 'lookup' ? 'registry' : `../registry/${subPath}`); return exclude.concat(...filtered .map(([, typeDef]) => typeDef.lookupName) .filter((n) => !!n)); }, []); } function generateDefaultLookup(destDir = 'packages/types-augment/src/lookup', staticData) { generateLookup(destDir, staticData ? [['lookup', staticData]] : [ ['substrate', substrate_hex_1.default], ['polkadot', polkadot_hex_1.default], ['kusama', kusama_hex_1.default], ['assetHubPolkadot', asset_hub_polkadot_hex_1.default], ['assetHubKusama', asset_hub_kusama_hex_1.default] ]); } function ignoreUnusedLookups(usedTypes, imports) { const usedStringified = usedTypes.toString(); const [lookupKey, typeDefinitions] = Object.entries(imports.localTypes).find(([typeModule, _]) => typeModule.includes('/lookup')) || ['', {}]; Object.keys(typeDefinitions).forEach((typeDef) => { if (!(usedStringified.includes(typeDef))) { delete (imports.localTypes[lookupKey])[typeDef]; } }); }