@arkstack/common

中文文档
0.22.2发布于 2026/11/07ES Module近 30 天下载 5224

Arkstack生态系统的核心公用事业、原始物和共享基础设施.

中文使用文档
文档目录17 节
  1. 目录
  2. 安装
  3. 模块
  4. 系统
  5. 锁定器
  6. 错误汉德勒
  7. 例外
  8. 钩子
  9. 加密
  10. 散开
  11. 网络
  12. 生命周期
  13. 原型
  14. 全球增强
  15. 类型
  16. 环境变量参考
  17. 帮助者

@arkstack/common

@arkstack/common

Arkstack框架生态系统的核心公用设施、原始设施和共享基础设施。 这个软件包提供了所有Arkstack软件包中使用的构件——错误处理,记录,散列,加密,生命周期管理,钩子等.


目录


安装

pnpm add @arkstack/common

模块

系统

src/system.ts

为环境变量访问、配置加载、路径解析和动态文件导入提供核心应用程序级公用事业.

env(key, defaultValue?)

从 process.env 有自动类型的强制。 布尔( B)true, (中文(简体) ), false, (中文(简体) ), on, (中文(简体) ), off),数字, null,空字符串都处理得优雅.

import { env } from '@arkstack/common'

const port = env('PORT', 3000) // number
const debug = env('DEBUG', false) // boolean
const name = env('APP_NAME', 'App') // string

类型强制规则:

原始值已解析类型
"true" 编号 : "on"true
"false" 编号 : "off"false
数字字符串number
"null"null
""undefined (倒计时) defaultValue(中文(简体) )

config(key?, defaultValue?)

从构建输出中装入并合并所有配置文件 config/ 目录。 支持 dot-path 密钥访问, 并带有完整的 TypeScript 推论.

import { config } from '@arkstack/common'

// Get the full config object
const allConfig = config()

// Access a nested key
const dbHost = config('database.host', 'localhost')

配置文件从解析后加载 outputDir() 使用 createRequire在 CLI 语境中运行时会跳过中件配置文件 .


构建一个完全合格的应用程序 URL APP_URL 财务报告和审定财务报表 PORT 环境变量.

import { appUrl } from '@arkstack/common'

appUrl() // "http://localhost:3000"
appUrl('/api/health') // "http://localhost:3000/api/health"

nodeEnv()

回返 'dev' 或者说 'prod' 基于 NODE_ENV 环境变量。 默认为 'dev' 对于任何未识别值.

import { nodeEnv } from '@arkstack/common'

nodeEnv() // "dev" | "prod"

outputDir(cwd?)

确定构建输出目录。 在开发中,默认为 .arkstack/build;在生产中,改为 dist两者都可以通过环境变量被推翻:

变量A. 背景情况默认
OUTPUT_DIR_DEV发展.arkstack/build
OUTPUT_DIR生产dist

importFile<T>(filePath)

动态导入文件使用 贾蒂,带有类型脚本和 tsconfig 路径支持。 用于在运行时装入用户定义的配置文件或插件文件 .

import { importFile } from '@arkstack/common'

const module = await importFile<{ default: MyConfig }>('./config/app.ts')

锁定器

src/Logger.ts

一个有结构的,有粉笔功率控制控制台的收录器,两栏格式化,并可堆放解析 API.

基本对数水平

import { Logger } from '@arkstack/common'

Logger.success('Server started')
Logger.info('Listening on port 3000')
Logger.warn('Deprecated option used')
Logger.error('Something went wrong', false) // false = don't exit
Logger.debug('Internal state dump') // only shown at verbosity >= 3

每个关卡都使用不同的图标和颜色:

方法图标颜色
success✓绿色
infoℹ蓝色
warn⚠黄色
error✖红色
debug🐛灰色

所有级别方法的第二个论据是 exit (boolean) (布尔语). 何时 true,该流程在日志后退出. error 默认退出( e)exit = true; 所有其他默认为 false。 。 。 .


Logger.configure(options)

设定了全球动词和压制行为.

Logger.configure({
  verbosity: 3, // enables debug output
  quiet: true, // suppresses info and success
  silent: true, // suppresses all output
})

Logger.twoColumnDetail(name, value, log?, spacer?)

将一个右向的双柱布局加到终端宽度上.

Logger.twoColumnDetail('Route', 'GET /api/users')
// "Route ......................................... GET /api/users"

const row = Logger.twoColumnDetail('Route', 'GET /api/users', false)
// returns [name, dots, value] without printing

Logger.describe(name, desc, width?, log?)

类似 twoColumnDetail,但使用固定宽度的空间垫而不是点。 用于命令帮助列表 .

Logger.describe('--port', 'Port to listen on', 40)
// "--port                    Port to listen on"

Logger.split(name, value, status?, exit?, preserveCol?, spacer?)

喜欢 twoColumnDetail,但根据 status。 。 。 .

Logger.split('Database', 'Connected', 'success')
Logger.split('Migration', 'Failed', 'error', true) // exits after logging

Logger.parse(config, joiner?, log?, sc?)

从 a 组成一个有样式的字符串 [text, chalkStyle] 组合阵列.

Logger.parse(
  [
    ['Arkstack', 'bold'],
    ['v1.0.0', 'gray'],
  ],
  ' ',
) // "Arkstack v1.0.0"

// Return instead of print
const str = Logger.parse([['Ready', 'green']], ' ', false)

Logger.log(config, joiner?, log?, sc?)

接受字符串+样式的灵活多态记录器,或 LoggerParseSignature 阵列。 返回 Logger 上课时没有争论.

Logger.log('PORT:3000', 'cyan')
Logger.log(
  [
    ['PORT', 'bold'],
    ['3000', 'cyan'],
  ],
  ' ',
)

Logger.chalker(styles[])

返回一个对任意输入应用一串粉笔样式的函数.

const highlight = Logger.chalker(['bold', 'green'])
console.log(highlight('Ready'))

Logger.console()

回返a Console- 对象与 log, (中文(简体) ), debug, (中文(简体) ), warn, (中文(简体) ), info,以及 error 方法。 。 。 可用于替换 globalThis.console。 。 。 .

const console = Logger.console()
console.log('hello')
console.warn('watch out')

错误汉德勒

src/ErrorHandler.ts

用于常态化,序列化,分级化,和记录错误的静态通用类. 与 皮诺 用于持续错误文件记录.

ErrorHandler.createErrorPayload(err, fallbackMessage?)

初一法门. 将任意抛出值转换为相容 ArkstackErrorPayload 对象,处理验证错误,模型未发现错误,以及通用错误.

import { ErrorHandler } from '@arkstack/common'

try {
  // ...
} catch (err) {
  const payload = ErrorHandler.createErrorPayload(err, 'Request failed')
  // { status: 'error', code: 422, message: '...', errors: {...} }
}

有效载荷形状 :

{
  status: 'error'
  code: number        // HTTP status code (100–599)
  message: string
  errors?: unknown    // present for validation errors
  stack?: string      // present in development unless HIDE_ERROR_STACK is set
}

分类逻辑 :

错误类型codeerrors 人口数
校验错误( 有) .errors(中文(简体) )statusCode 编号 : status 或者说 422对
未找到模型( 有) .getModelName()(中文(简体) )404没有
常规错误statusCode 编号 : status 或者说 500堆叠跟踪为对象

ErrorHandler.serializeError(value, seen?)

递归序列化任何值——包括 Error 实例和循环引用——输入一个简单的JSON安全对象。 通知引用改为 '[Circular]'。 。 。 .

const serialized = ErrorHandler.serializeError(new Error('oops'))
// { name: 'Error', message: 'oops', stack: '...' }

ErrorHandler.normalizeStatusCode(value, fallback?)

确保状态代码是区域内的有效整数 100–599返回倒计时(默认) 500用于任何无效的东西.

ErrorHandler.normalizeStatusCode('422') // 422
ErrorHandler.normalizeStatusCode('xyz') // 500

ErrorHandler.getErrorLogger()

返回写到的 Pino 日志实例 storage/logs/error.log (自动创建). 实例按目的地路径缓存 .


ErrorHandler.logUnhandledError(err, request, message)

将一个未处理的错误延续到错误日志文件,包括序列错误和相关的请求上下文.

ErrorHandler.logUnhandledError(err, { method: 'GET', url: '/api' }, 'Unhandled exception')

分类助手

ErrorHandler.isValidationError(err) // true if err.errors is defined
ErrorHandler.isModelNotFoundError(err) // true if err.getModelName is a function
ErrorHandler.shouldLogError(err) // false for validation/model-not-found errors
ErrorHandler.shouldHideStack() // true if HIDE_ERROR_STACK env is set
ErrorHandler.getPrimaryError(err) // unwraps err.cause if present
ErrorHandler.toErrorShape(value) // casts unknown to ArkstackErrorShape if object

为了方便起见,所有静态方法也作为命名的独立函数被导出:

import {
  createErrorPayload,
  isValidationError,
  serializeError,
  logUnhandledError,
  // ...
} from '@arkstack/common'

例外

src/Exceptions/

结构化错误投掷的三级例外等级 .

Exception

基类扩展 Error设置 .name 改为 'Exception'。 。 。 .

import { Exception } from '@arkstack/common'

throw new Exception('Something went wrong')

AppException

扩展 Exception添加 statusCode (默认) 400)和可选 errors 用于实地级验证错误的地图.

import { AppException } from '@arkstack/common'

const err = new AppException('Validation failed', 422)
err.errors = { email: ['Email is required'] }

RequestException

扩展 AppException。用于 HTTP 请求级别错误。 提供两个静态断言助手:

RequestException.assertNotEmpty(value, message, code?)

丢出一个 RequestException 如果值为 null 或者说 undefined缩小成功类型.

import { RequestException } from '@arkstack/common'

const user = await User.find(id)
RequestException.assertNotEmpty(user, 'User not found', 404)
// user is now User (not null | undefined)

RequestException.abortIf(condition, message, code?)

如果情况属实就扔出.

RequestException.abortIf(!user.isActive, 'Account is suspended', 403)

钩子

src/Hook.ts

再出口 Hook 从 @arkstack/foundry;两种进口都是相同的全过程登记册。 见 @arkstack/foundry 读取 用于API(on, (中文(简体) ), emit, (中文(简体) ), get, (中文(简体) ), has, (中文(简体) ), off, (中文(简体) ), all, (中文(简体) ), clear) (中文(简体) ). 通过扩展宣告已输入的钩子名称 HookRegistry 打开 @arkstack/foundry。 。 。 .


加密

src/utils/encryption.ts

一个薄薄的包裹 @arkstack/encryption键。 AES-256-GCM用于敏感值(如:两因子认证机密);下面的软件包运行在Web Crypto API上,因此服务器上加密的值可以在浏览器中解密,反之亦然.

Encryption.encrypt(value, key?)

加密字符串。 返回受冒号限制的碱基64url字符串 : <iv>:<authTag>:<ciphertext>。 。 。 .

import { Encryption } from '@arkstack/common'

const token = Encryption.encrypt('my-secret-value')
// "abc123:def456:ghi789"

Encryption.decrypt(payload, key?)

解密由下列人员生产的有效载荷: encrypt。如果格式无效或密钥出错,则丢出.

const original = Encryption.decrypt(token)
// "my-secret-value"

Encryption.encryptAsync(value, key?, options?) 编号 : Encryption.decryptAsync(payload, key?, options?)

在Web Crypto路径上相同的操作,采用相同的有效载荷格式,因此两者可以自由混合. 当调用代码与浏览器共享(或可能成为)时使用这些. options.aad 将额外认证数据绑入密码文本.


Encryption.cipher(key?)

A 类 Cipher 绑定在应用程序密钥上,用于加密许多值而不重新定义密钥,并通过 encryptBytes 编号 : decryptBytes。 。 。 .


主要公用事业

Encryption.generateKey() // random base64url key
await Encryption.generateKeyPair() // { publicKey, privateKey } ECDH identity
await Encryption.deriveKey(password) // PBKDF2 → { key, salt, iterations }
await Encryption.compareKeys(left, right) // constant time
await Encryption.fingerprint() // displayable digest of the app key

端到端加密

const channel = await Encryption.channel(myPrivateKey, peerPublicKey)

await channel.decrypt(await channel.encrypt('hey'))

await Encryption.seal('anonymous tip', peerPublicKey)
await Encryption.open(payload, myPrivateKey)

await Encryption.safetyNumber(myPublicKey, peerPublicKey)

全数 @arkstack/encryption 水面- Cipher, (中文(简体) ), Codec, (中文(简体) ), EncryptionKey, (中文(简体) ), KeyPair, (中文(简体) ), Keys, (中文(简体) ), SealedBox, (中文(简体) ), SecureChannel, (中文(简体) ), NodeCipher ——从这批货再出口.

环境变量:

变量需求说明
APP_KEY对原始密钥;通过SHA-256向内部256位密钥散列

生成一个 ark key:generate遗产 TWO_FACTOR_ENCRYPTION_KEY 仍然受到尊重,当 APP_KEY 未设置.


散开

src/utils/hash.ts

密码散列和检察官办公室发电设施.

Hash.make(value)

Hashes 使用 bcrypt 的字符串,盐因子为 10.

import { Hash } from '@arkstack/common'

const hashed = await Hash.make('user-password')

Hash.verify(value, hashedValue)

比较纯文本值和 bcrypt 散列值.

const isValid = await Hash.verify('user-password', hashed)

Hash.otp(digits?, label?, period?)

使用 otpauth 图书馆 SHA1 和一个静态的秘密。 适合简单的基于时间的检察官办公室流动.

const totp = Hash.otp(6, '[email protected]', 60)
const token = totp.generate()

Hash.totp(secret, label, issuer?, period?)

从一个已编码的 Base32 密钥创建 TOTP 实例 。 用于用户专用的TOTP(如认证器应用集成).

const totp = Hash.totp(user.totpSecret, user.email)
const isValid = totp.validate({ token: userInput }) !== null

网络

src/network.ts

启动 HTTP 服务器、 自动端口检测和渲染出错视图的工具 .

bootWithDetectedPort(boot, preferredPort?, app?)

检测是否可用的首选端口( 使用 ) detect-port),并在第一个自由端口上为服务器提供靴子. 添加关键全局 : env, (中文(简体) ), config, (中文(简体) ), str, (中文(简体) ), app,以及 arkctx。 。 。 .

import { bootWithDetectedPort } from '@arkstack/common'

await bootWithDetectedPort(
  async (port) => {
    server.listen(port)
    Logger.success(`Server:http://localhost:${port}`)
  },
  3000,
  appInstance,
)

全局设置 :

全球数值
globalThis.app() => app
globalThis.envenv
globalThis.configconfig
globalThis.strstr (从) @h3ravel/support(中文(简体) )
globalThis.arkctx{ runtime: 'HTTP' }

renderError({ message, stack, title, code })

使用 ~arkstack/common.error 视图模板。 倒从内置状态代码地图回落为人可读标题.

import { renderError } from '@arkstack/common'

const html = renderError({ code: 404, message: 'Page not found' })

内建状态头衔 : 400, (中文(简体) ), 401, (中文(简体) ), 403, (中文(简体) ), 404, (中文(简体) ), 500, (中文(简体) ), 502, (中文(简体) ), 503, (中文(简体) ), 504。 。 。 .


生命周期

src/lifecycle.ts

bindGracefulShutdown(shutdown)

注册清理召回 SIGINT, (中文(简体) ), SIGTERM,以及 SIGQUIT 信号,确保应用程序干净关闭.

import { bindGracefulShutdown } from '@arkstack/common'

bindGracefulShutdown(async () => {
  await db.disconnect()
  Logger.info('Server shut down gracefully')
})

原型

src/prototypes.ts

loadPrototypes()

扩展 String.prototype 使用四种实用方法。 在应用拖带时调用它一次 .

import { loadPrototypes } from '@arkstack/common'

loadPrototypes()

增加的方法:

方法说明示例
.titleCase()转换为标题大小写( 处理) _ 财务报告和审定财务报表 -(中文(简体) )"hello_world".titleCase() → "Hello World"
.camelCase()转换为骆驼Case"Hello World".camelCase() → "helloWorld"
.pascalCase()转换为 PascalCase"hello world".pascalCase() → "HelloWorld"
.truncate(len, suffix?)在字段边界上断线"Hello World".truncate(7) → "Hello..."

全球增强

src/app.d.ts

何时 loadPrototypes() 名为 bootWithDetectedPort() 将运行时间、以下全局和字符串原型扩展设置在应用程序中 :

// Globals (set by bootWithDetectedPort)
globalThis.env // GlobalEnv — typed env() accessor
globalThis.config // GlobalConfig — typed config() accessor

// String prototype extensions (set by loadPrototypes)
'my_string'.titleCase()
'my_string'.camelCase()
'my_string'.pascalCase()
'my long string'.truncate(10, '…')

类型

src/types.ts

从包中导出密钥类型 :

类型说明
GlobalEnv打印的签名 env() 函数
GlobalConfig打印的签名 config() 带有点路径支持的函数
ArkstackErrorShape跨框架常见错误属性的结合(statusCode, (中文(简体) ), status, (中文(简体) ), errors, (中文(简体) ), cause页:1
ArkstackErrorPayload由 : ErrorHandler
LoggerChalkChark 样式标识符被接受 Logger 方法
LoggerParseSignature矩阵 [string, LoggerChalk] 用于 Logger.parse()
LoggerLog超载函数类型 Logger.log()

环境变量参考

变量模块需求说明
PORTsystem, (中文(简体) ), network没有HTTP 服务器端口( 默认 ): 3000(中文(简体) )
APP_URLsystem没有基础应用程序 URL
APP_NAMEhash没有用作 TOTP 发行器的应用程序名称
NODE_ENVsystem没有development 或者说 production
OUTPUT_DIRsystem没有生产构建输出目录( 默认 ): dist(中文(简体) )
OUTPUT_DIR_DEVsystem没有开发构建输出目录( 默认值 : .arkstack/build(中文(简体) )
TWO_FACTOR_ENCRYPTION_KEYencryption对*AES-256-GCM 加密的秘密密钥( * 仅在使用时需要) Encryption(中文(简体) )
HIDE_ERROR_STACKErrorHandler没有设定为 true, (中文(简体) ), 1,或 on 以压制错误有效载荷中的堆栈痕迹

帮助者

src/utils/helpers.ts

perPage(query, defaults?)

从查询对象中提取安全页标限制。 粘接结果介于 1 财务报告和审定财务报表 50 或配置的默认值 maxPerPage,默认为 25 或配置的默认值 perPage。 。 。 .

import { perPage } from '@arkstack/common'

const limit = perPage({ limit: 100 }) // 50 (clamped)
const limit2 = perPage({ limit: 100 }, { maxPerPage: 100 }) // 100
const limit3 = perPage({}) // 25 (default)
const limit3 = perPage({}, { perPage: 100 }) // 100

resolvePagination(query, defaults?)

从查询对象中提取当前页面和安全页码限制。 粘接结果 perPage 介于 1 财务报告和审定财务报表 50 或配置的默认值 maxPerPage,默认为 25 或配置的默认值 perPage。 。 。 .

import { resolvePagination } from '@arkstack/common'

const limit = resolvePagination({ limit: 100 }) // {perPage: 50, page: 1} (clamped)
const limi2 = resolvePagination({ limit: 100 }, { maxPerPage: 100 }) // {perPage: 100, page: 1}
const limit3 = resolvePagination({}) // {perPage: 50, page: 1} (default)
const limit4 = resolvePagination({}, { perPage: 100, page: 2 }) // {perPage: 100, page: 2}

getModel(modelName)

动态地从配置的模型目录中以名称导入应用程序模型( 默认 ): ./src/app/models) (中文(简体) ). 增加支助 ModelRegistry 用于类型安全检查.

import { getModel } from '@arkstack/common'

const User = await getModel('User')
const users = await User.findAll()

// With type augmentation:
declare module '@arkstack/common' {
  interface ModelRegistry {
    User: typeof User
  }
}

const TypedUser = await getModel('User') // typeof User

版本与发布记录

@arkstack/common 共发布 238 个版本,首次发布于 2026/03/04;过去 12 个月发布了 238 个版本。

版本发布日期距今
0.22.2latest2026/11/07今天
0.22.12026/11/052 天前
0.22.02026/11/052 天前
0.21.12026/11/052 天前
0.21.02026/10/2810 天前
0.20.22026/10/2315 天前

关于 @arkstack/common 的常见问题

@arkstack/common 是什么?

Arkstack生态系统的核心公用事业、原始物和共享基础设施.

如何安装 @arkstack/common?

在项目目录运行 npm install @arkstack/common,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@h3ravel/support(^2.2.7)、@arkstack/foundry(^0.22.2)、@arkstack/contract(^0.22.2)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@arkstack/common 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/arkstack__common 是否存在。

@arkstack/common 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@arkstack/common 可以商用吗?

@arkstack/common 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@arkstack/common 的下载量有多少?

根据 npm 官方下载统计,@arkstack/common 在 2026/10/07 – 2026/11/05 这 30 天内被下载 5,224 次,日均约 174 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@arkstack/common 还在维护吗?

最新版本 0.22.2 发布于 2026/11/07(今天);至今共发布 238 个版本,其中过去 12 个月发布了 238 个;首次发布于 2026/03/04。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。