@usefragments/core 1.7.1 → 1.9.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.
Files changed (36) hide show
  1. package/dist/{chunk-WNMWKUYG.js → chunk-DGHZQTLH.js} +324 -6
  2. package/dist/chunk-DGHZQTLH.js.map +1 -0
  3. package/dist/chunk-MZ4SW3TP.js +375 -0
  4. package/dist/chunk-MZ4SW3TP.js.map +1 -0
  5. package/dist/codes/index.d.ts +1 -1
  6. package/dist/codes/index.js +1 -2
  7. package/dist/compiled-types/index.d.ts +1 -1
  8. package/dist/generate/index.d.ts +1 -1
  9. package/dist/governance-telemetry.d.ts +316 -0
  10. package/dist/governance-telemetry.js +11 -0
  11. package/dist/governance-telemetry.js.map +1 -0
  12. package/dist/{index-hZAlYCli.d.ts → index-DtHxs0Pf.d.ts} +1099 -1009
  13. package/dist/index.d.ts +503 -477
  14. package/dist/index.js +94 -37
  15. package/dist/index.js.map +1 -1
  16. package/dist/react-types.d.ts +1 -1
  17. package/dist/registry.d.ts +146 -146
  18. package/dist/schemas/index.d.ts +1 -1
  19. package/dist/schemas/index.js +3 -1
  20. package/dist/test-utils.d.ts +1 -1
  21. package/package.json +5 -1
  22. package/src/governance-telemetry.test.ts +18 -0
  23. package/src/governance-telemetry.ts +398 -0
  24. package/src/index.ts +17 -0
  25. package/src/rules/finding.ts +22 -0
  26. package/src/rules/index.ts +5 -1
  27. package/src/rules/jsx-preferred-import-path.ts +18 -0
  28. package/src/rules/rules.test.ts +114 -0
  29. package/src/rules/tokens-css-vars-must-be-defined.test.ts +66 -1
  30. package/src/rules/tokens-css-vars-must-be-defined.ts +88 -16
  31. package/src/schemas/index.ts +10 -0
  32. package/src/schemas/normalize-finding.test.ts +50 -0
  33. package/dist/chunk-WNMWKUYG.js.map +0 -1
  34. package/dist/chunk-ZHS52OT4.js +0 -317
  35. package/dist/chunk-ZHS52OT4.js.map +0 -1
  36. package/dist/{governance-D9KtH-vg.d.ts → governance-eEzCyfes.d.ts} +154 -154
package/dist/index.js CHANGED
@@ -1,3 +1,7 @@
1
+ import {
2
+ CompiledFragmentsFileValidationError,
3
+ parseCompiledFragmentsFile
4
+ } from "./chunk-RANPUC6C.js";
1
5
  import {
2
6
  generateContext
3
7
  } from "./chunk-X34IA4LR.js";
@@ -7,6 +11,11 @@ import {
7
11
  import {
8
12
  resolveArea
9
13
  } from "./chunk-3LLRNCPX.js";
14
+ import {
15
+ GOVERNANCE_TELEMETRY_FIELDS,
16
+ GOVERNANCE_TELEMETRY_SOURCE_DISCLOSURE,
17
+ GOVERNANCE_TELEMETRY_TOP_LEVEL_FIELDS
18
+ } from "./chunk-MZ4SW3TP.js";
10
19
  import {
11
20
  REGISTRY_ARTIFACT_SCHEMA_VERSION,
12
21
  REGISTRY_INSTALL_RECEIPT_SCHEMA_VERSION,
@@ -41,11 +50,16 @@ import {
41
50
  sha256Hex
42
51
  } from "./chunk-YF65VYRY.js";
43
52
  import {
53
+ AGENT_FORMAT_SCHEMA_VERSION,
44
54
  CODES,
45
55
  EXPLAIN_URL_BASE,
46
56
  FactIndex,
47
57
  RULE_FAMILY_IDS,
48
58
  RULE_FAMILY_MEMBERS,
59
+ agentErrorEnvelopeSchema,
60
+ agentFormatSchema,
61
+ agentIntegritySchema,
62
+ agentOutputSchema,
49
63
  asComponentId,
50
64
  bridgeSourceViolation,
51
65
  bridgeSourceViolations,
@@ -61,13 +75,25 @@ import {
61
75
  describePolicyExclude,
62
76
  excludeGlobToRegExp,
63
77
  explainUrlForCode,
78
+ factEvidenceSchema,
64
79
  factId,
80
+ factLocationSchema,
81
+ findingFixSchema,
82
+ findingReplaceClassTokenFixSchema,
83
+ findingReplaceComponentFixSchema,
84
+ findingReplaceImportFixSchema,
85
+ findingReplacePropValueFixSchema,
86
+ findingReplaceStyleValueFixSchema,
87
+ findingSchema,
88
+ fixSchema,
65
89
  g,
66
90
  globalGovernanceRecordSchema,
67
91
  globalJsxGovernanceRecordSchema,
68
92
  globalStyleGovernanceRecordSchema,
69
93
  governanceConfigSchema,
70
94
  governanceSeveritySchema,
95
+ governanceVerdictMetadataSchema,
96
+ governanceVerdictSchema,
71
97
  hash64Hex,
72
98
  isPresetSourcedRule,
73
99
  isRuleFamilyId,
@@ -116,8 +142,11 @@ import {
116
142
  matchPolicyExclude,
117
143
  matchesGlob,
118
144
  normalizeExcludePath,
145
+ normalizeFinding,
119
146
  normalizeGovernanceConfig,
120
147
  normalizePolicyExcludes,
148
+ normalizeSeverity,
149
+ normalizeViolation,
121
150
  ownedComponentIdsEqual,
122
151
  ownedImportMatchesRoot,
123
152
  ownedImportsEqual,
@@ -126,33 +155,11 @@ import {
126
155
  projectSupersededImportPathPreferences,
127
156
  resolveComponentGovernance,
128
157
  ruleFamilyMembers,
129
- scaleGovernanceRecordSchema
130
- } from "./chunk-WNMWKUYG.js";
131
- import {
132
- AGENT_FORMAT_SCHEMA_VERSION,
133
- agentErrorEnvelopeSchema,
134
- agentFormatSchema,
135
- agentIntegritySchema,
136
- agentOutputSchema,
137
- factEvidenceSchema,
138
- factLocationSchema,
139
- findingFixSchema,
140
- findingReplaceClassTokenFixSchema,
141
- findingReplaceComponentFixSchema,
142
- findingReplaceImportFixSchema,
143
- findingReplacePropValueFixSchema,
144
- findingReplaceStyleValueFixSchema,
145
- findingSchema,
146
- fixSchema,
147
- governanceVerdictMetadataSchema,
148
- governanceVerdictSchema,
149
- normalizeFinding,
150
- normalizeSeverity,
151
- normalizeViolation,
158
+ scaleGovernanceRecordSchema,
152
159
  suppressionDirectiveSchema,
153
160
  validatorResultSchema,
154
161
  violationSchema
155
- } from "./chunk-ZHS52OT4.js";
162
+ } from "./chunk-DGHZQTLH.js";
156
163
  import {
157
164
  OWNED_PACKAGE_IDENTITY_EPOCH,
158
165
  OWNED_PACKAGE_IDENTITY_SOURCE_SHA256,
@@ -182,10 +189,6 @@ import {
182
189
  severitySchema,
183
190
  sortBySeverity
184
191
  } from "./chunk-V4VQB57N.js";
185
- import {
186
- CompiledFragmentsFileValidationError,
187
- parseCompiledFragmentsFile
188
- } from "./chunk-RANPUC6C.js";
189
192
 
190
193
  // src/constants.ts
191
194
  var BRAND = {
@@ -4679,13 +4682,21 @@ function isAriaHidden(props) {
4679
4682
  }
4680
4683
 
4681
4684
  // src/rules/finding.ts
4685
+ var POSITION_IDENTITY_KEYS = ["line", "column", "endLine", "endColumn", "offset", "location"];
4682
4686
  function makeFinding(input) {
4683
4687
  if (input.evidence.length === 0) {
4684
4688
  throw new Error(`makeFinding(${input.ruleId}): findings must carry at least one evidence fact`);
4685
4689
  }
4690
+ const positionKeys = POSITION_IDENTITY_KEYS.filter((key) => key in input.fingerprintIdentity);
4691
+ if (positionKeys.length > 0) {
4692
+ throw new Error(
4693
+ `makeFinding(${input.ruleId}): fingerprintIdentity must not contain position keys (${positionKeys.join(", ")}) \u2014 fingerprints hash what's wrong, never where it sits. Use a source-order occurrence index for repeats of the same identity.`
4694
+ );
4695
+ }
4686
4696
  const fingerprint = hash64Hex(
4687
4697
  canonicalJson({ ruleId: input.ruleId, ...input.fingerprintIdentity })
4688
4698
  );
4699
+ const previousFingerprint = input.previousFingerprintIdentity ? hash64Hex(canonicalJson({ ruleId: input.ruleId, ...input.previousFingerprintIdentity })) : void 0;
4689
4700
  const code = byRuleId.get(input.ruleId);
4690
4701
  return normalizeFinding({
4691
4702
  ruleId: input.ruleId,
@@ -4695,6 +4706,7 @@ function makeFinding(input) {
4695
4706
  helpUrl: code?.explainUrl,
4696
4707
  message: input.message,
4697
4708
  fingerprint,
4709
+ ...previousFingerprint !== void 0 ? { previousFingerprint } : {},
4698
4710
  location: input.location,
4699
4711
  evidence: input.evidence,
4700
4712
  evidenceGrade: input.evidenceGrade ?? "source_backed",
@@ -6743,6 +6755,7 @@ function ruleJsxPreferredImportPath(ix) {
6743
6755
  if (policies.length === 0) return [];
6744
6756
  const findings = [];
6745
6757
  const seen = /* @__PURE__ */ new Set();
6758
+ const occurrences = /* @__PURE__ */ new Map();
6746
6759
  for (const usage of ix.byKind("usage_import")) {
6747
6760
  const bridgeGoverned = policies.some((policy) => bridgeGovernsUnderlyingImport(policy, usage));
6748
6761
  const matches = policies.filter((policy) => {
@@ -6763,6 +6776,9 @@ function ruleJsxPreferredImportPath(ix) {
6763
6776
  const key = `${policy.id}\0${usage.file}\0${usage.source}\0${usage.location.line}\0${usage.location.column}\0${importedIdentity}`;
6764
6777
  if (seen.has(key)) continue;
6765
6778
  seen.add(key);
6779
+ const identityKey = `${usage.file}\0${usage.source}\0${policy.to}\0${importedIdentity}`;
6780
+ const occurrence = occurrences.get(identityKey) ?? 0;
6781
+ occurrences.set(identityKey, occurrence + 1);
6766
6782
  findings.push(
6767
6783
  makeFinding({
6768
6784
  ruleId: RULE_ID8,
@@ -6772,6 +6788,15 @@ function ruleJsxPreferredImportPath(ix) {
6772
6788
  location: usage.location,
6773
6789
  evidence: ix.evidence([usage.id, policy.id]),
6774
6790
  fingerprintIdentity: {
6791
+ file: usage.file,
6792
+ from: usage.source,
6793
+ to: policy.to,
6794
+ imported: policy.imported,
6795
+ occurrence
6796
+ },
6797
+ // Grace window (baseline v1 → v2): the pre-migration hash keyed on
6798
+ // line/column. Drop with the v1 dual-match after one release.
6799
+ previousFingerprintIdentity: {
6775
6800
  file: usage.file,
6776
6801
  from: usage.source,
6777
6802
  to: policy.to,
@@ -8760,16 +8785,28 @@ function indexTokensByCssVariable(tokens) {
8760
8785
  var RULE_ID22 = "tokens/css-vars-must-be-defined";
8761
8786
  var RULE_VERSION23 = "1";
8762
8787
  var CSS_VAR_REFERENCE = /var\(\s*(--[A-Za-z0-9_-]+)/gi;
8788
+ function contractVocabularyContext(ix) {
8789
+ if (!ix.policy.cssVarsMustBeDefined()) return void 0;
8790
+ const vocabulary = new Set(ix.byKind("contract_token").map((token) => token.name));
8791
+ if (vocabulary.size === 0) return void 0;
8792
+ return {
8793
+ vocabulary,
8794
+ prefixes: contractPrefixFamilies(vocabulary),
8795
+ hasFlatTokens: [...vocabulary].some(isSingleSegmentVarName),
8796
+ locallyDefinedCustomProperties: new Set(
8797
+ ix.byKind("style_declaration").filter((decl) => decl.property.startsWith("--")).map((decl) => decl.property)
8798
+ )
8799
+ };
8800
+ }
8801
+ function isJudgedReference(tokenName, context) {
8802
+ return context.vocabulary.has(tokenName) || sharesContractPrefix(tokenName, context.prefixes) || context.hasFlatTokens && isSingleSegmentVarName(tokenName) || context.locallyDefinedCustomProperties.has(tokenName);
8803
+ }
8763
8804
  function ruleTokensCssVarsMustBeDefined(ix) {
8764
8805
  const policy = ix.policy.cssVarsMustBeDefined();
8765
8806
  if (!policy) return [];
8766
- const vocabulary = new Set(ix.byKind("contract_token").map((token) => token.name));
8767
- if (vocabulary.size === 0) return [];
8768
- const prefixes = contractPrefixFamilies(vocabulary);
8769
- const hasFlatTokens = [...vocabulary].some(isSingleSegmentVarName);
8770
- const locallyDefinedCustomProperties = new Set(
8771
- ix.byKind("style_declaration").filter((decl) => decl.property.startsWith("--")).map((decl) => decl.property)
8772
- );
8807
+ const context = contractVocabularyContext(ix);
8808
+ if (!context) return [];
8809
+ const { vocabulary } = context;
8773
8810
  const findings = [];
8774
8811
  for (const decl of ix.byKind("style_declaration")) {
8775
8812
  const seen = /* @__PURE__ */ new Set();
@@ -8779,8 +8816,7 @@ function ruleTokensCssVarsMustBeDefined(ix) {
8779
8816
  const tokenName = match[1];
8780
8817
  CSS_VAR_REFERENCE.lastIndex = skipToCloseParen(decl.value, match.index + 3);
8781
8818
  if (vocabulary.has(tokenName)) continue;
8782
- const shaped = sharesContractPrefix(tokenName, prefixes) || hasFlatTokens && isSingleSegmentVarName(tokenName) || locallyDefinedCustomProperties.has(tokenName);
8783
- if (!shaped) continue;
8819
+ if (!isJudgedReference(tokenName, context)) continue;
8784
8820
  if (seen.has(tokenName)) continue;
8785
8821
  seen.add(tokenName);
8786
8822
  findings.push(
@@ -8819,6 +8855,23 @@ function sharesContractPrefix(name, prefixes) {
8819
8855
  function isSingleSegmentVarName(name) {
8820
8856
  return name.indexOf("-", 2) === -1;
8821
8857
  }
8858
+ function contractTokenReferenceCensus(ix) {
8859
+ const context = contractVocabularyContext(ix);
8860
+ if (!context) return void 0;
8861
+ const checked = /* @__PURE__ */ new Set();
8862
+ for (const decl of ix.byKind("style_declaration")) {
8863
+ CSS_VAR_REFERENCE.lastIndex = 0;
8864
+ let match;
8865
+ while ((match = CSS_VAR_REFERENCE.exec(decl.value)) !== null) {
8866
+ const tokenName = match[1];
8867
+ CSS_VAR_REFERENCE.lastIndex = skipToCloseParen(decl.value, match.index + 3);
8868
+ if (!isJudgedReference(tokenName, context)) continue;
8869
+ checked.add(`${decl.location.file}:${decl.location.line}:${decl.location.column}`);
8870
+ break;
8871
+ }
8872
+ }
8873
+ return { checkedSites: checked.size };
8874
+ }
8822
8875
  function skipToCloseParen(value, openParenIndex) {
8823
8876
  let depth = 0;
8824
8877
  for (let i = openParenIndex; i < value.length; i++) {
@@ -10282,6 +10335,9 @@ export {
10282
10335
  EXPLAIN_URL_BASE,
10283
10336
  FRAGMENTS_INTERNAL_RULE_IDS,
10284
10337
  FactIndex,
10338
+ GOVERNANCE_TELEMETRY_FIELDS,
10339
+ GOVERNANCE_TELEMETRY_SOURCE_DISCLOSURE,
10340
+ GOVERNANCE_TELEMETRY_TOP_LEVEL_FIELDS,
10285
10341
  OWNED_PACKAGE_IDENTITY_EPOCH,
10286
10342
  OWNED_PACKAGE_IDENTITY_SOURCE_SHA256,
10287
10343
  PRESET_NAMES,
@@ -10383,6 +10439,7 @@ export {
10383
10439
  contractHash,
10384
10440
  contractPolicyFromGovernanceConfig,
10385
10441
  contractTierRuleIds,
10442
+ contractTokenReferenceCensus,
10386
10443
  customerDefaultRuleStates,
10387
10444
  defineBlock,
10388
10445
  defineConfig,