@empyria/common

中文文档
0.3.18发布于 2026/11/01MITES Module

Shared backend goodies for Empyria

原始使用文档
文档目录9 节
  1. Requirements
  2. Install
  3. Usage
  4. Modules
  5. Validation options
  6. Schema builders
  7. Dialect
  8. Scripts
  9. License

@empyria/common

Shared backend services for higher-level components in Empyria, a nanoservice framework built primarily on Bun: environment variable schemas, error definitions, Codogram (SMS/TOTP-style challenge codes), and Ata (JSON schema building blocks and validation).

Requirements

  • Bun >=1.4.0 or Node.js >=26
  • Plain ESM, no build step, no TypeScript

Both requirements come from @empyria/classification, which this package depends on and which uses the native Temporal global for all date/time handling.

Install

bun add @empyria/common

Usage

import { createEnv, BaseErrors, generateCodogram, validate, string } from '@empyria/common'

const envSchema = createEnv({ API_KEY: string() })

throw new BaseErrors.EntityInvalid({ type: 'User', id: 42 })

const pin = generateCodogram('PIN')

Everything is re-exported from the package root via index.js. Individual modules under lib/ can also be imported directly if you only need one:

import { defineSchema } from '@empyria/common/lib/Ata.js'

Modules

ModulePurpose
index.jsPackage entry point; re-exports every module below plus Moleculer meta helpers (moleculerMeta, moleculerEmpyriaMeta) and workflow ID helpers (workflowName, workflowId, identifyWorkflow).
lib/Errors.jsEmpyriaError, the ErrorCreator factory, and BaseErrors — Empyria's catalog of pre-built, templated errors.
lib/Env.jscreateEnv — builds a service's environment-variable JSON schema from Empyria-wide defaults; pass { closed: true } to reject undeclared vars and bind { coerceTypes, removeAdditional } to the schema.
lib/Ata.jsJSON schema building blocks (string, number, integer, bool, enumType, constant, nullable, array, discriminated, email, isoDateTime, ...) and validation — throwing (defineSchema, createValidator, validate), transform-intent aliases (parse, createParser), or non-throwing/structured (createChecker, checkSchema, now returning the parsed data) — built on ata-validator. See Schema builders and Validation options below.
lib/Codogram.jsgenerateCodogram — one-time challenge codes (PIN, alphanumeric, alphabetic) for SMS/TOTP-style verification flows.
lib/Defaulter.jsdefaultsFromSchema — builds a fully-populated default object for a JSON schema.

Every exported function is documented with JSDoc directly in its source file — hovering a function in VSCode or Zed shows its parameters and return type without any extra tooling, since both editors read JSDoc from plain .js files automatically.

Tests live under test/, one file per module, separate from the lib/ sources.

Validation options

createValidator / validate / parse / createChecker / checkSchema forward ata-validator's options to the underlying Validator. Options are resolved in three layers, last wins:

  1. library defaults — setAtaDefaults({ ... }), called once at startup for a deployment-wide policy; getAtaDefaults() reads it back, setAtaDefaults() clears it.
  2. schema-bound — defineSchema(map, { validation: { ... } }) stores options on a non-enumerable key, so a schema carries its own parsing policy (schemaOptions(schema) reads it). The schema still serialises and compares as plain JSON Schema.
  3. per-call — the options argument to any of the functions above.

formats is merged one level deep, with EMPYRIA_FORMATS always underneath.

OptionWhat it does (Empyria relevance)
coerceTypes"4040" → 4040 before validation. The reason env.js files work — every process.env value is a string.
useDefaultsFill missing props from their schema default. On by default; every string()/number()/bool()/enumType() emits one.
removeAdditionalStrip keys not covered by the schema. Only visible with additionalProperties: false (i.e. defineSchema({ strict: true })).
assertFormatWhether a format mismatch is a hard error. On by default.
abortEarlyStop at the first error, skip enrichment. For hot verdict-only paths (pair with createChecker, not the throwing path).
richErrorsKeep ATA#### codes / doc URLs / hints that renderPretty & co. consume. On by default; leave it on.
verboseAdd parentSchema to each error (ajv's verbose).
formatsCustom format checkers. EMPYRIA_FORMATS (empyria-email, empyria-password, empyria-ipv4, empyria-ipv6) is folded in automatically.

Return value / mutation. createValidator & validate return ata-validator's result.data — the same object as the input unless coerceTypes / removeAdditional / useDefaults applied. Those passes also mutate the input object in place, so hand them a copy when the caller must keep its input pristine (as the env.js files do with { ...process.env }). parse / createParser are behavioural aliases for call sites whose intent is to transform rather than merely assert. createChecker / checkSchema now also return data (the parsed value on success, undefined on failure).

Schema builders

Each returns a plain JSON Schema fragment; compose them in defineSchema(map, opts).

BuilderProduces
bool(default?){ type: 'boolean' }
string(default?, minLength | { minLength, maxLength, pattern, format, description }){ type: 'string', … }
number(default?, { min, max, exclusiveMin, exclusiveMax, multipleOf, description }){ type: 'number', … }
integer(default?, …){ type: 'integer', … } — use for ports/counts; rejects 3.5
enumType(list, default?, { type, description }){ enum, type? }
constant(value, { description }){ const: value }
nullable(schema)type: [t, 'null'], or { anyOf: [schema, { type: 'null' }] }
array(items?, { minItems, maxItems, uniqueItems, default, description }){ type: 'array', … }
email() / password() / ip4() / ip6(){ type: 'string', format: 'empyria-*' } (see EMPYRIA_FORMATS)
isoDateTime() / isoDate() / isoTime() / duration() / uri() / uuid(){ type: 'string', format: … } (ata built-in formats)
logLevel() / nodeEnv() / tmpFile() / logFile()domain presets
discriminated(prop, { value: schema, … }, { description })JSON Schema v1 propertyDependencies — an object whose shape depends on prop's value

Dialect

defineSchema(map, { dialect: 'v1' \| '2020-12' \| 'draft-07' \| <uri> }) stamps $schema (ata-validator reads it to pick the dialect). setDefaultDialect('v1') / getDefaultDialect() set a process-wide default a per-call dialect overrides. v1 differs from 2020-12 only in $dynamicRef scoping and unlocks propertyDependencies; discriminated() works on any dialect (ata supports the keyword as an extension) but dialect: 'v1' makes it spec-legitimate.

defineSchema(map, { strict: 'unevaluated' }) sets unevaluatedProperties: false while leaving additionalProperties open — the composable form of strict, for schemas meant to be allOf-combined.

Scripts

bun run format       # check formatting (oxfmt)
bun run format:fix   # apply formatting
bun run lint         # lint (oxlint)
bun run lint:fix     # lint and fix
bun run test         # run tests with coverage

License

MIT © Imre Fazekas

版本与发布记录

@empyria/common 共发布 30 个版本,首次发布于 2026/08/16;过去 12 个月发布了 30 个版本。

版本发布日期距今
0.3.18latest2026/11/012 天前
0.3.172026/10/295 天前
0.3.162026/10/259 天前
0.3.152026/10/2311 天前
0.3.142026/10/1815 天前
0.3.132026/10/1618 天前

关于 @empyria/common 的常见问题

@empyria/common 是什么?

共享后端为Empyria的好东西

如何安装 @empyria/common?

在项目目录运行 npm install @empyria/common,或使用 pnpm add / yarn add / bun add。

@empyria/common 支持 TypeScript 吗?

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

@empyria/common 支持 ESM 还是 CommonJS?

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

@empyria/common 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=26。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@empyria/common 可以商用吗?

@empyria/common 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@empyria/common 还在维护吗?

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