news 2026/10/1 2:36:35

SubQuery @subql/utils 工具库能力全景:从 CHANGELOG 解读其 GraphQL 指令、日志与类型系统的演进

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SubQuery @subql/utils 工具库能力全景:从 CHANGELOG 解读其 GraphQL 指令、日志与类型系统的演进
  • 区块链
  • 后端

【免费下载链接】subql

SubQuery is an Open, Flexible, Fast and Universal data indexing framework for web3. Our mission is to help developers create the decentralised products of the future.

项目地址:https://gitcode.com/gh_mirrors/su/subql
点击查看免费下载

@subql/utils是 SubQuery 数据索引框架中面向 schema 解析、日志、类型哈希与通用工具的核心基础包,被packages/cli、packages/node-core、packages/query等多个上层模块共同依赖。本文以 packages/utils/CHANGELOG.md 的版本演进为主线,结合仓库源码逐项还原其 GraphQL 自定义指令、Logger 过滤机制、可哈希类型系统与 hex/base58 等工具函数的真实实现,帮助读者在升级版本时快速定位能力变化,并理解这些工具在 SubQuery 数据模型与索引流水线中的具体作用。

包定位与导出结构

@subql/utils当前版本为 2.22.1(见 packages/utils/package.json),其对外导出入口 packages/utils/src/index.ts 只做五件事:

export * from './graphql'; // GraphQL schema 解析、指令与查询构造 export {levelFilter, Logger, LoggerOption} from './logger'; // 日志 export * from './query'; // 元数据表名与 MetaData 类型 export * from './types'; // 可哈希类型系统 TypeClass export * from './buffer'; // hex/u8a/base58/base64 工具 export * from './networking'; // findAvailablePort

这五个模块恰好对应 CHANGELOG 中历次功能性变更的主线:GraphQL 指令(@jsonField、@fullText、@dbType、@compositeIndexes)、Logger 过滤与错误格式化、类型 hashCode 与 Sequelize 映射、元数据命名哈希,以及端口探测。下面按能力域逐一展开。

GraphQL 指令体系:schema.graphql 的数据建模基础

SubQuery 项目的schema.graphql是数据模型的定义入口,@subql/utils负责把它解析成可供 codegen 使用的结构化模型。所有支持的指令在 packages/utils/src/graphql/schema/directives.ts 中统一定义:

directive @derivedFrom(field: String!) on FIELD_DEFINITION directive @entity on OBJECT directive @jsonField(indexed: Boolean) on OBJECT directive @index(unique: Boolean) on FIELD_DEFINITION directive @compositeIndexes(fields: [[String]]!) on OBJECT directive @fullText(fields: [String!], language: String) on OBJECT directive @dbType(type: String!) on FIELD_DEFINITION

而基础标量(BigInt、BigDecimal、Date、Bytes、Float)在 packages/utils/src/graphql/schema/scalas.ts 中声明,最终通过 packages/utils/src/graphql/schema.ts 的buildSchemaFromString/buildSchemaFromDocumentNode将用户 schema 与基础 schema 合并。

核心解析逻辑集中在 packages/utils/src/graphql/entities.ts 的getAllEntitiesRelations(),它会遍历 schema 中所有@entity类型,产出{models, relations, enums}三件套,类型定义见 packages/utils/src/graphql/types.ts。CHANGELOG 中若干关键条目都能在这里找到对应的实现证据:

  • @dbType指令(2.17.0 新增,2.17.1 修复关系解析):entities.ts中getDirectives(schema, ['derivedFrom', 'index', 'dbType'])读取该指令,允许把实体id字段映射为BigInt/Float/ID/Int/String白名单之一(代码中有显式allowedTypes校验),并且在外键关联时会把关联实体 id 的实际 db 类型同步到外键字段;非法类型会抛出带可用类型清单的错误信息(2.17.2 中"Update error message to include allowed dbType types"即指此处)。
  • @fullText指令(2.8.0 新增):在entities.ts尾部从实体收集fullText配置,要求至少一个字段、只支持String/ID类型,并对关系字段自动改写为xxx_id。对应的类型定义GraphQLFullTextType位于 packages/utils/src/graphql/types.ts。
  • @compositeIndexes(2.4.0 新增):支持在实体上声明复合索引,实现里会先经 packages/utils/src/array/array.ts 的findDuplicateStringArray检测重复索引,再通过getJoinIndexFields把外键字段自动补上Id后缀,且限制单条复合索引 1~3 个字段。
  • @jsonField的indexed参数(1.5.0 新增):Json 类型字段默认自动追加 GIN 索引(向后兼容),只有显式声明indexed: false才跳过,见entities.ts中DirectiveName.JsonField的分支处理。
  • 枚举索引(2.15.0):@index指令现在允许作用于枚举字段;而枚举本身被统一收集进enums输出供 codegen 使用。

此外graphql.spec.ts(packages/utils/src/graphql/graphql.spec.ts)提供了一整套验证:@entity标注、实体字段提取、不支持类型的报错(如Double)、Bytes/Float支持、union/interface 拒绝等,可作为指令行为的可执行参考。

Logger:分级过滤、子日志调试与错误格式化

日志模块是@subql/utils中被 CLI、node 与 query 服务广泛复用的能力,其核心类Logger位于 packages/utils/src/logger/logger.ts,构造选项LoggerOption包含:

export interface LoggerOption { level?: string; // 默认 'info' filepath?: string; // 输出到文件 rotate?: boolean; // 日志轮转 nestedKey?: string; outputFormat?: 'json' | 'colored'; // 默认彩色输出 debugFilter?: string[]; // 针对子 logger 的调试过滤 }

CHANGELOG 中与 Logger 相关的演进都可以在源码中印证:

  • 负向过滤(2.5.0):debugFilter支持以-前缀排除指定类别的调试日志,例如--debug="*,-SQL"表示全局开 debug 但关掉 SQL 类。实现在applyChildDebug():命中-${category}时把该子 logger 级别重置为全局级别与info中的较高者,并输出Debug logging is disabled for ...提示。
  • 子 logger 调试级别(2.4.4):通过debugFilter指定类别名即可单独开启debug;*通配符则全局开启(但不打印通配符本身的日志以免刷屏)。setDebugFilter/setLevel会在运行期动态应用到所有已创建的子 logger。
  • 错误日志带 cause 与实例名(2.13.0、2.11.0):formatErrorString会输出错误构造函数名、消息、可选 Stack,并递归展开err.cause;JSON 输出模式(formatErrorJson)则输出结构化{type, name, message, stack, cause}。
  • worker 日志的 debug 兼容(2.9.2):applyChildDebug中isMainThread判断会去掉子线程 category 的-#${threadId}后缀,确保 worker 日志调试过滤与主线程一致。
  • 等级体系(2.5.0 之前已有):级别定义在 packages/utils/src/logger/constants.ts,trace/debug/info/warn/error/fatal/silent分别映射 10~999;levelFilter(test, target)(packages/utils/src/logger/util.ts)用于判断某级别是否达到阈值。
  • 颜色输出(2.11.0 的"improve colors"):packages/utils/src/logger/colors.ts 用 chalk 为各级别上色(FATAL 红底、ERROR 红、WARN 黄、INFO 绿、DEBUG 蓝、TRACE 灰),时间戳<category>与消息分别以品红和青色区分。

若指定filepath,Logger 会通过rotating-file-stream写文件,rotate开启时按1d间隔、最多 7 个文件、单文件 1G 上限轮转——这些常量定义在logger.ts的rotateOptions中。

类型系统与哈希:TypeClass、支持类型与 Json 哈希修复

packages/utils的types模块为 SubQuery 的实体字段提供"图类型 ↔ TypeScript 类型 ↔ Sequelize 类型"的映射,并承担 POI/去重所需的哈希职责。核心抽象是 packages/utils/src/types/TypeClass.ts:

export class TypeClass<T extends string, D> { constructor( public name: T, private _hashCode: (data: D) => Uint8Array, private _tsType?: string, private _fieldScalar?: string, private _sequelizeType?: SequelizeTypes ) {} hashCode(data: D): Uint8Array { ... } }

getTypeByScalarName()(packages/utils/src/types/generalTypes.ts)按名称找到对应的TypeClass。CHANGELOG 中几个 hash 相关的修复在此有明确落点:

  • Int 负值哈希(2.7.1):@polkadot/util的numberToU8a不支持负数,packages/utils/src/types/u8aUtils.ts 提供wrappedNumToU8a,负数时拼接[0]前缀与绝对值编码;Int的 hashCode 走此包装(见 packages/utils/src/types/supported/Int.ts)。
  • Json 键排序哈希(2.13.1):为消除 JSON 对象键顺序不同导致的哈希不一致,packages/utils/src/types/supported/Json.ts 在sortJsonObjectProperties中递归排序对象键(数组元素也逐个排序),随后JSON.stringify后编码,最终映射为DataTypes.JSONB。
  • 其他支持类型:BigInt(bn.js 转 buffer、numeric)、Bytes(hex 转 u8a、BLOB)、Date(时间戳、timestamp)、Boolean、Float、ID、String均在 packages/utils/src/types/supported/ 下逐个定义,与 packages/utils/src/graphql/types.ts 中的FieldScalar一一对应。

编码与 hex 工具:对齐 ethers 与 polkadot

buffer模块(packages/utils/src/buffer/buffer.ts)集中 re-export 了@polkadot/util与@polkadot/util-crypto的常用函数(u8aToHex、hexToU8a、numberToHex、blake2AsHex、base58Decode等),CHANGELOG 对应的动作包括:

  • 暴露 polkadot 全套 util(2.1.0):直接打通@polkadot/utils与@polkadot/utils-crypto,上层(如 CLI 与 node)无需再直接依赖 polkadot 工具即可完成 hex/u8a/base58/base64 操作。
  • hexStripZeros(2.9.0):为与 ethers 的 hex 表示对齐,本地实现了去掉前导零的函数(0x0001→0x1,全零则返回0x0),并在非 hex 输入时抛错;同一版本还正式导出numberToHex。
  • base58/base64(2.3.0、2.4.0):base58Decode/isBase58与 base64 相关函数在此暴露,服务于地址类数据的编解码。

元数据命名与_global表正则

query模块(packages/utils/src/query/metadata.ts)承担元数据表命名与健康信息类型:

export const METADATA_REGEX = /^_metadata$/; export const MULTI_METADATA_REGEX = /^_metadata_[a-zA-Z0-9-]+$/; export const MULTI_GLOBAL_REGEX = /^_[global|Global]$/; export function getMetadataTableName(chainId: string): string { ... } // blake2 哈希后截断 63 字符 export function hashName(schema, type, tableName): string { ... } // 函数/触发器/通道命名防超长

CHANGELOG 中的_global正则修复(2.19.0 增加、2.20.1 修复)正是针对MULTI_GLOBAL_REGEX的演进;同时hashName/getMetadataTableName用blake2AsHex(..., 64).substring(0, 63)规避 PostgreSQL 标识符 63 字节上限。配套的MetaData类型(packages/utils/src/query/types.ts)包含lastProcessedHeight、targetHeight、genesisHash、rowCountEstimate、deployments、historicalStateEnabled等索引器/查询节点健康与进度字段;其中rowCountEstimate与startHeight字段的增补分别对应 2.4.2、1.4.0 的变更。

端口探测工具

networking.ts(packages/utils/src/networking.ts)提供findAvailablePort(startPort, range = 10):从起始端口起在range范围内逐个用detect-port探测,返回第一个空闲端口,探测异常或范围内无空闲则返回null。该函数在 2.14.0 从 common 包迁入,供 CLI 与 node 在本地端口冲突时自动避让。

工程维护:依赖收敛与发布规范

从 CHANGELOG 后半段可以看到该包的长期维护节奏:

  • Polkadot 依赖持续对齐:@polkadot/api从 v9(0.1.0)一路更新到 v15(2.18.0)、v16(2.21.0),@polkadot/util至 v13(当前 package.json),为的是让哈希/编码行为与 SubQuery 其他包保持同源。
  • Sequelize 与数据库兼容:1.4.1 升级 sequelize 6.28.0;2.4.1 起改用@subql/x-sequelize以支持 CockroachDB;2.6.1/2.6.2 针对大库中getForeignKeyReferencesQuery的性能与子查询表达式报错做了修复。
  • 发布体积与质量:2.20.0 从发布包中移除测试文件与产物(对应 package.json 中files的!/dist/**/*.spec.*等排除规则);2.12.0 开启 TS strict 模式并对无效 GraphQL schema 提供更友好的错误。
  • ESLint 9 严格化(2.22.0):升级 lint 规则带来的"较小改进与修复",以及 2.22.1 对flatted依赖的更新,属于纯工程面调整。

版本演进速查(完整条目)

以下按 CHANGELOG 原文顺序整理全部版本变更,便于按版本号对照功能:

版本日期类型核心内容
2.22.12025-11-05Changed更新 flatted 依赖 (#2941)
2.22.02025-10-15Changed升级 eslint 9 及更严格配置带来的改进与修复 (#2929)
2.21.22025-09-16Changed处理 linter 告警 (#2876);更新 polkadot 依赖 (#2915)
2.21.12025-07-24Fixed拼写修正 (#2834)
2.21.02025-07-14Changed对齐@polkadot/api@16(#2845)
2.20.12025-07-02Fixed_global表正则修复 (#2840)
2.20.02025-07-01Removed从发布包移除测试文件与产物 (#2838)
2.19.02025-05-21Added新增_global表正则 (#2799)
2.18.12025-04-24Changed更新 polkadot 依赖
2.18.02025-02-19Changed更新 polkadot api 至 15 (#2680)
2.17.22025-02-04Changed版权头更新至 2025;错误信息包含允许的 dbType 类型 (#2662);修复拼写
2.17.12025-01-28Fixed@dbType指令下 GraphQL 实体关系无法解析 id 类型 (#2649)
2.17.02024-12-11Added新增@dbTypeGraphQL 指令 (#2622)
2.16.02024-11-25Changedpolkadot/api 更新至 14
2.15.02024-11-22Added/Changed支持枚举字段索引 (#2586);更新 metadata 类型 (#2584)
2.14.02024-08-05Added/Changed从 common 包引入findAvailablePort(#2518);更新依赖
2.13.12024-07-25FixedJson 与 Json 数组哈希前按键排序
2.13.02024-07-22Changed错误日志尽量附带错误实例名 (#2492)
2.12.12024-07-09ChangedTS 构建设置调整 (#2475)
2.12.02024-06-21Added无效 GraphQL schema 的错误信息优化 (#2458);启用 TS strict;Query 调试时 TS 检查报错
2.11.02024-06-12Changed支持带 cause 的错误日志并改进颜色 (#2435)
2.10.02024-05-08Changedpolkadot 依赖更新至 v11
2.9.22024-05-02Fixedworker logger 的 debug 标志失效问题 (#2374)
2.9.12024-04-12Changed更新 tar 依赖
2.9.02024-03-28Added导出numberToHex(#2307);新增hexStripZeros以对齐 ethers (#2319)
2.8.02024-03-05Added新增@fullTextGraphQL 指令 (#2280)
2.7.12024-02-29FixedInt hashCode 因不支持负数而失败 (#2278)
2.7.02024-01-25Added导出 sequelize 支持类型 (#2179)
2.6.22024-01-10Fixedx-sequelize 中getForeignKeyReferencesQuery在大库下的性能 (#2212)
2.6.12024-01-04Fixedx-sequelize 修复子查询表达式多行返回错误 (#2209)
2.6.02023-11-10Changed/RemovedPolkadot/util 10.5.1 (#2150);移除未使用的 axios (#2155)
2.5.02023-10-31AddedLogger 支持负向过滤,--debug="*,-SQL"(#2133)
2.4.42023-10-11Added/Fixed子 logger 独立 debug 级别;修复不支持字段类型的 undefined TS 类型 (#2003)
2.4.32023-07-31Fixed更新 license (#1891)
2.4.22023-06-26Fixed修正 metadata 的 rowCountEstimate 类型,移除 terra metadata (#1839)
2.4.12023-06-09Changed改用@subql/x-sequelize以支持 CockroachDB (#1791)
2.4.02023-05-30Added实体复合索引 (#1759);暴露 base64 函数 (#1761)
2.3.02023-05-24AddedBase58 工具函数 (#1750)
2.2.02023-05-19Changedpolkadot api 更新至 10.7.1 (#1736)
2.1.02023-05-10Changed通过 utils 暴露全部@polkadot/utils与@polkadot/utils-crypto(#1653)
2.0.02023-04-20Changed主版本 2.0.0,与其余包版本对齐
1.5.02023-04-14Added@jsonField支持关闭 GIN 索引 (#1613)
1.4.22023-03-29Changedpolkadot api 更新至 10.1.4 (#1580)
1.4.12023-02-21Changedsequelize 升级至 6.28.0 (#1521)
1.4.02023-01-23Changedmetadata 类型新增startHeight(#1473);polkadot api 9.11.1 (#1483)
1.3.12022-11-30Fixed支持 PostgreSQL 标识符限制 (#1438)
1.3.02022-11-23Changed支持多链索引 (#1375)
1.2.02022-08-11Changedsequelize 更新至 6.23.0 (#1311)
1.1.02022-08-11Changed@polkadot/util更新至 v10 (#1230)
1.0.12022-07-05Fixed依赖整理,ipfs-http-client移至 common 包 (#1160)
1.0.02022-05-11Changed主版本发布
0.1.02022-05-06Changedpolkadot/api 更新至 9

从这张表可以清楚看到两条演进脉络:一是面向数据模型的 GraphQL 指令不断补齐(@jsonField → @compositeIndexes → @fullText → @dbType),二是依赖面(polkadot、sequelize/x-sequelize)持续与 SubQuery 其他包对齐。CHANGELOG 遵循 Keep a Changelog 格式、按 Semantic Versioning 语义化版本管理,并在 packages/utils/package.json 中提供了changelog:release脚本(基于npx chan release与utils/版本前缀),说明每次发版都会同步产出标准化的变更记录。

小结

@subql/utils是一个"小而全"的基础包:graphql模块决定 SubQuery 数据模型如何被解释与校验,types模块决定字段如何哈希与映射到 PostgreSQL,logger模块决定索引/查询服务的可观测性,buffer与networking则是通用工具补充。结合 packages/utils/CHANGELOG.md 与各源码文件对照阅读,既能按版本快速判断升级影响面,也能在遇到 schema 校验、日志过滤或哈希不一致等问题时,直接定位到具体的实现文件与修复版本。

  • 区块链
  • 后端

【免费下载链接】subql

SubQuery is an Open, Flexible, Fast and Universal data indexing framework for web3. Our mission is to help developers create the decentralised products of the future.

项目地址:https://gitcode.com/gh_mirrors/su/subql
点击查看免费下载
上一篇:IPFS Desktop:零基础入门分布式存储,告别技术门槛
下一篇:Wand-Enhancer:游戏修改器本地化增强架构解析与深度定制指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 2:35:40

2025年IT转行指南:数据工程、云原生与AI应用赛道解析

写这篇东西的起因特别简单&#xff1a;前两周有个后台私信&#xff0c;说自己在传统行业干了八年&#xff0c;想转行进IT&#xff0c;问我“2025年到底该学什么”。我盯着这个问题想了半天&#xff0c;发现它其实不是“学什么”的问题&#xff0c;而是“选什么赛道”的问题。IT…

作者头像 李华
网站建设 2026/10/1 2:35:38

kkFileView HTTPS在线预览配置与混合内容排障实战

前阵子帮一个做内部文档中台的朋友收拾一个预览故障&#xff1a;业务站点早就全站切到了 https&#xff0c;嵌在页面里的预览窗口却始终白屏&#xff0c;浏览器控制台红字刷了一屏。排查大半天&#xff0c;根因朴素得让人想笑——kkfile 这边的预览服务还老老实实跑在 http 上。…

作者头像 李华
网站建设 2026/10/1 2:35:09

Unity中手绘FlowMap:FlowPainter编辑器工具实现与Shader采样优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/1 2:34:19

springboot3建筑工程项目管理平台 毕业设计---附源码87085

摘要 建筑工程管理领域面临信息传递滞后与流程协作脱节等挑战。传统管理模式依赖纸质文档与线下沟通&#xff0c;难以应对项目延期、质量监管、跨部门协同等复杂场景。现代项目管理对数据实时性与流程规范性提出了更高要求&#xff0c;亟需构建集成化的信息管理平台以提升整体效…

作者头像 李华
网站建设 2026/10/1 2:34:04

YOLOv8道路病害检测实战:从数据集标注到模型部署全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华