@bridge-ds/core

中文文档
0.29.0发布于 2026/11/08MITTypeScriptES Module构建来源已验证近 30 天下载 6064

Bridge Core: bridge.config.json, DTCG 令牌加载(等级和分层模式),别名分辨率,WCAG对比,diffs,最小-diff编辑,PR正文,共享风险等级分级器,更改ets和一个基于取回的GitHub客户端. 无 Figma API, 无 DOM; 节点连接

中文使用文档
文档目录22 节
  1. 等级
  2. 配置
  3. 施政
  4. 分层集(CLI和MCP)
  5. 类型
  6. json-ast和dtcg-codec(最小编辑)
  7. 数值和范围
  8. 符号集( 装入量)
  9. 解析器(跨层级的异名)
  10. wcag (续)
  11. 验证器(护栏)
  12. id-map and diff-engine (三道diff) 互联网档案馆的存檔,存档日期2013-12-21
  13. 作曲( 回写更改)
  14. 风险
  15. pr- 组合和更改
  16. github 客户端
  17. 建议(建议t、建议审查t、建议github.ts)
  18. 故事书(故事书.ts)
  19. repo模型(repo-source.ts,repo-model.ts,指代-row.ts,对比-模型.ts,组件-s…
  20. 历史沿革 (历史沿革,历史沿革,历史沿革)
  21. 审计 @bridge-ds/core/audit (中文(简体) )
  22. 组件规格( e) component-spec.ts ,生成器在 @bridge-ds/core/node (中文(简…

@ bridge-ds/ core (中文(简体) )

Bridge的纯设计-托肯逻辑:负载 DTCG 2025.10 符号跨层,解决每个品牌的别名, 主题和密度, 请检查 WCAG 对比度, diff 三个版本的符号集, 编辑 *.tokens.json 文件 在不重排它们的情况下,构建牵引请求(body, risk level, changet)并与 GitHub 交谈.

主条目中没有 Figma API 、 没有 DOM 、 没有节点的 API( 节点助手居住) @bridge-ds/core/node: 它运行在 Figma 插件沙盒、 浏览器、 节点或 MCP 中 服务器。 DS Bridge Figma 插件 (apps/figma-plugin) 在其上; 一个 CLI 和一个 MCP 服务器可以是 我也一样。 这里没有硬码存储器: 呼叫者通过一个 BridgeConfig (通常情况) bridge.config.json) (中文(简体) ).

import { loadConfig, buildTokenSet, layoutOptions, validateSet, parseContrastChecks } from '@bridge-ds/core';

已出版的建造船舶ES模块和类型声明 dist/ (单位:千美元)npm run build:packages) (中文(简体) ). 里面这个 单曲 source 导出条件解决了 TypeScript 源, 所以不需要构建 先说 测试 : npx vitest run --project core (部分为根) npm test) (中文(简体) ). 类型检查 : npx tsc --noEmit -p packages/core。 。 。 .

等级

级别文件( 下) tokens.root(中文(简体) )模式5月别名
primitiveprimitives/*.tokens.json单身("value"(中文(简体) )原始人
brandbrands/<brand>.tokens.json每个品牌一个原始人
basesemantic/base.tokens.json单人原始人(允许的识字)
semanticsemantic/<theme>.tokens.json每个主题一个颜色 : palette.* (或 color.alpha.*其他:品牌角色或原始人
densitydensity/<density>.tokens.json一个密度原始人
componentcomponents/*.tokens.json单人语义、基础、密度、品牌角色、原始尺度步骤;从不调色板角色或原始颜色
覆盖brands/<brand>.<theme>.tokens.json品牌 x 主题与语义相同; 必须覆盖已存在的语义符号

配置

bridge.config.json 在寄存器根: 1 文件 和一个 schema ()packages/core/bridge.config.schema.json, (中文(简体) ), 也导出为 @bridge-ds/core/bridge.config.schema.json)用于插件、文件站点、CLI和MCP 服务器。 条形: repo, (中文(简体) ), tokens (单位:千美元)root, (中文(简体) ), include, (中文(简体) ), exclude, (中文(简体) ), tiers,命令 layers 与 {mode} 占位符和 optional, (中文(简体) ), modes (名称 - > { values, default, parity }, (中文(简体) ), contrast (单位:千美元)path, (中文(简体) ), modes, (中文(简体) ), components, (中文(简体) ), docs, (中文(简体) ), changesets, (中文(简体) ), cssVar, (中文(简体) ), governance (单位:千美元)protectedBranches, (中文(简体) ), branchPrefix, (中文(简体) ), labels, (中文(简体) ), guardrails, (中文(简体) ), owners: { design, tech }, (中文(简体) ), changes (单位:千美元)"suggest",默认值,或 "direct"和 storybook (单位:千美元){ url },https) (中文(简体) ). 较旧的平面形式(tokens.primitives, (中文(简体) ), modes.brands.)仍载.

const CONFIG_FILE = 'bridge.config.json';
interface BridgeConfig {
  repo: { owner; name; defaultBranch } | undefined;
  tokens: TokenPaths & { include; exclude; tiers: Record<string, string[]>; layers: { files; optional }[] };
  axes: Record<string, { values; default; parity }>;     // canonical modes
  modes: { brands; themes; densities; defaults };         // brand/theme/density view for the tier model
  contrast: { path; modes? } | undefined;
  components?: { dir; docsSuffix; styleSuffix; reference?; index? };
  docs; changesets: { dir; package } | undefined; changeset?: { package };
  cssVar: { prefix; separator };
  governance: { protectedBranches; branchPrefix; labels; guardrails; owners: { design: string[]; tech: string[] } };
  changes: 'suggest' | 'direct';                          // how changes reach the code (default 'suggest')
  storybook?: { url: string };
}
function defineConfig(input): BridgeConfig;   function loadConfig(source): BridgeConfig;   // ConfigError { problems }
function toConfigJson(config): object;        // canonical JSON (what `bridge init` writes)
function protectedBranchesOf(config); function baseBranchOf(config); function tokensPath(config, rel?);
function changesMode(config): 'suggest' | 'direct';   function storybookUrl(config): string | undefined; // storybook.url, else previews.production.storybook

施政

function assertSafeBranch(branch, { protectedBranches?, base?, branchPrefix? }): void;  // ProtectedBranchError
const DEFAULT_PROTECTED_BRANCHES = ['main', 'master'];

GitHub客户端和当地的git作家都称它:没有Bridge表面写给受保护的分支.

分层集(CLI和MCP)

new LayeredTokenSet(config, files: Map<relPath, text>);  // combos(), view(combo), resolve(path, combo), tierOf(path), cssVarName(path)
function validateLayered(set): LayerIssue[];              // DTCG shapes, names, aliases per combo, missing layers, mode parity
function runLayeredContrast(set, pairs, modes?); function contrastDelta(before, after);
function applyTokenEdits(set, edits: TokenEdit[]): { files; touched; notes };   // set, add, remove, rename; minimal diffs
function coerceValue(input, type?, existing?);            // "#ff5500", "12px", "150ms" -> the repo's DTCG form
function diffLayered(before, after); function layeredImpact(before, after, changes);
function classifyLayered(changes, otherFiles?, config?);  // classifyRisk underneath
function composeProposalBody(input); function changeTable(changes); function contrastDeltaTable(deltas);

@bridge-ds/core/node (仅节点): git, (中文(简体) ), isGitRepo, (中文(简体) ), currentBranch, (中文(简体) ), branchExists, (中文(简体) ), showFile, (中文(简体) ), listFilesAt, (中文(简体) ), originRepo, (中文(简体) ), commitToNewLocalBranch (在新分行上投放;工作树、指数和结账没有改变), fsSource(root, ref?) 财务报告和审定财务报表 localRepoRef(root) 联合国 RepoSource 在一次退票时,见repo模型.

类型

type Tier = 'primitive' | 'brand' | 'base' | 'semantic' | 'density' | 'component';
const TIER_ORDER: Tier[];                       // dependency order
const TIER_AXIS: Record<Tier, 'brand' | 'theme' | 'density' | undefined>;
const TIER_NAMES: Record<Tier, string>;         // "Primitives", "Brand", "Base", "Semantic", "Density", "Component"
const SINGLE_MODE = 'value';                    // mode key of single-mode tiers (alias PRIMITIVE_MODE)
interface LogicalToken { id; path; type; tier; values: Record<mode, unknown>; description; scopes; files: Record<mode, file> }
interface ThemeOverride { brand; theme; path; type; value; file }
interface RepoLayout { primitiveFiles; brands; baseFiles; themes; overrides; densities; componentFiles }
function isMultiMode(tier: Tier): boolean;
function modeDisplayName(mode: string): string; // "light" -> "Light"

json-ast和dtcg-codec(最小编辑)

保留格式的 JSON 解析器: 未激活的文件序列化字节为字节; 编辑过的符号保存密钥 顺序、缩进、内线或多行布局和数字拼写.

function parseJson(text: string): JsonDocument;
function serializeJson(doc: JsonDocument): string;
function parseTokenFile(file: string, text: string): TokenDocument;
function serializeTokenFile(doc: TokenDocument): string;
function flattenTokens(doc: TokenDocument): FlatToken[];              // $type inherited from groups
function readTokenAt(doc, path): FlatToken | undefined;
function upsertToken(doc, path, fields: { type; value; description; extensions? }, template?): boolean; // false when nothing changed
function removeToken(doc, path): boolean;                             // prunes empty groups
function moveToken(doc, from, to): boolean;                           // keeps every field
function emptyTokenFile(file): TokenDocument;

数值和范围

function isAlias(v): v is string;  function aliasTarget(v: string): string;  function toAlias(path): string;
function parseColor(v): Rgba | undefined;  function rgbaToDtcg(c: Rgba): object;  function rgbaToHex(c): string;
function parseDimension(v): { value: number; unit: string } | undefined;
function valuesEqual(type, a, b): boolean;    // colors by 8-bit hex + alpha, numbers to 1e-4
function formatValue(type, v): string;        // "palette.primary.600", "#4b5562", "16px"
function defaultScopes(path, type, tier): string[];   // Figma scopes inferred from path and type
function effectiveScopes(t): string[];

符号集( 装入量)

function buildTokenSet(files: Record<relPath, text>, options?: LayoutOptions): TokenSet;
function layoutOptions(config: BridgeConfig): LayoutOptions;           // tier folders + mode order from the config
function detectLayout(files: string[], options?: LayoutOptions): RepoLayout;
function modesOf(layout, tier): string[];        // ["bridge", "ocean"], ["light", "dark"], ["value"]...
function modeFile(layout, tier, mode): string | undefined;
function defaultFile(tier, path, dirs?): string; // where a new single-mode token goes
function defaultContext(set): ResolveContext;    // first brand, theme, density, with overrides
function contextFor(set, tier, mode): ResolveContext;
interface TokenSet { tokens; byPath; docs; layout; options; overrides: ThemeOverride[]; overrideIndex; problems: string[] }

解析器(跨层级的异名)

interface ResolveContext { brand?; theme?; density?; overrides?: Map<string, unknown> }
function resolve(index: Map<path, LogicalToken>, path, ctx): { value?; chain: string[]; via: ('token' | 'override')[]; error?: 'cycle' | 'broken' | 'missing-mode'; at? };
function valueIn(t: LogicalToken, ctx): { value; via };
function findReferenceProblems(index, axes: { brand?: string[]; theme?: string[]; density?: string[] }): ReferenceProblem[];

语义符号在上下文的"品牌x"主题有"一"时取出"一"的"一"字.

wcag (续)

const CONTRAST_CHECKS_FILE = 'contrast.checks.json';
function parseContrastChecks(text): ContrastPair[];   // { pairs: [[fg, bg, min], ...] }; kind = min >= 4.5 ? 'text' : 'ui'
function contrastScope(set): ContrastScope;           // every brand x theme, default density, overrides
function evaluatePairs(index, pairs, scope): ContrastResult[];  // { pair, brand, theme, ratio, level, error?, steps }
function contrastRatio(fg, bg): number;  function contrastLevel(ratio, kind, min?): 'AAA' | 'AA' | 'fail';
function renderedColor(v): Rgba | undefined;           // hex wins over components, like tokens.css
function contextLabel(r): string;                       // "Ocean dark"
function pairKey(r): string;

steps 列出两种颜色都解开的每个符号,这就是一个变化是如何找到对的 影响(见 affectedContrast) (中文(简体) ).

验证器(护栏)

function validateSet(set, pairs): { issues: Issue[]; contrast: ContrastResult[] };
function validateProposal(proposed, head, pairs, typeChanges?): { blocking; warnings; contrastBefore; contrastAfter };
function shadowedEdits(set, edits: { path; tier; modes }[]): Issue[];  // semantic edits a brand override hides
type IssueCode = 'file-problem' | 'raw-value' | 'alias-tier' | 'broken-reference' | 'alias-cycle' | 'all-scopes'
  | 'missing-mode' | 'override-orphan' | 'override-shadowed' | 'contrast' | 'contrast-unresolved' | 'type-change';

基础分支上已经存在的问题作为警告再次出现,所以只有变化会带出块.

id-map and diff-engine (三道diff) 互联网档案馆的存檔,存档日期2013-12-21

function threeWayDiff(base?: Map<id, LogicalToken>, edited: Map, head: Map): { local; remote; conflicts; unchanged };
function toMap(tokens): Map<id, LogicalToken>;
function fieldChanges(a, b): FieldChange[];
function reconcileIds(edited: LogicalToken[], git: LogicalToken[]): { tokens; adoptedByName; suggestions: RenameSuggestion[] };
function applyConfirmedRenames(tokens, confirmed): LogicalToken[];
function idExtensionFor(t): string | undefined;   // "com.dsbridge.id" only after a rename

作曲( 回写更改)

interface AcceptedChange { target?: LogicalToken; current?: LogicalToken }   // target undefined = remove
function composeFiles(head: TokenSet, originals: Record<relPath, text>, changes): { files; allFiles };

每个值都转到其分级和模式的文件;只返回已更改的文件.

风险

type RiskTier = 1 | 2 | 3;
function classifyRisk(input: { tokenChanges?; files?: { path; status? }[]; config? }): { tier; label; reasons: string[]; bump?: 'patch' | 'minor' | 'major' };
function tokenBump(changes); function isGuardrail(path, config?);
const RISK_LABELS: Record<RiskTier, string>;

插件的分类器,Docs站点,CLI和MCP服务器的分类器. 规则(从 docs/GOVERNANCE.md,最高胜负):第3级,用于任何已添加、已更改的令牌(价值、类型、范围)、更名或 在任何一级或任何一级被删除, *.tokens.json 文档,当其符号更改未知时,则守护符 文档(governance.guardrails对比检查, bridge.config.json, (中文(简体) ), .github/**) (中文(简体) ). 第二级组件 来源 components.dir 和未知源文件。 仅用于描述符号编辑的第1级, Docs, *.md故事, 说:, *.docs.json测试和更改。 弹出:清除和重命名 major,其他符号 变动 minor,仅说明 patch。鼠标更改可以是 AcceptedChanges 或 (简体中文) { kind, path, descriptionOnly? } 总结.

pr- 组合和更改

function composePrBody(input: { changes; head; proposed; validation; baseBranch; headSha; baseSha; origin: PrOrigin; title; notes; upstreamPaths; resolvedConflicts }): string;
interface PrOrigin { tool: string; surface: string; location?: string; authoredBy: string }
function affectedContrast(change, before: ContrastResult[], after: ContrastResult[]): { before?; after? }[];
function changedModes(change): Set<string> | undefined;
function defaultTitle(changes): string;  function branchName(slug, date): string;  function slugify(text, max?): string;
function commitMessage(title, changes, footer?): string;
function changesetBump(changes): 'minor' | 'major';
function composeChangeset(changes, { title, branch, packageName, source? }): { path; content };

主体有一个变化表(按下、分级、旧 - > 每个模式的新,对比度在 - > 之后),对比度 影响表、护栏清单和风险等级。 当一对已更改的符号 前景或背景在品牌x主题中直接或通过该符号或别名解决 使用已更改模式的地方(PR # 4回归: 正在更改) color.bg.default 列出其中的每一对.

github 客户端

new GitHubClient(repo: 'owner/name', token: string, fetchImpl?: FetchLike, retry?: RetryPolicy);
// refs and git data
getRepo(); getBranchSha(branch); getCommitTree(sha); getTree(treeSha, recursive?); getBlobText(sha);
createBlob(text); createTree(baseTree, files); createCommit(message, tree, parents); createBranch(name, sha); updateBranch(name, sha);
compare(base, head);
// contents API
getFileText(path, ref?): Promise<string | undefined>;  putFile({ path, content, branch, message, sha? }): Promise<commitSha>;
// pull requests, reviews, checks, labels
createPullRequest({ title, head, base, body, draft }); getPullRequest(n); findOpenPullRequest(branch); updatePullRequest(n, patch);
listPullRequestFiles(n); listReviews(n); createReview(n, { event, body });
listCheckRuns(ref); createCheckRun({ name, headSha, status?, conclusion?, output? });   // check runs need a GitHub App token
addLabels(n, labels); removeLabel(n, label); addComment(n, body);
// whole token set at a commit, honoring bridge.config.json in the repo
loadRepoFiles(client, commitSha, fallbackTokensPath): Promise<{ files; contrastChecks; config?; tokensPath; warnings }>;

读取和内容地址重试网络错误, 5xx和二次费率限制; 错误 变成 GitHubError { status, message, detail } 有简单语言的信息.

建议(建议t、建议审查t、建议github.ts)

作为 GitHub 问题而不是分支存档的更改,所以所有者只需写出问题 。 可读 Markdown, 然后是 a jSON 载荷bridge.suggestion/1以标记表示其犬形的sha256;符号变化是 编辑(路径和值),其他文件全部内容,前后使用 git blob shas 。 不适合的内容 主体(65,536个字符)到继续评论,最多8个。 评论是与有效载荷sha绑定的 并且只从指定的所有者中计数.

composeSuggestionIssue(payload, { labels?, assignees?, state?, details? }): { title; body; labels; assignees; parts: string[]; sha };
parseSuggestionIssue(body, { comments?, author? }): { ok: true; payload; sha; markedSha; edited; parts } | { ok: false; reason; message };
suggestionPayloadSha(payload); canonicalJson(value); sha256Hex(text); gitBlobSha(text);
suggestionLabels(payload, { state?, labels? }); suggestionIssueTitle(payload); suggestionStatus({ state, stateReason?, linkedPrs?, review?, applied?, outdated? });
suggestionPathProblems(payload, config): string[];    unsafePathProblem(path): string | null;
summarizeSuggestionApprovals(comments, { owners, rights?, teams?, soloOwnerCanApproveBoth? }, { payloadSha, author? }); suggestionReviewState(tier, approvals);
composeSuggestionReviewComment(record); parseSuggestionReviewComment(body); composeSuggestionAppliedComment(record); parseSuggestionAppliedComment(body);
// GitHub (Issues read and write only)
createSuggestionOnGitHub(gh, payload, opts); listSuggestionsOnGitHub(gh, { state? }); getSuggestionOnGitHub(gh, n, gov, { outdated? });
reviewSuggestionOnGitHub(gh, n, { event, role?, message?, payloadSha? }, gov); linkSuggestionPrOnGitHub(gh, n, { pr?, branch?, commit?, payloadSha });
declineSuggestionOnGitHub(gh, n, reason, by?); syncSuggestionStateLabel(gh, n, labels, status);

故事书(故事书.ts)

读取一个已部署或已建的故事书,而无需重写: index.json (v4为"故事集"7,v5为"8"并后作"),其他 stories.json (v3) (英语). 条目按标题归类为组件( name = 最后一个标题段); 测试条目退出 联 合 国 stories。一个404,一个HTML的回答,来自一个返回到 index.html,或者没有条目的天体移动到 下一个文件。 错误带有代码 : invalid-url, (中文(简体) ), not-found, (中文(简体) ), not-json, (中文(简体) ), private (署名墙壁,色谱登录) 答复,第401/403号, empty, (中文(简体) ), http, (中文(简体) ), network。纯净,注射 fetch· ; @bridge-ds/visual 使用解析器 storybook-static/index.json 和用于捕获的 iframe URL 构建器.

fetchStorybookIndex(base, { fetch?, signal? }): Promise<{ version; source: 'index.json' | 'stories.json'; entries; components }>;
parseStorybookIndex(json, source?); groupStorybookComponents(entries): { title; name; group; stories; docs; tags }[];
normalizeStorybookUrl(pasted): string;   // https only (http on localhost), drops ?path=, /index.html, /iframe.html
storybookIframeUrl(base, id, { viewMode?, globals?, args? }); storybookManagerUrl(base, id, viewMode?); storybookIndexUrls(base);

repo模型(repo-source.ts,repo-model.ts,指代-row.ts,对比-模型.ts,组件-scan.ts)

所有文件网站和工作室 从一个设计系统检索到的 RepoSource因此,建筑(当地建筑) 取出)和浏览器(任何团队在GitHub上的回放)运行相同的代码. bridge.config.json 解析一次; 每 文件夹来自它( e)tokens.root 和分级的文件夹, contrast.path, (中文(简体) ), components.dir|index|specs, (中文(简体) ), tokens.usage),以此repo的前路径作为默认路径(REPO_MODEL_DEFAULTS) (中文(简体) ). Repo 内容从未丢出: 不好 配置、 docs.json 或别名, 或一个文件, 来源拒绝作为太大的 (413), 降落在 problems; 利率限制或 网络出错仍会丢出,以便调用者可以重试.

interface RepoSource { ref: { owner; repo; sha }; list(prefix?): Promise<string[]>; text(path): Promise<string | null> }
memorySource(files, ref?); readRepoTexts(source, paths, concurrency?, onError?);   // fsSource(root, ref?) in @bridge-ds/core/node
// gitHubSource(client, sha, opts?) (repo-source-github.ts) is the same RepoSource over GitHub; every list() is sorted.
loadRepoModel(source, { components?, href?, concurrency? }): Promise<RepoModel>;
// RepoModel: { ref, configText, config, site: SiteRepo, problems, tokens: { root, files, rows, usage },
//              contrast: { path, specs, pairs }, components: { dir, index, families, list } | null, specs: { path, file, coverage } }
siteRepoFromConfig(config, raw?, fallback?); parseModelConfig(text);
buildTokenRows(config, readText, listFiles); tokenRowIndex(rows); tokenRowAxes(config, readText?); tokenRowFiles(config);
parseContrastSpecs(text); evaluateContrastPairs(specs, rows); hexContrastRatio(a, b);
scanComponents(input); parseComponentTsx(name, src); parseComponentCss(src, labels, describeVar);
parseComponentStories(src); parseComponentFamilies(indexSrc, componentsRel?); resolveInheritedTokens(list);

历史沿革 (历史沿革,历史沿革,历史沿革)

代号上的变化,何时,谁改变了,为什么,如何安全地解除.

// model
interface HistoryEntry { id; sha; baseSha?; date; author; title; why; pr?; changes: LayeredChange[]; counts; tier; bump; breaking; reasons; changesets; version?; bulk?; demo? }
function buildHistoryEntry({ config, commit, before, after, changesets? }): HistoryEntry | null;
function collectHistory(config, backend: HistoryBackend, { ref, limit }): Promise<HistoryEntry[]>;
// backends: GitHub REST (browser or Node) and local git (Node, @bridge-ds/core/node)
function gitHubHistoryBackend(client, config); function loadGitHubHistory(client, config, { ref?, limit? }): Promise<HistoryReport>;
function localGitHistoryBackend(root, config); function loadLocalHistory(root, config, { ref?, limit? }): Promise<HistoryReport>;
// versions: CHANGELOG sections and tags; the timeline of design system versions
function parseChangelog(text); function releasesFromTags(tags, pkg?); function assignVersions(entries, releases); function versionTimeline(entries, releases?);
// reading
function filterHistory(entries, { token?, author?, tier?, version?, breaking?, since?, until?, query? });
function tokenHistory(entries, path, config?): TokenHistoryItem[];   // every change of one token, renames followed
function fileModes(config, file); function modeLabel(modes);            // semantic/dark.tokens.json -> { theme: "dark" } -> "Dark"
// planning (never writes)
function planRevert({ current, entry, later?, pairs?, resolutions? }): ChangePlan;
function planRestore({ current, path, file?, value, label?, item?, pairs? }): ChangePlan;
function planToJson(plan);                                             // a patch-like JSON for people without a token
function demoHistory(config, currentFiles): HistoryReport;             // fixture entries, flagged demo, never real

本地历史跟随裁判的第一个父,所以合并的分支是一条目(合并承诺针对 gitHub 历史向每个承诺询问其拉动请求,并显示 PR 的合并承诺. 批量条目(超过60个令牌更改:导入或重组)被标记.

归来不是瞎子 git revert。 。 。 . planRevert 根据当前基准计算反向符号编辑 分支 : 后期再次更改的符号( s)changed-later页:1removed-later回来 (单位:千美元)recreated-later),移动(renamed-later)或者其他代名词(still-referenced是一种冲突, 与后面的改动一起列出,这些改动解释并保持原样,除非 resolutions[key] 实值 "use-before"。 。 。 . 已撤销的更改被跳过 。 剩下的都过去了 applyTokenEdits (最小diffs),验证 对比门, classifyRisk 和任何提议一样 status 实值 ready, (中文(简体) ), blocked (新设) 验证错误或失败的对比对)或 nothing-to-do。公关机构从“Reverts #n”开始 冲突表.

审计@bridge-ds/core/audit(中文(简体) )

设计系统采用并漂移在一个消耗DS的产品编码库中. 纯 (文件文本输入, 报告) 它读取 TSX/JSX, 以及Astro、 Vue 和 Svelte 文件的前题和脚本, 有 TypeScript 编译器 API(只使用语法),这就是为什么它是自己的条目,而Figma插件从不加载它. @bridge-ds/core/node 添加磁盘侧.

import { DesignSystemIndex, buildAuditReport, compareWithBaseline, auditMarkdown, planCssFixes, auditFile } from '@bridge-ds/core/audit';
import { loadDesignSystem, runAudit, collectAuditFiles, fixCss, findDesignSystemRoot, loadAllowlist } from '@bridge-ds/core/node';

const ds = loadDesignSystem('/path/to/ds-repo');               // bridge.config.json: tokens in every mode, components, packages
const report = runAudit('apps/admin/src', { ds: ds.root, label: 'admin', baseline });  // AuditReport, schemaVersion 1
  • 扫描: CSS、SCSS、减分CSS模块; style,毛里求斯 sx, (中文(简体) ), styled(), (中文(简体) ), makeStyles, (中文(简体) ), createTheme 和主题 对象, 有样式的组件/ 情感模板; Tailwind类字符串(className, (中文(简体) ), cn(), (中文(简体) ), clsx(), (中文(简体) ), cva(), (中文(简体) ), @apply); 代码中的任何颜色文字. Astro、Vue和Svelte文件:前题和 <script> 块为 TS, (中文(简体) ), <style> 块作为 CSS/SCSS/Less,以及模板标记(tags, style 财务报告和审定财务报表 class 属性,静态 style="...", (中文(简体) ), style={{ ... }}单 :style,斯维尔特 style:prop,颜色属性,例如 fill="#...") (中文(简体) ).
  • 硬码值: 颜色(hex, rgb, hsl, 命名, 赤裸 HSL 通道), 间隔, 大小, 弧度, 边框宽度, 影相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相 每个都得到最接近的标志: 在 OKLab 中以 deltaE 为单位的颜色, 跨越每个模式( 符合属性的语义符号和符号赢得了近五十个), 长度按最接近的尺度级,并带有置信度(exact, (中文(简体) ), high, (中文(简体) ), medium, (中文(简体) ), low) (中文(简体) ).
  • 调用引用数字 : var(--x) 的 DS 符号( 也用 Tailwind 任意值)。 其他变量, MUI 调色板 路径, theme.spacing() 和 Tailwind Stale 类算作对另一个主题的引用,而不是硬码.
  • 构成部分: 从DS包中导入的JSX实例(audit.packages,默认值: components.dir附加时 @bridge-ds/react对外国UI库(MUI,反应-admin,Atd,Chakra,Radix, 无头UI,Mantine,Shadcn/ui本地组件.),应该为DS组件的本地组件 (单位:千美元)button, (中文(简体) ), input, (中文(简体) ), select, (中文(简体) ), textarea, (中文(简体) ), dialog, (中文(简体) ), table, (中文(简体) ), a 与 href, (中文(简体) ), img),路由器链接(反应-路由器, 半径 LinkBase,下个/链接),除非作为DS组件通过 render 元素,图表库(目录, Nivo, Chart.js.: 外相而无DS等同)和以DS组件命名的本地组件. 供应商和 其他非视觉部分从不计数,包括DS部分。 在Astro、Vue和Svelte模板中,标签是一个DS组件 当前题或 <script> 从DS软件包中导入( Vue kebab 例) <ds-button> 包括);当地 Button.astro, (中文(简体) ), Button.vue 或者说 Button.svelte 是重新创建的 DS 组件. <input type="hidden">,锚 无 href 里面的东西 <noscript> 非UI 实例.
  • 逃生舱数字 : bridge-audit-ignore-next-line: reason 在任何评论中<!-- -->, (中文(简体) ), {/* */}, (中文(简体) ), /* */, (中文(简体) ), //)将下行的定论从计数中留出. 需要说明理由:没有理由,或 下一行没有找到, 没有忽略任何东西, 文件将它列在下面 ignoreErrors许可列表 (单位:千美元)runAudit(..., { allowlist: loadAllowlist(path) }), (中文(简体) ), { "entries": [{ "file", "line", "what"?, "reason" }] }已经 对已知文件的相同: 线性违规。 被忽略的项目保留在报表中( E)files[].ignored, (中文(简体) ), ignored.items, (中文(简体) ), ; 无匹配的允许列表条目在 ignored.staleAllowlist。 。 。 .
  • 计量: 符号采纳 = 符号引用 / (收录引用 + 硬码值); 组件采纳 = DS 实例 / 所有UI 实例 。 按类别,顶部文件,顶部修正,每个文件的发现有行号.
  • 基线数字 : compareWithBaseline(report, previous) 每公吨、类别和文件增加三角洲,并携带 历史. auditMarkdown(report) 作总结. planCssFixes(text, lang, ds) 是安全的自定义 : CSS 值等于一个符号 var(--token)。 。 。 .

报告计划是 packages/core/audit-report.schema.json (也导出为 @bridge-ds/core/audit-report.schema.json) (中文(简体) ). bridge.config.json 选择 audit 节: packages, (中文(简体) ), foreignLibraries, (中文(简体) ), nativeElements, (中文(简体) ), exclude。 。 。 .

组件规格( e)component-spec.ts,生成器在 @bridge-ds/core/node(中文(简体) )

对设计工具可以重建的编码组件的宣告性描述:可变轴,TEXT和BOOLEAN 属性、部件(框架、文本、带有自动布局的图标)以及每个变体,每个填充、中键、, 半径、 粘贴、 间隙、 大小和文本属性 。 DS Bridge Figma 插件将它牵引为组件集绑定在变量上.

import { parseComponentSpecs, variantKeyOf, type ComponentSpec } from '@bridge-ds/core';
import { generateRepoComponentSpecs, serializeComponentSpecs } from '@bridge-ds/core/node';

const file = generateRepoComponentSpecs('/path/to/repo', ['Button']); // reads bridge.config.json, tokens, TSX, CSS modules

从代码中衍生出来,从未手持: npm run specs 写入 packages/react/component-specs.json (路径 : components.specs 在图文中,和 packages/core/test/component-specs.test.ts 过期时失败 . 生成器使用 TypeScript 解析器读取组件( props 接口, 默认, 它返回给定的 JSX) 道具,象图标等嵌入式DS组件并运行一个小型CSS级联(spec-css.ts: 类,属性, :hover, (中文(简体) ), :active, (中文(简体) ), :not(), (中文(简体) ), :has()组合器, @media (hover: hover),特异性,继承,风俗财产). 改变样式的联盟道具成为轴; a State 轴列表显示的状态( Hover、 按住、 已禁用) 不一样 非符号值( A)calc()它不抽取的道具和道具列于 unmapped。 。 。 .

可移动部件携带a swap (INSTANCE SWAP 属性名称,默认组件,选项)和每个变体列出 显示于 slots数字 :

  • 图标部件LucideIcon 道具)默认图标预览文件,然后是 AllStates 故事,传到 道具(else Plus,用于徽章的信息). 档案 icons 区域持有 24x24 SVG (stroke="currentColor"(中文(简体) ) 每个图标的插槽默认,每个图标组件的文档和故事参考,以及一个通用的集 (单位:千美元)COMMON_ICONS),从安装中读取 lucide-react;一个Lucide图标的别名会折叠成所见的第一个名字. iconStyle 命名图标组件本身的符号(大小、中风颜色、中风宽度).
  • 复合部分的文本, 代码在某个变体中画出全血( 无内嵌活字: 卡 padding="none"是一个 内容槽 : Slot/<Component> <part> text 或者说 Slot/Media媒体的血流成河 这个 slots 节 描述两个组件.

版本与发布记录

@bridge-ds/core 共发布 38 个版本,首次发布于 2026/10/18;过去 12 个月发布了 38 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.29.0latest2026/11/08今天
0.28.02026/11/035 天前
0.27.32026/11/036 天前
0.27.22026/11/026 天前
0.27.12026/11/026 天前
0.27.02026/11/026 天前

关于 @bridge-ds/core 的常见问题

@bridge-ds/core 是什么?

Bridge Core: bridge.config.json, DTCG 令牌加载(等级和分层模式),别名分辨率,WCAG对比,diffs,最小-diff编辑,PR正文,共享风险等级分级器,更改ets和一个基于取回的GitHub客户端. 无 Figma API, 无 DOM; 节点连接

如何安装 @bridge-ds/core?

在项目目录运行 npm install @bridge-ds/core,或使用 pnpm add / yarn add / bun add。

@bridge-ds/core 支持 TypeScript 吗?

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

@bridge-ds/core 支持 ESM 还是 CommonJS?

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

@bridge-ds/core 可以商用吗?

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

@bridge-ds/core 的下载量有多少?

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

@bridge-ds/core 还在维护吗?

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