@devfellowship/ux-paths-spec

中文文档
1.3.1发布于 2026/08/14MITTypeScriptES Module零依赖近 30 天下载 8443

The DFL UX Paths data contract: the v1 JSON Schema, TypeScript types generated from it, and a validate() with zero runtime dependencies and zero network I/O.

原始使用文档
文档目录9 节
  1. Why this is a separate package
  2. What it exports
  3. The $id is a name, not an address
  4. Zero runtime dependencies is a tested property
  5. So how does it validate without Ajv?
  6. Versioning
  7. Changing the schema
  8. Not in the schema yet (a v1.4 conversation)
  9. License

@devfellowship/ux-paths-spec

The DFL UX Paths data contract, on its own: the v1 JSON Schema, TypeScript types generated from it, and a validate() with zero runtime dependencies and zero network I/O.

pnpm add @devfellowship/ux-paths-spec
import { validate, assertValid, SCHEMA_V1 } from "@devfellowship/ux-paths-spec";
import type { UxPathsDoc } from "@devfellowship/ux-paths-spec";

const result = validate(JSON.parse(text));
if (!result.valid) {
  for (const error of result.errors) console.error(error.formatted);
  //  screens[0].id: must be string (expected type: string)
  process.exit(1);
}
result.doc.screens; // typed as UxPathsDoc

// Or the throwing form, which narrows in place.
assertValid(doc, "itera-player.flows.json");

Why this is a separate package

Its consumers are a CI validator, a capture job and an AI explorer. None of them should need React to find out whether a flows.json is well-formed, and one of them runs in a browser. The schema is a data contract, so it ships as data — not folded into a component library.

It also ends a vendored copy kept in step by a promise. dfl-components-cli carries its own copy of v1.schema.json with a comment asking a human to "mirror it in the same round". A promise fails quietly: the copy goes stale, the validator keeps exiting 0, and a document nobody should have accepted sails through. Here, every artifact that restates the schema is generated from it, and CI fails if any of them stops matching.

What it exports

ExportWhat it is
validate(doc, options?){ valid: true, doc } or { valid: false, errors }. No I/O. Synchronous.
assertValid(doc, location?, options?)Throws SpecValidationError; narrows doc to UxPathsDoc on success.
formatErrors(errors)One human-readable line per violation.
SCHEMA_V1The schema itself, as an object.
SCHEMA_IDThe schema's $id. A name, not an address — see below.
SUPPORTED_SCHEMA_VERSIONS["1.0.0", "1.1.0", "1.2.0", "1.3.0"].
UxPathsDoc, Screen, Flow, Screenshot, SourceRef, …Types generated from the schema.
stepScreenId, flowScreenIds, danglingScreenIdsHelpers for rules JSON Schema cannot express.
assertSchemaSupported, isDateTime, isUriInternals, exported for testing.

The raw schema also ships in the tarball, for consumers that are not TypeScript:

import schema from "@devfellowship/ux-paths-spec/schema/v1.json" with { type: "json" };

The $id is a name, not an address

SCHEMA_ID is https://raw.githubusercontent.com/devfellowship/dfl-ux-paths/main/schema/v1.json.

dfl-ux-paths is a private repo, so that URL 404s for anyone outside the org — and GitHub reports a private path as not found, never forbidden, so the failure disguises itself as a broken link. The $id identifies the schema. It is never fetched. This package exists in large part so that nothing has to try.

Zero runtime dependencies is a tested property

dependencies is absent from package.json, and src/__tests__/package-contract.test.ts fails the build if one appears, if shipped source imports anything non-relative, or if it references fetch / node:fs / any other host API.

tsconfig.build.json drops @types/node from the shipped compile, so a node: import is a compile error rather than a convention someone remembers.

So how does it validate without Ajv?

It interprets the schema at runtime. validate() reads SCHEMA_V1 and walks the document against it — the schema is the input, never a thing transcribed into TypeScript. Add a field upstream and this validator enforces it with no edit here. A hand-written validator would have re-created the exact drift this package exists to end.

Two guards keep that honest:

  • Ajv parity. Ajv is the reference implementation and stays a devDependency. src/__tests__/ajv-parity.test.ts runs both engines over every committed flows document plus ~30 single-rule mutations, and fails on any disagreement.
  • Unknown keywords are a hard stop. The interpreter implements a fixed keyword set. If a future schema uses one it does not know, assertSchemaSupported() throws naming the keyword, rather than skipping it and quietly accepting documents it should refuse. A v1.4 needing maxLength fails here loudly, in the round it lands.

Versioning

major.minor tracks the highest schema_version the package admits — 1.3.x ships schema v1.3. A schema v1.4 makes it 1.4.0. A fix in validate() is a patch bump. A test asserts the version and the schema agree.

Changing the schema

schema/v1.json at the repo root is the single source of truth. Edit it, then:

pnpm --filter @devfellowship/ux-paths-spec run generate

That rewrites spec/schema/v1.json (byte copy), spec/src/schema.generated.ts and spec/src/types.generated.ts. Never edit those three by hand. CI runs generate --check and fails, naming the stale files, if you forget.

Not in the schema yet (a v1.4 conversation)

The viewer app reads three fields the schema has never defined: requirements[], screen.fidelity and screen.archetype (plus screen.page_class). The schema sets additionalProperties: false at the top level and on $defs/screen, so a document carrying any of them is refused — this is a real gap, not a tolerated extra. Three committed viewer fixtures fail validation for exactly this reason, and ajv-parity.test.ts pins that fact with both engines so it stays visible until v1.4 closes it.

License

MIT.

版本与发布记录

@devfellowship/ux-paths-spec 共发布 2 个版本,首次发布于 2026/08/13;过去 12 个月发布了 2 个版本。

版本发布日期距今
1.3.1latest2026/08/142 个月前
1.3.02026/08/132 个月前

关于 @devfellowship/ux-paths-spec 的常见问题

@devfellowship/ux-paths-spec 是什么?

The DFL UX Paths data contract: the v1 JSON Schema, TypeScript types generated from it, and a validate() with zero runtime dependencies and zero network I/O.

如何安装 @devfellowship/ux-paths-spec?

在项目目录运行 npm install @devfellowship/ux-paths-spec,或使用 pnpm add / yarn add / bun add。

@devfellowship/ux-paths-spec 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@devfellowship/ux-paths-spec 支持 ESM 还是 CommonJS?

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

@devfellowship/ux-paths-spec 需要什么版本的 Node.js?

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

@devfellowship/ux-paths-spec 可以商用吗?

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

@devfellowship/ux-paths-spec 的下载量有多少?

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

@devfellowship/ux-paths-spec 还在维护吗?

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