@fabricorg/sdui-release 0.5.0 → 0.7.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.
package/dist/index.js CHANGED
@@ -416,7 +416,9 @@ function buildKnownActionIntents(contracts, add, grantedIntents) {
416
416
  const occurrences = /* @__PURE__ */ new Map();
417
417
  for (const contract of contracts) {
418
418
  const experience = contract.extensions?.["fabric.experience/v1"];
419
+ const declaredActions = new Set(contract.actions.map((action) => action.actionId));
419
420
  for (const intent of experience?.actionIntents ?? []) {
421
+ if (!declaredActions.has(intent.actionId)) continue;
420
422
  const shortName2 = intent.name.startsWith(`${contract.namespace}.`) ? intent.name.slice(contract.namespace.length + 1) : intent.name;
421
423
  const reference = `${contract.namespace}/${shortName2}`;
422
424
  if (grantedIntents === void 0 || grantedIntents.has(`capability://${reference}`)) {
@@ -675,6 +677,25 @@ function validateSduiRelease(input) {
675
677
  ...resolved.remote ? { remote: resolved.remote } : {}
676
678
  });
677
679
  }
680
+ const contractNamespaces = /* @__PURE__ */ new Set();
681
+ const distinctContracts = contracts.filter((contract) => {
682
+ if (contractNamespaces.has(contract.namespace)) {
683
+ add(
684
+ "ambiguous_capability_reference",
685
+ `contracts.${contract.namespace}`,
686
+ `contract for "${contract.namespace}" is supplied more than once`
687
+ );
688
+ return false;
689
+ }
690
+ contractNamespaces.add(contract.namespace);
691
+ return true;
692
+ });
693
+ const seenDocumentNamespaces = /* @__PURE__ */ new Set();
694
+ const distinctDocuments = input.contracts.filter((document) => {
695
+ if (seenDocumentNamespaces.has(document.capability.namespace)) return false;
696
+ seenDocumentNamespaces.add(document.capability.namespace);
697
+ return true;
698
+ });
678
699
  {
679
700
  for (const pack of resolvedPacks) {
680
701
  const approved = input.assembly.componentPacks.find(
@@ -726,7 +747,7 @@ function validateSduiRelease(input) {
726
747
  );
727
748
  }
728
749
  }
729
- for (const document of input.contracts) {
750
+ for (const document of distinctDocuments) {
730
751
  const approved = input.assembly.capabilities.find(
731
752
  (capability) => capability.namespace === document.capability.namespace && capability.usageContractDigest === computeUsageContractDocumentDigest(document)
732
753
  );
@@ -746,23 +767,32 @@ function validateSduiRelease(input) {
746
767
  }
747
768
  }
748
769
  const coreComponents = new Set(input.coreComponents ?? []);
749
- const knownViews = buildKnownViews(contracts);
770
+ const knownViews = buildKnownViews(distinctContracts);
750
771
  const grantedViews = buildGrantedReferences(input.grants.views, "grants.views");
751
772
  const grantedIntents = buildGrantedReferences(input.grants.intents, "grants.intents");
752
- const knownIntents = buildKnownActionIntents(contracts, add, grantedIntents);
753
- reportAmbiguousGrantedViews(contracts, grantedViews, add);
754
- const contractNamespaces = /* @__PURE__ */ new Set();
755
- for (const contract of contracts) {
756
- if (contractNamespaces.has(contract.namespace)) {
773
+ const knownIntents = buildKnownActionIntents(distinctContracts, add, grantedIntents);
774
+ reportAmbiguousGrantedViews(distinctContracts, grantedViews, add);
775
+ for (const reference of grantedViews) {
776
+ const parsed = parseCapabilityRef(reference);
777
+ if (parsed && !knownViews.has(`${parsed.namespace}/${parsed.name}`)) {
757
778
  add(
758
- "ambiguous_capability_reference",
759
- `contracts.${contract.namespace}`,
760
- `contract for "${contract.namespace}" is supplied more than once`
779
+ "unauthorized_data_ref",
780
+ `grants.views.${reference}`,
781
+ `release grants "${reference}", which no supplied capability publishes; promotion would fail to route it`
782
+ );
783
+ }
784
+ }
785
+ for (const reference of grantedIntents) {
786
+ const parsed = parseCapabilityRef(reference);
787
+ if (parsed && !knownIntents.has(`${parsed.namespace}/${parsed.name}`)) {
788
+ add(
789
+ "mutation_bypass",
790
+ `grants.intents.${reference}`,
791
+ `release grants "${reference}", which no supplied capability declares as an intent backed by a declared action; promotion would fail to route it`
761
792
  );
762
793
  }
763
- contractNamespaces.add(contract.namespace);
764
794
  }
765
- validateIntentActionDeclarations(contracts, add);
795
+ validateIntentActionDeclarations(distinctContracts, add);
766
796
  const fragmentGrants = /* @__PURE__ */ new Map();
767
797
  for (const [fragmentId, declared] of Object.entries(input.grants.fragments ?? {})) {
768
798
  for (const view of declared.views ?? []) {
@@ -1064,7 +1094,9 @@ function deriveAuthorizationGrants(contracts, held, options = {}) {
1064
1094
  const reference = `capability://${contract.namespace}/${shortName(view.name, contract.namespace, "/")}`;
1065
1095
  if (!bound || bound.views.has(reference)) views.push(reference);
1066
1096
  }
1097
+ const declaredActions = new Set(contract.actions.map((action) => action.actionId));
1067
1098
  for (const intent of actionIntentsOf(contract)) {
1099
+ if (!declaredActions.has(intent.actionId)) continue;
1068
1100
  const reference = `capability://${contract.namespace}/${shortName(intent.name, contract.namespace, ".")}`;
1069
1101
  if (!bound || bound.intents.has(reference)) intents.push(reference);
1070
1102
  }