feat(bgm): support role= on code block info strings

Parse role.type#id from the fence info string and merge it into each
parsed object, erroring on conflicts with the content. id on the info
string can't combine with $variants. Auto-named blocks now hash their
content instead of the info string, so identical blocks dedupe.
This commit is contained in:
2026-08-10 16:09:12 +08:00
parent c41c266ac1
commit aab0b66ee8
7 changed files with 207 additions and 10 deletions
+6 -2
View File
@@ -21,6 +21,7 @@ import { validatePackage, validatePart, validateSetup, validateSurface } from '.
import { expandVariants } from './variants.js';
import {
BgmError,
ROLES,
type DefFile,
type ParsedDef,
type Package,
@@ -31,8 +32,6 @@ import {
type Surface,
} from './types.js';
const ROLES = new Set<Role>(['package', 'part', 'surface', 'setup']);
/** Every definition parsed from a def file, keyed by its path-style name. */
export interface DefMap {
/** All def files (real + virtual), keyed by name. */
@@ -174,6 +173,11 @@ class PackageAcc {
}
private add(role: Role, def: ParsedDef, fileName: string) {
// `id` on the info string can't combine with `$variants`, since every
// row supplies its own `id` and would override it.
if (def.role?.id && '$variants' in def.value) {
throw new BgmError(`id on the info string can't combine with $variants`, fileName);
}
const expanded = this.expand(def.value, def.file, def.source);
for (const obj of expanded) {
switch (role) {