@jsenv/navi 0.16.8 → 0.16.10

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.
@@ -7781,9 +7781,17 @@ const createRoutePattern = (pattern) => {
7781
7781
  return null;
7782
7782
  }
7783
7783
 
7784
+ // Get parent route's resolved signal values to pass to child routes
7785
+ const parentResolvedParams = resolveParams(params);
7786
+
7784
7787
  // Try each child pattern object to find the most specific match
7785
7788
  for (const childPatternObj of childPatternObjs) {
7786
- const childRouteCandidate = evaluateChildRoute(childPatternObj, params);
7789
+
7790
+ const childRouteCandidate = evaluateChildRoute(
7791
+ childPatternObj,
7792
+ params,
7793
+ parentResolvedParams,
7794
+ );
7787
7795
 
7788
7796
  if (childRouteCandidate) {
7789
7797
  return childRouteCandidate;
@@ -7795,7 +7803,11 @@ const createRoutePattern = (pattern) => {
7795
7803
  /**
7796
7804
  * Helper: Evaluate if a specific child route is suitable for current params/signals
7797
7805
  */
7798
- const evaluateChildRoute = (childPatternObj, params) => {
7806
+ const evaluateChildRoute = (
7807
+ childPatternObj,
7808
+ params,
7809
+ parentResolvedParams = {},
7810
+ ) => {
7799
7811
  // Step 1: Check parameter compatibility
7800
7812
  const compatibility = checkChildRouteCompatibility(childPatternObj, params);
7801
7813
  if (!compatibility.isCompatible) {
@@ -7813,7 +7825,7 @@ const createRoutePattern = (pattern) => {
7813
7825
  }
7814
7826
 
7815
7827
  // Step 3: Build child route URL with proper parameter filtering
7816
- return buildChildRouteUrl(childPatternObj, params);
7828
+ return buildChildRouteUrl(childPatternObj, params, parentResolvedParams);
7817
7829
  };
7818
7830
 
7819
7831
  /**
@@ -7891,26 +7903,39 @@ const createRoutePattern = (pattern) => {
7891
7903
  };
7892
7904
  }
7893
7905
 
7894
- // Check for incompatible cases
7895
- if (item.isUserProvided && !matchesChildLiteral) {
7906
+ // Check if this is a query parameter in the parent pattern
7907
+ const isParentQueryParam = parsedPattern.queryParams.some(
7908
+ (qp) => qp.name === paramName,
7909
+ );
7910
+
7911
+ if (isParentQueryParam) {
7912
+ // Query parameters are always compatible and can be inherited by child routes
7913
+ return {
7914
+ isCompatible: true,
7915
+ shouldInclude: !item.isUserProvided && !matchesChildLiteral,
7916
+ paramName,
7917
+ paramValue,
7918
+ };
7919
+ }
7920
+
7921
+ // Check for generic parameter-literal conflicts (only for path parameters)
7922
+ if (!matchesChildLiteral) {
7896
7923
  // Check if this is a path parameter from parent pattern
7897
7924
  const isParentPathParam = connections.some(
7898
7925
  (conn) => conn.paramName === paramName,
7899
7926
  );
7900
7927
 
7901
7928
  if (isParentPathParam) {
7902
- // User provided a path param value that doesn't match this child's literals
7903
- return { isCompatible: false };
7904
- }
7905
- }
7929
+ // Parameter value (from user or signal) doesn't match this child's literals
7930
+ // Check if child has any literal segments that would conflict with this parameter
7931
+ const hasConflictingLiteral = childParsedPattern.segments.some(
7932
+ (segment) =>
7933
+ segment.type === "literal" && segment.value !== paramValue,
7934
+ );
7906
7935
 
7907
- // Special case: section parameter with settings literal
7908
- if (paramName === "section" && paramValue !== "settings") {
7909
- const hasSettingsLiteral = childParsedPattern.segments.some(
7910
- (segment) => segment.type === "literal" && segment.value === "settings",
7911
- );
7912
- if (hasSettingsLiteral) {
7913
- return { isCompatible: false };
7936
+ if (hasConflictingLiteral) {
7937
+ return { isCompatible: false };
7938
+ }
7914
7939
  }
7915
7940
  }
7916
7941
 
@@ -7962,13 +7987,20 @@ const createRoutePattern = (pattern) => {
7962
7987
  // Use child route if:
7963
7988
  // 1. Child has active non-default parameters, OR
7964
7989
  // 2. User provided params AND child can be built completely
7965
- return hasActiveParams || (hasProvidedParams && canBuildChildCompletely);
7990
+ const shouldUse =
7991
+ hasActiveParams || (hasProvidedParams && canBuildChildCompletely);
7992
+
7993
+ return shouldUse;
7966
7994
  };
7967
7995
 
7968
7996
  /**
7969
7997
  * Helper: Build URL for selected child route with proper parameter filtering
7970
7998
  */
7971
- const buildChildRouteUrl = (childPatternObj, params) => {
7999
+ const buildChildRouteUrl = (
8000
+ childPatternObj,
8001
+ params,
8002
+ parentResolvedParams = {},
8003
+ ) => {
7972
8004
  // Start with child signal values
7973
8005
  const baseParams = {};
7974
8006
  for (const connection of childPatternObj.connections) {
@@ -7981,6 +8013,40 @@ const createRoutePattern = (pattern) => {
7981
8013
  }
7982
8014
  }
7983
8015
 
8016
+ // Add parent parameters that should be inherited (excluding defaults and consumed parameters)
8017
+ for (const [paramName, parentValue] of Object.entries(
8018
+ parentResolvedParams,
8019
+ )) {
8020
+ // Skip if child route already handles this parameter
8021
+ const childConnection = childPatternObj.connections.find(
8022
+ (conn) => conn.paramName === paramName,
8023
+ );
8024
+ if (childConnection) {
8025
+ continue; // Child route handles this parameter directly
8026
+ }
8027
+
8028
+ // Skip if parameter is consumed by child's literal path segments
8029
+ const isConsumedByChildPath = childPatternObj.pattern.segments.some(
8030
+ (segment) =>
8031
+ segment.type === "literal" && segment.value === parentValue,
8032
+ );
8033
+ if (isConsumedByChildPath) {
8034
+ continue; // Parameter is consumed by child's literal path
8035
+ }
8036
+
8037
+ // Check if parent parameter is at default value
8038
+ const parentConnection = connections.find(
8039
+ (conn) => conn.paramName === paramName,
8040
+ );
8041
+ const parentDefault = parentConnection?.options?.defaultValue;
8042
+ if (parentValue === parentDefault) {
8043
+ continue; // Don't inherit default values
8044
+ }
8045
+
8046
+ // Inherit this parameter as it's not handled by child and not at default
8047
+ baseParams[paramName] = parentValue;
8048
+ }
8049
+
7984
8050
  // Apply user params with filtering logic
7985
8051
  for (const [paramName, userValue] of Object.entries(params)) {
7986
8052
  const childConnection = childPatternObj.connections.find(
@@ -8070,6 +8136,7 @@ const createRoutePattern = (pattern) => {
8070
8136
  };
8071
8137
 
8072
8138
  const buildMostPreciseUrl = (params = {}) => {
8139
+
8073
8140
  // Step 1: Resolve and clean parameters
8074
8141
  const resolvedParams = resolveParams(params);
8075
8142