@bridge-ds/core 0.12.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1039,6 +1039,19 @@ function approverEntries(owners, rights) {
1039
1039
  if (!rights) return { design: [...owners.design], tech: [...owners.tech] };
1040
1040
  return { design: holdersOf("approveDesign", owners, rights), tech: holdersOf("approveTech", owners, rights) };
1041
1041
  }
1042
+ function soloApprover(owners) {
1043
+ const d = [...new Set(owners.design.map(norm))];
1044
+ const t = [...new Set(owners.tech.map(norm))];
1045
+ if (d.length !== 1 || t.length !== 1 || d[0] !== t[0] || !d[0] || d[0].includes("/")) return null;
1046
+ return d[0];
1047
+ }
1048
+ function soloOwnerOf(gov, teams) {
1049
+ if (!gov.soloOwnerCanApproveBoth) return null;
1050
+ return soloApprover(approverLists(gov.owners, gov.rights ?? null, teams));
1051
+ }
1052
+ function soloOwnerSentence(login, you = false) {
1053
+ return you ? "As the only owner, your approval covers design and code." : `As the only owner, @${norm(login)} approves design and code in one review.`;
1054
+ }
1042
1055
  function shipPolicy(owners, rights, teams) {
1043
1056
  if (!rights) return null;
1044
1057
  const entries = holdersOf("ship", owners, rights);
@@ -1196,7 +1209,7 @@ const DEFAULT_GOVERNANCE = {
1196
1209
  owners: { design: [], tech: [] }
1197
1210
  };
1198
1211
  const FLAT_TOKEN_KEYS = ["primitives", "brands", "semantic", "base", "density", "components", "contrastChecks"];
1199
- const CANONICAL_TOKEN_KEYS = ["root", "include", "exclude", "tiers", "layers"];
1212
+ const CANONICAL_TOKEN_KEYS = ["root", "include", "exclude", "tiers", "layers", "usage"];
1200
1213
  const FLAT_MODE_KEYS = ["brands", "themes", "densities", "defaults"];
1201
1214
  const AXIS_OF = { brands: "brand", themes: "theme", densities: "density" };
1202
1215
  class ConfigError extends Error {
@@ -1284,7 +1297,7 @@ function defineConfig(input) {
1284
1297
  const contrastFile = contrastPath ?? [root === "." ? "" : root, paths.contrastChecks].filter(Boolean).join("/");
1285
1298
  return {
1286
1299
  repo: parseRepoInput(input.repo, input.branch),
1287
- tokens: { ...paths, include: input.tokens?.include ?? ["**/*.tokens.json"], exclude: input.tokens?.exclude ?? [], tiers, layers },
1300
+ tokens: { ...paths, include: input.tokens?.include ?? ["**/*.tokens.json"], exclude: input.tokens?.exclude ?? [], tiers, layers, ...t.usage ? { usage: trimSlashes(t.usage) } : {} },
1288
1301
  axes,
1289
1302
  modes,
1290
1303
  contrast: { path: contrastFile, modes: input.contrast?.modes },
@@ -1313,11 +1326,13 @@ function defineConfig(input) {
1313
1326
  minReasonLength: g.override.minReasonLength ?? DEFAULT_OVERRIDE.minReasonLength
1314
1327
  }
1315
1328
  } : {},
1316
- ...g.rights ? { rights: normalizeRights(g.rights) } : {}
1329
+ ...g.rights ? { rights: normalizeRights(g.rights) } : {},
1330
+ ...g.soloOwnerCanApproveBoth === true ? { soloOwnerCanApproveBoth: true } : {}
1317
1331
  },
1318
1332
  products: input.products?.length ? input.products.map((p) => ({ ...p })) : DEFAULT_PRODUCTS.map((p) => ({ ...p })),
1319
1333
  changes: input.changes === "direct" ? "direct" : DEFAULT_CHANGES_MODE,
1320
1334
  ...input.storybook?.url ? { storybook: { url: input.storybook.url.trim().replace(/\/+$/, "") } } : {},
1335
+ ...input.library?.public === true ? { library: { public: true } } : {},
1321
1336
  ...input.audit ? { audit: { ...input.audit } } : {},
1322
1337
  ...input.visualImpact ? { visualImpact: { mode: input.visualImpact.mode === "on-demand" ? "on-demand" : "auto" } } : {},
1323
1338
  ...input.integrations ? { integrations: { ...input.integrations } } : {},
@@ -1362,7 +1377,7 @@ function loadConfig(source) {
1362
1377
  if (!isObj(tokens)) problems.push('"tokens" must be an object');
1363
1378
  else
1364
1379
  for (const [k, v] of Object.entries(tokens)) {
1365
- if (FLAT_TOKEN_KEYS.includes(k) || k === "root") {
1380
+ if (FLAT_TOKEN_KEYS.includes(k) || k === "root" || k === "usage") {
1366
1381
  if (!isStr(v)) problems.push(`"tokens.${k}" must be a non-empty string`);
1367
1382
  } else if (k === "include" || k === "exclude") {
1368
1383
  if (!isStrList(v)) problems.push(`"tokens.${k}" must be a list of globs`);
@@ -1437,6 +1452,7 @@ function loadConfig(source) {
1437
1452
  }
1438
1453
  }
1439
1454
  problems.push(...rightsProblems(gov.rights));
1455
+ if (gov.soloOwnerCanApproveBoth !== void 0 && typeof gov.soloOwnerCanApproveBoth !== "boolean") problems.push('"governance.soloOwnerCanApproveBoth" must be true or false');
1440
1456
  }
1441
1457
  }
1442
1458
  problems.push(...visualImpactProblems(d.visualImpact));
@@ -1447,6 +1463,14 @@ function loadConfig(source) {
1447
1463
  else if (!/^https:\/\/[^\s/]+/.test(sb.url.trim())) problems.push('"storybook.url" must start with https://, for example https://storybook.example.com');
1448
1464
  else for (const k of Object.keys(sb)) if (k !== "url") problems.push(`"storybook.${k}" is not a known key`);
1449
1465
  }
1466
+ const lib = d.library;
1467
+ if (lib !== void 0) {
1468
+ if (!isObj(lib)) problems.push('"library" must be an object, for example { "public": true }');
1469
+ else {
1470
+ if (lib.public !== void 0 && typeof lib.public !== "boolean") problems.push('"library.public" must be true or false');
1471
+ for (const k of Object.keys(lib)) if (k !== "public") problems.push(`"library.${k}" is not a known key`);
1472
+ }
1473
+ }
1450
1474
  problems.push(...productProblems(d.products));
1451
1475
  const audit = d.audit;
1452
1476
  if (audit !== void 0) {
@@ -1486,12 +1510,13 @@ function storybookUrl(config) {
1486
1510
  const prod = config?.previews?.production?.storybook?.trim();
1487
1511
  return prod && /^https:\/\//.test(prod) && !/\{\w+\}/.test(prod) ? prod.replace(/\/+$/, "") : void 0;
1488
1512
  }
1513
+ const libraryIsPublic = (config) => config?.library?.public === true;
1489
1514
  function toConfigJson(config, schema = "./packages/core/bridge.config.schema.json") {
1490
1515
  return {
1491
1516
  $schema: schema,
1492
1517
  version: 1,
1493
1518
  ...config.repo ? { repo: config.repo } : {},
1494
- tokens: { root: config.tokens.root, include: config.tokens.include, ...config.tokens.exclude.length ? { exclude: config.tokens.exclude } : {}, tiers: config.tokens.tiers, layers: config.tokens.layers.map((l) => l.optional ? l : { files: l.files }) },
1519
+ tokens: { root: config.tokens.root, include: config.tokens.include, ...config.tokens.exclude.length ? { exclude: config.tokens.exclude } : {}, tiers: config.tokens.tiers, layers: config.tokens.layers.map((l) => l.optional ? l : { files: l.files }), ...config.tokens.usage ? { usage: config.tokens.usage } : {} },
1495
1520
  modes: Object.fromEntries(Object.entries(config.axes).map(([k, a]) => [k, a.parity ? a : { values: a.values, default: a.default }])),
1496
1521
  ...config.contrast ? { contrast: config.contrast.modes ? config.contrast : { path: config.contrast.path } } : {},
1497
1522
  ...config.components ? { components: Object.fromEntries(Object.entries(config.components).filter(([, v]) => v !== void 0)) } : {},
@@ -1504,6 +1529,7 @@ function toConfigJson(config, schema = "./packages/core/bridge.config.schema.jso
1504
1529
  ...config.visualImpact ? { visualImpact: config.visualImpact } : {},
1505
1530
  changes: changesMode(config),
1506
1531
  ...config.storybook ? { storybook: config.storybook } : {},
1532
+ ...config.library ? { library: config.library } : {},
1507
1533
  ...config.products && !sameProducts(config.products, DEFAULT_PRODUCTS) ? { products: config.products } : {}
1508
1534
  };
1509
1535
  }
@@ -2924,7 +2950,7 @@ export {
2924
2950
  previewsSettled as Z,
2925
2951
  DEFAULT_TOKEN_PATHS as _,
2926
2952
  proposedTokenPath as a,
2927
- contextFor as a$,
2953
+ composite as a$,
2928
2954
  buildTokenSet as a0,
2929
2955
  readPreviewComment as a1,
2930
2956
  linkStatus as a2,
@@ -2935,98 +2961,98 @@ export {
2935
2961
  withNeededBy as a7,
2936
2962
  withLink as a8,
2937
2963
  withPiecesRecord as a9,
2938
- RIGHTS as aA,
2939
- RIGHT_LABEL as aB,
2940
- RISK_TIER as aC,
2941
- TIER_ORDER as aD,
2942
- TeamDirectory as aE,
2943
- VISUAL_CHECK_LABEL as aF,
2944
- affectedContrast as aG,
2945
- aliasOf as aH,
2946
- appForProject as aI,
2947
- appUrl as aJ,
2948
- approverEntries as aK,
2949
- approverLists as aL,
2950
- baseBranchOf as aM,
2951
- branchName as aN,
2952
- branchSlug as aO,
2953
- canShip as aP,
2954
- changeKind as aQ,
2955
- changedModes as aR,
2956
- changesMode as aS,
2957
- clearRawDeep as aT,
2958
- colorToCss as aU,
2959
- colorsEqual as aV,
2960
- comboKey as aW,
2961
- commitMessage as aX,
2962
- compactJson as aY,
2963
- composePrBody as aZ,
2964
- composite as a_,
2964
+ PRODUCT_LABEL_PREFIX as aA,
2965
+ RIGHTS as aB,
2966
+ RIGHT_LABEL as aC,
2967
+ RISK_TIER as aD,
2968
+ TIER_ORDER as aE,
2969
+ TeamDirectory as aF,
2970
+ VISUAL_CHECK_LABEL as aG,
2971
+ affectedContrast as aH,
2972
+ aliasOf as aI,
2973
+ appForProject as aJ,
2974
+ appUrl as aK,
2975
+ approverEntries as aL,
2976
+ approverLists as aM,
2977
+ baseBranchOf as aN,
2978
+ branchName as aO,
2979
+ branchSlug as aP,
2980
+ canShip as aQ,
2981
+ changeKind as aR,
2982
+ changedModes as aS,
2983
+ changesMode as aT,
2984
+ clearRawDeep as aU,
2985
+ colorToCss as aV,
2986
+ colorsEqual as aW,
2987
+ comboKey as aX,
2988
+ commitMessage as aY,
2989
+ compactJson as aZ,
2990
+ composePrBody as a_,
2965
2991
  productBranchSentence as aa,
2966
2992
  mergePiecesRecord as ab,
2967
2993
  productOfBranch as ac,
2968
2994
  defaultProduct as ad,
2969
2995
  slugify as ae,
2970
- AAA_MIN as af,
2971
- AA_MIN as ag,
2972
- CHANGES_MODES as ah,
2973
- CONTRAST_CELL_MAX as ai,
2974
- CONTRAST_CHECKS_FILE as aj,
2975
- ConfigError as ak,
2976
- DEFAULT_CHANGES_MODE as al,
2977
- DEFAULT_GOVERNANCE as am,
2978
- DEFAULT_OVERRIDE as an,
2979
- DEFAULT_PRODUCTS as ao,
2980
- DEFAULT_RIGHTS as ap,
2981
- DEFAULT_VISUAL_IMPACT as aq,
2982
- DTCG_TYPES as ar,
2983
- JsonParseError as as,
2984
- LINK_STATUS_TONE as at,
2985
- OWNER_GROUPS as au,
2986
- PREVIEW_APP_LABELS as av,
2987
- PREVIEW_COMMENT_MARKER as aw,
2988
- PREVIEW_PLACEHOLDERS as ax,
2989
- PRIMITIVE_MODE as ay,
2990
- PRODUCT_LABEL_PREFIX as az,
2996
+ defineConfig as af,
2997
+ ConfigError as ag,
2998
+ DEFAULT_CHANGES_MODE as ah,
2999
+ DEFAULT_OVERRIDE as ai,
3000
+ DEFAULT_PRODUCTS as aj,
3001
+ AAA_MIN as ak,
3002
+ AA_MIN as al,
3003
+ CHANGES_MODES as am,
3004
+ CONTRAST_CELL_MAX as an,
3005
+ CONTRAST_CHECKS_FILE as ao,
3006
+ DEFAULT_GOVERNANCE as ap,
3007
+ DEFAULT_RIGHTS as aq,
3008
+ DEFAULT_VISUAL_IMPACT as ar,
3009
+ DTCG_TYPES as as,
3010
+ JsonParseError as at,
3011
+ LINK_STATUS_TONE as au,
3012
+ OWNER_GROUPS as av,
3013
+ PREVIEW_APP_LABELS as aw,
3014
+ PREVIEW_COMMENT_MARKER as ax,
3015
+ PREVIEW_PLACEHOLDERS as ay,
3016
+ PRIMITIVE_MODE as az,
2991
3017
  modesOf as b,
2992
- sameProducts as b$,
2993
- contrastLevel as b0,
2994
- contrastPair as b1,
2995
- contrastRatio as b2,
2996
- defaultContext as b3,
2997
- defaultTitle as b4,
2998
- defineConfig as b5,
3018
+ rightsProblems as b$,
3019
+ contextFor as b0,
3020
+ contrastLevel as b1,
3021
+ contrastPair as b2,
3022
+ contrastRatio as b3,
3023
+ defaultContext as b4,
3024
+ defaultTitle as b5,
2999
3025
  detectLayout as b6,
3000
3026
  entriesFor as b7,
3001
3027
  entryLabel as b8,
3002
3028
  expandEntries as b9,
3003
- nearestQuestion as bA,
3004
- neededBySection as bB,
3005
- nodesEqual as bC,
3006
- normalizeRights as bD,
3007
- overrideKey as bE,
3008
- ownerEntryProblems as bF,
3009
- pairKey as bG,
3010
- parseDimension as bH,
3011
- parseJson as bI,
3012
- parseNeededBy as bJ,
3013
- parseOwnerEntry as bK,
3014
- parseVercelComment as bL,
3015
- piecesSection as bM,
3016
- plainEqual as bN,
3017
- previewComment as bO,
3018
- previewLinksOf as bP,
3019
- previewUrl as bQ,
3020
- productForPlace as bR,
3021
- productLabel as bS,
3022
- productMarks as bT,
3023
- productProblems as bU,
3024
- productsOf as bV,
3025
- projectOfLabel as bW,
3026
- protectedBranchesOf as bX,
3027
- renderedColor as bY,
3028
- rgbaToDtcg as bZ,
3029
- rightsProblems as b_,
3029
+ luminance as bA,
3030
+ nearestQuestion as bB,
3031
+ neededBySection as bC,
3032
+ nodesEqual as bD,
3033
+ normalizeRights as bE,
3034
+ overrideKey as bF,
3035
+ ownerEntryProblems as bG,
3036
+ pairKey as bH,
3037
+ parseDimension as bI,
3038
+ parseJson as bJ,
3039
+ parseNeededBy as bK,
3040
+ parseOwnerEntry as bL,
3041
+ parseVercelComment as bM,
3042
+ piecesSection as bN,
3043
+ plainEqual as bO,
3044
+ previewComment as bP,
3045
+ previewLinksOf as bQ,
3046
+ previewUrl as bR,
3047
+ productForPlace as bS,
3048
+ productLabel as bT,
3049
+ productMarks as bU,
3050
+ productProblems as bV,
3051
+ productsOf as bW,
3052
+ projectOfLabel as bX,
3053
+ protectedBranchesOf as bY,
3054
+ renderedColor as bZ,
3055
+ rgbaToDtcg as b_,
3030
3056
  expandOwners as ba,
3031
3057
  fieldChanges as bb,
3032
3058
  findProduct as bc,
@@ -3052,33 +3078,37 @@ export {
3052
3078
  isVercelComment as bw,
3053
3079
  kindForMin as bx,
3054
3080
  layeredParityIssues as by,
3055
- luminance as bz,
3081
+ libraryIsPublic as bz,
3056
3082
  TIER_AXIS as c,
3057
- sameToken as c0,
3058
- serializeJson as c1,
3059
- shipPolicy as c2,
3060
- snapshotUrl as c3,
3061
- storybookUrl as c4,
3062
- suggestNearestComment as c5,
3063
- summarizeTokenChange as c6,
3064
- tarballAssetName as c7,
3065
- tarballUrl as c8,
3066
- teamKey as c9,
3067
- teamKeyOf as ca,
3068
- teamUnreadableMessage as cb,
3069
- teamsIn as cc,
3070
- toAlias as cd,
3071
- toMap as ce,
3072
- toPlain as cf,
3073
- tokenBump as cg,
3074
- tokenNode as ch,
3075
- unreadableShipTeams as ci,
3076
- unreadableTeams as cj,
3077
- valueIn as ck,
3078
- valueToCss as cl,
3079
- visualImpactProblems as cm,
3080
- whoCanShipSentence as cn,
3081
- whyItExists as co,
3083
+ sameProducts as c0,
3084
+ sameToken as c1,
3085
+ serializeJson as c2,
3086
+ shipPolicy as c3,
3087
+ snapshotUrl as c4,
3088
+ soloApprover as c5,
3089
+ soloOwnerOf as c6,
3090
+ soloOwnerSentence as c7,
3091
+ storybookUrl as c8,
3092
+ suggestNearestComment as c9,
3093
+ summarizeTokenChange as ca,
3094
+ tarballAssetName as cb,
3095
+ tarballUrl as cc,
3096
+ teamKey as cd,
3097
+ teamKeyOf as ce,
3098
+ teamUnreadableMessage as cf,
3099
+ teamsIn as cg,
3100
+ toAlias as ch,
3101
+ toMap as ci,
3102
+ toPlain as cj,
3103
+ tokenBump as ck,
3104
+ tokenNode as cl,
3105
+ unreadableShipTeams as cm,
3106
+ unreadableTeams as cn,
3107
+ valueIn as co,
3108
+ valueToCss as cp,
3109
+ visualImpactProblems as cq,
3110
+ whoCanShipSentence as cr,
3111
+ whyItExists as cs,
3082
3112
  collectRefs as d,
3083
3113
  evaluatePairs as e,
3084
3114
  findReferenceProblems as f,
@@ -3103,4 +3133,4 @@ export {
3103
3133
  parseColor as y,
3104
3134
  rgbaToHex as z
3105
3135
  };
3106
- //# sourceMappingURL=prod-branch-BdMPKffE.js.map
3136
+ //# sourceMappingURL=prod-branch-BjXFIz74.js.map