@inf-monkeys-tech/monkeys 1.1.10 → 1.1.11

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/README.md CHANGED
@@ -33,7 +33,9 @@ import { resolveThemeTokens } from '@inf-monkeys-tech/monkeys/runtime';
33
33
 
34
34
  `Page`、`PageRelease`、`Workbench`、`WorkbenchRelease`、`Navigation` 与 `NavigationRelease` 是六个独立的 control Ontology 合同。它们复用显式的 tenant scope、不可变 revision/hash、受限 AccessPolicy、RouteSpace/RouteClaim、PublicationPlan 和发布证据;不保存业务 Records、用户组成员、任意 URL 或可执行代码。
35
35
 
36
- `compilePageRuntimeBundle`、`compileWorkbenchRuntimeBundle` 与 `compileNavigationRuntimeBundle` 只接受精确依赖和调用方批准的规模上限,输出可重建、与用户身份无关的确定性 Bundle。现有 `PageDefinition`、`MenuDefinition` 及其编译器保持不变,消费者可以按独立部署节奏升级 SDK。
36
+ `compilePageRuntimeBundle`, `compileWorkbenchRuntimeBundle`, and `compileNavigationRuntimeBundle` validate dependency evidence and caller-approved size limits, then produce rebuildable bundles before identity filtering. Navigation Page links use stable Page identity and the current published target registry; historical Page references in `NavigationRelease` remain audit evidence. Page upgrades, rollbacks, disappearance, and recovery do not require a Navigation publication. Workbench and action target bindings remain exact.
37
+
38
+ `projectCurrentNavigationPages` refreshes Page routes and access policies from a complete, tenant-authorized catalog. Consumers hide unavailable or disabled nodes and empty groups, and enforce both Navigation audience and current Page permissions. Catalog failures remain errors. Persisted release and dependency hashes are not rewritten by runtime projection.
37
39
 
38
40
  ## 发布门禁
39
41
 
package/lib/esm/index.mjs CHANGED
@@ -24605,13 +24605,11 @@ var compileNavigationRuntimeBundle = (input) => {
24605
24605
  const registration = targetsByStableRef.get(stableRefKey(node.targetRef));
24606
24606
  const released = releasedByNodeId.get(node.nodeId);
24607
24607
  const unavailable = unavailableByNodeId.get(node.nodeId);
24608
- if (!registration && unavailable && node.targetRef.kind === "page" && sameStableRef(unavailable.stableTargetRef, node.targetRef)) {
24609
- assertTenantCompatible(
24610
- node.targetRef,
24611
- scope,
24612
- `nodes[${index}].targetRef`
24613
- );
24614
- if (unavailable.accessPolicy && !accessPolicyChainImplies(
24608
+ if (!registration && node.targetRef.kind === "page" && (unavailable && sameStableRef(unavailable.stableTargetRef, node.targetRef) || released && sameStableRef(released.stableTargetRef, node.targetRef))) {
24609
+ if (!released || !verifiedKernelPageReferenceKeys.has(revisionRefKey(released.targetRevisionRef))) {
24610
+ assertTenantCompatible(node.targetRef, scope, `nodes[${index}].targetRef`);
24611
+ }
24612
+ if (unavailable?.accessPolicy && !accessPolicyChainImplies(
24615
24613
  [...ancestors, node.audience],
24616
24614
  unavailable.accessPolicy
24617
24615
  )) {
@@ -24630,24 +24628,25 @@ var compileNavigationRuntimeBundle = (input) => {
24630
24628
  kind: "unavailable",
24631
24629
  nodeId: node.nodeId,
24632
24630
  stableTargetRef: node.targetRef,
24633
- accessPolicy: unavailable.accessPolicy
24631
+ accessPolicy: unavailable?.accessPolicy ?? null
24634
24632
  }
24635
24633
  };
24636
24634
  }
24637
- if (!registration || !released || !sameStableRef(
24635
+ const currentPage = node.targetRef.kind === "page" && registration?.kind === "route";
24636
+ if (!registration || !released && !(currentPage && unavailable && sameStableRef(unavailable.stableTargetRef, node.targetRef)) || !sameStableRef(
24638
24637
  registration.stableTargetRef,
24639
24638
  stableFromRevision(registration.targetRevisionRef)
24640
- ) || !sameStableRef(registration.stableTargetRef, released.stableTargetRef) || !sameRevisionRef(
24639
+ ) || released && !sameStableRef(registration.stableTargetRef, released.stableTargetRef) || !currentPage && released && !sameRevisionRef(
24641
24640
  registration.targetRevisionRef,
24642
24641
  released.targetRevisionRef
24643
- ) || registration.kind === "route" && (Boolean(registration.releaseRevisionRef) !== Boolean(released.releaseRevisionRef) || registration.releaseRevisionRef && released.releaseRevisionRef && !sameRevisionRef(
24642
+ ) || !currentPage && released && registration.kind === "route" && (Boolean(registration.releaseRevisionRef) !== Boolean(released.releaseRevisionRef) || registration.releaseRevisionRef && released.releaseRevisionRef && !sameRevisionRef(
24644
24643
  registration.releaseRevisionRef,
24645
24644
  released.releaseRevisionRef
24646
24645
  ))) {
24647
24646
  throw new DeclarativeControlCompilationError(
24648
24647
  "NAV_TARGET_UNRELEASED",
24649
24648
  `nodes[${index}].targetRef`,
24650
- "Navigation target is not resolved to the exact active release recorded by NavigationRelease."
24649
+ "Navigation target must resolve to the same Page identity or the exact non-Page binding recorded by NavigationRelease."
24651
24650
  );
24652
24651
  }
24653
24652
  if (registration.surface !== release.target.surface) {
@@ -24683,7 +24682,7 @@ var compileNavigationRuntimeBundle = (input) => {
24683
24682
  `nodes[${index}].targetRef`
24684
24683
  );
24685
24684
  }
24686
- if (!accessPolicyChainImplies(
24685
+ if (!currentPage && !accessPolicyChainImplies(
24687
24686
  [...ancestors, node.audience],
24688
24687
  registration.accessPolicy
24689
24688
  )) {
@@ -24708,7 +24707,10 @@ var compileNavigationRuntimeBundle = (input) => {
24708
24707
  let resolvedTarget;
24709
24708
  if (registration.kind === "route") {
24710
24709
  resolvedTarget = {
24711
- ...released,
24710
+ nodeId: node.nodeId,
24711
+ stableTargetRef: registration.stableTargetRef,
24712
+ targetRevisionRef: registration.targetRevisionRef,
24713
+ ...registration.releaseRevisionRef ? { releaseRevisionRef: registration.releaseRevisionRef } : {},
24712
24714
  kind: "route",
24713
24715
  accessPolicy: registration.accessPolicy,
24714
24716
  routeClaim: registration.routeClaim
@@ -24906,6 +24908,45 @@ function projectNavigationCompatibility(bundle, supportsUnavailable) {
24906
24908
  const nodes = bundle.nodes.filter((node) => node.kind !== "target" || node.resolvedTarget.kind !== "unavailable");
24907
24909
  return NavigationRuntimeBundleSchema.parse({ ...unsigned, nodes, contentHash: canonicalContentHash({ ...unsigned, nodes }) });
24908
24910
  }
24911
+ function projectCurrentNavigationPages(source, navigation, targets) {
24912
+ const currentTargets = new Map(targets.map((target) => [canonicalContentHash(target.stableTargetRef), target]));
24913
+ if (currentTargets.size !== targets.length) throw new TypeError("DECLARATIVE_TARGET_CATALOG_INVALID");
24914
+ const authored = new Map(navigation.nodes.map((node) => [node.nodeId, node]));
24915
+ const nodes = source.nodes.map((node) => {
24916
+ if (node.kind !== "target" || node.targetRef.kind !== "page") return node;
24917
+ const original = authored.get(node.nodeId);
24918
+ if (original?.kind !== "target" || canonicalContentHash(original.targetRef) !== canonicalContentHash(node.targetRef)) {
24919
+ throw new TypeError("DECLARATIVE_TARGET_IDENTITY_MISMATCH");
24920
+ }
24921
+ const current = currentTargets.get(canonicalContentHash(node.targetRef));
24922
+ if (current && (!sameStableRef(current.stableTargetRef, current.targetRevisionRef) || current.kind !== "route" || current.surface !== source.surface || current.routeClaim.surface !== source.surface)) {
24923
+ throw new TypeError("DECLARATIVE_TARGET_CATALOG_INVALID");
24924
+ }
24925
+ if (!current || current.kind !== "route" || !current.routeClaim.matcher.parameters.filter((parameter) => current.routeClaim.normalizedPath.split("/").includes(`:${parameter.name}`)).every((parameter) => {
24926
+ if (!parameter.required) return true;
24927
+ const binding = original.parameterMapping[parameter.name];
24928
+ return binding?.kind === "constant" && (typeof binding.value === "string" || typeof binding.value === "number") && String(binding.value).length > 0;
24929
+ })) {
24930
+ return { ...node, disabled: true, parameterMapping: {}, resolvedTarget: {
24931
+ kind: "unavailable",
24932
+ nodeId: node.nodeId,
24933
+ stableTargetRef: node.targetRef,
24934
+ accessPolicy: null
24935
+ } };
24936
+ }
24937
+ return { ...node, disabled: original.disabled, parameterMapping: original.parameterMapping, resolvedTarget: {
24938
+ kind: "route",
24939
+ nodeId: node.nodeId,
24940
+ stableTargetRef: current.stableTargetRef,
24941
+ targetRevisionRef: current.targetRevisionRef,
24942
+ ...current.releaseRevisionRef ? { releaseRevisionRef: current.releaseRevisionRef } : {},
24943
+ accessPolicy: current.accessPolicy,
24944
+ routeClaim: current.routeClaim
24945
+ } };
24946
+ });
24947
+ const { contentHash: _hash, ...unsigned } = source;
24948
+ return NavigationRuntimeBundleSchema.parse({ ...unsigned, nodes, contentHash: canonicalContentHash({ ...unsigned, nodes }) });
24949
+ }
24909
24950
 
24910
24951
  // src/runtime/menu-compiler.ts
24911
24952
  var MenuCompilationError = class extends Error {
@@ -27380,6 +27421,7 @@ export {
27380
27421
  parseWorkflowColumnBinding,
27381
27422
  permissionAlternativePolicyAllows,
27382
27423
  projectAgentSessionEvents,
27424
+ projectCurrentNavigationPages,
27383
27425
  projectNavigationCompatibility,
27384
27426
  projectPageProperties,
27385
27427
  projectRecordEditorValidation,