@inf-monkeys-tech/monkeys 1.0.68 → 1.0.69
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/lib/contracts/declarative-control-http.d.ts +1681 -369
- package/lib/contracts/declarative-control-http.d.ts.map +1 -1
- package/lib/contracts/declarative-control.d.ts +740 -23
- package/lib/contracts/declarative-control.d.ts.map +1 -1
- package/lib/contracts/declarative-control.js +22 -3
- package/lib/contracts/declarative-control.js.map +1 -1
- package/lib/esm/contracts/index.mjs +22 -3
- package/lib/esm/contracts/index.mjs.map +1 -1
- package/lib/esm/index.mjs +98 -3
- package/lib/esm/index.mjs.map +1 -1
- package/lib/esm/runtime/index.mjs +97 -3
- package/lib/esm/runtime/index.mjs.map +1 -1
- package/lib/esm/schemas/index.mjs +22 -3
- package/lib/esm/schemas/index.mjs.map +1 -1
- package/lib/json-schema/navigation-release.schema.json +582 -0
- package/lib/json-schema/navigation-runtime-bundle.schema.json +579 -0
- package/lib/runtime/declarative-control-compiler.d.ts.map +1 -1
- package/lib/runtime/declarative-control-compiler.js +26 -0
- package/lib/runtime/declarative-control-compiler.js.map +1 -1
- package/lib/runtime/index.d.ts +1 -0
- package/lib/runtime/index.d.ts.map +1 -1
- package/lib/runtime/index.js +1 -0
- package/lib/runtime/index.js.map +1 -1
- package/lib/runtime/menu-compiler.d.ts +19 -1
- package/lib/runtime/menu-compiler.d.ts.map +1 -1
- package/lib/runtime/menu-compiler.js +34 -0
- package/lib/runtime/menu-compiler.js.map +1 -1
- package/lib/runtime/navigation-availability.d.ts +6 -0
- package/lib/runtime/navigation-availability.d.ts.map +1 -0
- package/lib/runtime/navigation-availability.js +17 -0
- package/lib/runtime/navigation-availability.js.map +1 -0
- package/lib/schemas/index.d.ts +240 -1
- package/lib/schemas/index.d.ts.map +1 -1
- package/lib/schemas/index.js +5 -4
- package/lib/schemas/index.js.map +1 -1
- package/package.json +1 -1
- package/test/fixtures/navigation-three-roots-topology.json +275 -0
|
@@ -10076,6 +10076,12 @@ var ResolvedNavigationTargetSchema = z9.object({
|
|
|
10076
10076
|
targetRevisionRef: RevisionRefSchema,
|
|
10077
10077
|
releaseRevisionRef: RevisionRefSchema.optional()
|
|
10078
10078
|
}).strict();
|
|
10079
|
+
var UnavailableNavigationTargetSchema = z9.object({
|
|
10080
|
+
nodeId: ContractIdentifierSchema,
|
|
10081
|
+
stableTargetRef: StableRefSchema.refine((reference) => reference.kind === "page", "Only missing Pages can be isolated."),
|
|
10082
|
+
reason: z9.literal("page-missing"),
|
|
10083
|
+
accessPolicy: AccessPolicySchema.nullable()
|
|
10084
|
+
}).strict();
|
|
10079
10085
|
var NavigationReleaseSchema = z9.object({
|
|
10080
10086
|
contract: z9.literal("NavigationRelease"),
|
|
10081
10087
|
...ReleaseBaseShape,
|
|
@@ -10085,13 +10091,17 @@ var NavigationReleaseSchema = z9.object({
|
|
|
10085
10091
|
surface: ProductSurfaceSchema,
|
|
10086
10092
|
placement: ContractIdentifierSchema
|
|
10087
10093
|
}).strict(),
|
|
10088
|
-
resolvedTargets: z9.array(ResolvedNavigationTargetSchema)
|
|
10094
|
+
resolvedTargets: z9.array(ResolvedNavigationTargetSchema),
|
|
10095
|
+
unavailableTargets: z9.array(UnavailableNavigationTargetSchema).optional()
|
|
10089
10096
|
}).strict().superRefine((value, context) => {
|
|
10090
10097
|
validateDependencySnapshot(value.dependencySnapshot, context);
|
|
10091
10098
|
validateReleaseExpectedHead(value, "navigation-release", context);
|
|
10092
10099
|
if (value.navigationRevisionRef.kind !== "navigation") context.addIssue({ code: "custom", path: ["navigationRevisionRef", "kind"], message: "Expected a navigation revision." });
|
|
10093
10100
|
if (value.target.environmentRef.kind !== "environment") context.addIssue({ code: "custom", path: ["target", "environmentRef", "kind"], message: "Navigation release target requires an environment reference." });
|
|
10094
10101
|
if (uniqueArray(value.resolvedTargets, (target) => target.nodeId)) context.addIssue({ code: "custom", path: ["resolvedTargets"], message: "Resolved Navigation node IDs must be unique." });
|
|
10102
|
+
if (uniqueArray([...value.resolvedTargets, ...value.unavailableTargets ?? []], (target) => target.nodeId)) {
|
|
10103
|
+
context.addIssue({ code: "custom", path: ["unavailableTargets"], message: "Navigation target resolutions must have unique node IDs." });
|
|
10104
|
+
}
|
|
10095
10105
|
});
|
|
10096
10106
|
var RuntimeDiagnosticSchema = z9.object({
|
|
10097
10107
|
code: ContractIdentifierSchema,
|
|
@@ -10179,7 +10189,8 @@ var CompiledNavigationDomainCommandTargetSchema = ResolvedNavigationTargetSchema
|
|
|
10179
10189
|
var CompiledNavigationResolvedTargetSchema = z9.discriminatedUnion("kind", [
|
|
10180
10190
|
CompiledNavigationTargetSchema,
|
|
10181
10191
|
CompiledNavigationRegisteredMenuActionTargetSchema,
|
|
10182
|
-
CompiledNavigationDomainCommandTargetSchema
|
|
10192
|
+
CompiledNavigationDomainCommandTargetSchema,
|
|
10193
|
+
UnavailableNavigationTargetSchema.omit({ reason: true }).extend({ kind: z9.literal("unavailable") }).strict()
|
|
10183
10194
|
]);
|
|
10184
10195
|
var CompiledNavigationGroupNodeSchema = NavigationGroupNodeSchema.extend({
|
|
10185
10196
|
ancestorAccessPolicies: z9.array(AccessPolicySchema)
|
|
@@ -10187,7 +10198,14 @@ var CompiledNavigationGroupNodeSchema = NavigationGroupNodeSchema.extend({
|
|
|
10187
10198
|
var CompiledNavigationTargetNodeSchema = NavigationTargetNodeSchema.extend({
|
|
10188
10199
|
ancestorAccessPolicies: z9.array(AccessPolicySchema),
|
|
10189
10200
|
resolvedTarget: CompiledNavigationResolvedTargetSchema
|
|
10190
|
-
}).strict()
|
|
10201
|
+
}).strict().superRefine((node, context) => {
|
|
10202
|
+
if (node.resolvedTarget.nodeId !== node.nodeId || stableRefIdentity(node.resolvedTarget.stableTargetRef) !== stableRefIdentity(node.targetRef)) {
|
|
10203
|
+
context.addIssue({ code: "custom", path: ["resolvedTarget"], message: "Resolved target identity must match the source node." });
|
|
10204
|
+
}
|
|
10205
|
+
if (node.resolvedTarget.kind === "unavailable" && (node.disabled !== true || Object.keys(node.parameterMapping).length > 0)) {
|
|
10206
|
+
context.addIssue({ code: "custom", path: ["resolvedTarget"], message: "Unavailable targets must be disabled and contain no executable input." });
|
|
10207
|
+
}
|
|
10208
|
+
});
|
|
10191
10209
|
var CompiledNavigationSeparatorNodeSchema = NavigationSeparatorNodeSchema.extend({
|
|
10192
10210
|
ancestorAccessPolicies: z9.array(AccessPolicySchema)
|
|
10193
10211
|
}).strict();
|
|
@@ -11407,7 +11425,14 @@ var compileNavigationRuntimeBundle = (input) => {
|
|
|
11407
11425
|
assertUniqueRegistryKeys(targetRegistry.map((registration) => stableRefKey(registration.stableTargetRef)), "targetRegistry");
|
|
11408
11426
|
const targetsByStableRef = new Map(targetRegistry.map((registration) => [stableRefKey(registration.stableTargetRef), registration]));
|
|
11409
11427
|
const releasedByNodeId = new Map(release.resolvedTargets.map((target) => [target.nodeId, target]));
|
|
11428
|
+
const unavailableByNodeId = new Map((release.unavailableTargets ?? []).map((target) => [target.nodeId, target]));
|
|
11410
11429
|
const nodesById = new Map(navigation.nodes.map((node) => [node.nodeId, node]));
|
|
11430
|
+
for (const target of release.unavailableTargets ?? []) {
|
|
11431
|
+
const node = nodesById.get(target.nodeId);
|
|
11432
|
+
if (node?.kind !== "target" || !sameStableRef(node.targetRef, target.stableTargetRef)) {
|
|
11433
|
+
throw new DeclarativeControlCompilationError("NAV_TARGET_UNRELEASED", "release.unavailableTargets", "An unavailable target must identify its source Page node exactly.");
|
|
11434
|
+
}
|
|
11435
|
+
}
|
|
11411
11436
|
const nodes = orderedNavigationNodes(navigation).map((node, index) => {
|
|
11412
11437
|
const ancestors = [];
|
|
11413
11438
|
let parentId = node.parentNodeId;
|
|
@@ -11422,6 +11447,25 @@ var compileNavigationRuntimeBundle = (input) => {
|
|
|
11422
11447
|
}
|
|
11423
11448
|
const registration = targetsByStableRef.get(stableRefKey(node.targetRef));
|
|
11424
11449
|
const released = releasedByNodeId.get(node.nodeId);
|
|
11450
|
+
const unavailable = unavailableByNodeId.get(node.nodeId);
|
|
11451
|
+
if (!registration && unavailable && node.targetRef.kind === "page" && sameStableRef(unavailable.stableTargetRef, node.targetRef)) {
|
|
11452
|
+
assertTenantCompatible(node.targetRef, scope, `nodes[${index}].targetRef`);
|
|
11453
|
+
if (unavailable.accessPolicy && !accessPolicyChainImplies([...ancestors, node.audience], unavailable.accessPolicy)) {
|
|
11454
|
+
throw new DeclarativeControlCompilationError("AUDIENCE_WIDER_THAN_TARGET", `nodes[${index}].audience`, "Effective Navigation audience is wider than the last verified target audience.");
|
|
11455
|
+
}
|
|
11456
|
+
return {
|
|
11457
|
+
...node,
|
|
11458
|
+
disabled: true,
|
|
11459
|
+
parameterMapping: {},
|
|
11460
|
+
ancestorAccessPolicies: ancestors,
|
|
11461
|
+
resolvedTarget: {
|
|
11462
|
+
kind: "unavailable",
|
|
11463
|
+
nodeId: node.nodeId,
|
|
11464
|
+
stableTargetRef: node.targetRef,
|
|
11465
|
+
accessPolicy: unavailable.accessPolicy
|
|
11466
|
+
}
|
|
11467
|
+
};
|
|
11468
|
+
}
|
|
11425
11469
|
if (!registration || !released || !sameStableRef(registration.stableTargetRef, stableFromRevision(registration.targetRevisionRef)) || !sameStableRef(registration.stableTargetRef, released.stableTargetRef) || !sameRevisionRef(registration.targetRevisionRef, released.targetRevisionRef) || registration.kind === "route" && (Boolean(registration.releaseRevisionRef) !== Boolean(released.releaseRevisionRef) || registration.releaseRevisionRef && released.releaseRevisionRef && !sameRevisionRef(registration.releaseRevisionRef, released.releaseRevisionRef))) {
|
|
11426
11470
|
throw new DeclarativeControlCompilationError("NAV_TARGET_UNRELEASED", `nodes[${index}].targetRef`, "Navigation target is not resolved to the exact active release recorded by NavigationRelease.");
|
|
11427
11471
|
}
|
|
@@ -11551,6 +11595,16 @@ var resolveWorkbenchEntry = (input) => {
|
|
|
11551
11595
|
return { status: "forbidden", workbenchId: "" };
|
|
11552
11596
|
};
|
|
11553
11597
|
|
|
11598
|
+
// src/runtime/navigation-availability.ts
|
|
11599
|
+
var NAVIGATION_UNAVAILABLE_CAPABILITY_HEADER = "x-monkeys-navigation-capabilities";
|
|
11600
|
+
var NAVIGATION_UNAVAILABLE_CAPABILITY = "unavailable-pages-v1";
|
|
11601
|
+
function projectNavigationCompatibility(bundle, supportsUnavailable) {
|
|
11602
|
+
if (supportsUnavailable || !bundle.nodes.some((node) => node.kind === "target" && node.resolvedTarget.kind === "unavailable")) return bundle;
|
|
11603
|
+
const { contentHash: _hash, ...unsigned } = bundle;
|
|
11604
|
+
const nodes = bundle.nodes.filter((node) => node.kind !== "target" || node.resolvedTarget.kind !== "unavailable");
|
|
11605
|
+
return NavigationRuntimeBundleSchema.parse({ ...unsigned, nodes, contentHash: canonicalContentHash({ ...unsigned, nodes }) });
|
|
11606
|
+
}
|
|
11607
|
+
|
|
11554
11608
|
// src/runtime/menu-compiler.ts
|
|
11555
11609
|
var MenuCompilationError = class extends Error {
|
|
11556
11610
|
constructor(code, path, message) {
|
|
@@ -11823,6 +11877,13 @@ var compileMenuRuntimeBundle = (input) => {
|
|
|
11823
11877
|
const contributionProviders = input.contributionProviders.map((registration) => MenuContributionProviderRegistrationSchema.parse(registration));
|
|
11824
11878
|
const inputValidators = input.inputValidators ?? /* @__PURE__ */ new Map();
|
|
11825
11879
|
const knownPermissions = new Set(input.permissionCodes.map((permission) => ContractIdentifierSchema.parse(permission)));
|
|
11880
|
+
const completeApplications = new Set(input.missingPagePolicy?.completeApplicationIds.map((id) => ContractIdentifierSchema.parse(id)) ?? []);
|
|
11881
|
+
const unavailableAccess = input.missingPagePolicy ? MenuAccessRequirementSchema.parse(input.missingPagePolicy.unavailableAccess) : void 0;
|
|
11882
|
+
if (unavailableAccess) {
|
|
11883
|
+
validatePermissionCodes(unavailableAccess.permissionAllOf, knownPermissions, "missingPagePolicy.unavailableAccess.permissionAllOf");
|
|
11884
|
+
validatePermissionCodes(unavailableAccess.permissionAnyOf, knownPermissions, "missingPagePolicy.unavailableAccess.permissionAnyOf");
|
|
11885
|
+
}
|
|
11886
|
+
const diagnostics = [];
|
|
11826
11887
|
pages.forEach((registration, index) => {
|
|
11827
11888
|
if (!registration.page.visibility.productContexts.some((context) => context === registration.applicationId)) {
|
|
11828
11889
|
throw new MenuCompilationError(
|
|
@@ -11887,6 +11948,35 @@ var compileMenuRuntimeBundle = (input) => {
|
|
|
11887
11948
|
if (node.behavior.kind === "navigate") {
|
|
11888
11949
|
const registration = pagesByKey.get(pageKey(node.behavior.page));
|
|
11889
11950
|
if (!registration) {
|
|
11951
|
+
if (unavailableAccess && completeApplications.has(node.behavior.page.applicationId)) {
|
|
11952
|
+
const activationId2 = resolveMenuActivationId(node.behavior.page, node.behavior.activationId);
|
|
11953
|
+
const identity2 = targetKey(node.behavior.page, activationId2);
|
|
11954
|
+
const signature2 = stableSerialize2({ ...node.behavior, activationId: activationId2 });
|
|
11955
|
+
const previous = targetSourceSignatures.get(identity2);
|
|
11956
|
+
if (previous !== void 0 && previous !== signature2) {
|
|
11957
|
+
throw new MenuCompilationError("conflicting-navigation-target", `${nodePath}.behavior`, "Missing navigation target has conflicting behavior or input.");
|
|
11958
|
+
}
|
|
11959
|
+
targetSourceSignatures.set(identity2, signature2);
|
|
11960
|
+
if (definition.applicationId === applicationId) {
|
|
11961
|
+
diagnostics.push({
|
|
11962
|
+
code: "missing-page",
|
|
11963
|
+
severity: "warning",
|
|
11964
|
+
applicationId: definition.applicationId,
|
|
11965
|
+
surface: definition.surface,
|
|
11966
|
+
menuId: definition.menuId,
|
|
11967
|
+
nodeId: node.nodeId,
|
|
11968
|
+
page: node.behavior.page,
|
|
11969
|
+
path: `${nodePath}.behavior.page`
|
|
11970
|
+
});
|
|
11971
|
+
}
|
|
11972
|
+
const { requiredPermission: requiredPermission3, behavior: _behavior3, ...presentation3 } = node;
|
|
11973
|
+
return CompiledMenuItemNodeSchema.parse({
|
|
11974
|
+
...presentation3,
|
|
11975
|
+
disabled: true,
|
|
11976
|
+
behavior: { kind: "navigate", page: node.behavior.page, activationId: activationId2 },
|
|
11977
|
+
access: { ...unavailableAccess, requiredPermission: requiredPermission3 }
|
|
11978
|
+
});
|
|
11979
|
+
}
|
|
11890
11980
|
throw new MenuCompilationError(
|
|
11891
11981
|
"unknown-page",
|
|
11892
11982
|
`${nodePath}.behavior.page`,
|
|
@@ -12049,6 +12139,7 @@ var compileMenuRuntimeBundle = (input) => {
|
|
|
12049
12139
|
};
|
|
12050
12140
|
return Object.freeze({
|
|
12051
12141
|
document: deepFreeze2(document),
|
|
12142
|
+
diagnostics: deepFreeze2(diagnostics),
|
|
12052
12143
|
menusByKey,
|
|
12053
12144
|
navigationTargetsByKey: documentTargetsByKey,
|
|
12054
12145
|
serverInputByTargetKey,
|
|
@@ -15852,6 +15943,8 @@ export {
|
|
|
15852
15943
|
DeclarativeControlCompilationError,
|
|
15853
15944
|
MONKEYS_REQUIRED_THEME_TOKEN_PATHS,
|
|
15854
15945
|
MenuCompilationError,
|
|
15946
|
+
NAVIGATION_UNAVAILABLE_CAPABILITY,
|
|
15947
|
+
NAVIGATION_UNAVAILABLE_CAPABILITY_HEADER,
|
|
15855
15948
|
ThemeTokenValidationError,
|
|
15856
15949
|
accessPolicyChainImplies,
|
|
15857
15950
|
applyViewRuntimeBindings,
|
|
@@ -15896,6 +15989,7 @@ export {
|
|
|
15896
15989
|
mergeThemeTokenDocuments,
|
|
15897
15990
|
parseApplicationHandoff,
|
|
15898
15991
|
projectAgentSessionEvents,
|
|
15992
|
+
projectNavigationCompatibility,
|
|
15899
15993
|
publishOpenApiToolCapabilityManifests,
|
|
15900
15994
|
readApplicationHandoffFromUrl,
|
|
15901
15995
|
readMenuActivationFromSearch,
|