Skip to content

Conversation

weareoutman
Copy link
Member

@weareoutman weareoutman commented Sep 4, 2025

依赖检查

组件之间的依赖声明,是微服务组件架构下的重要信息,请确保其正确性。

请勾选以下两组选项其中之一:

  • 本次 MR 没有使用上游组件(例如框架、后台组件等)的较新版本提供的特性。

或者:

  • 本次 MR 使用了上游组件(例如框架、后台组件等)的较新版本提供的特性。
  • 在对应的文件中更新了该上游组件的依赖版本(或确认了当前声明的依赖版本已包含本次 MR 使用的新特性)。

提交信息检查

Git 提交信息将决定包的版本发布及自动生成的 CHANGELOG,请检查工作内容与提交信息是否相符,并在以下每组选项中都依次确认。

破坏性变更是针对于下游使用者而言,可以通过本次改动对下游使用者的影响来识别变更类型:

  • 下游使用者不做任何改动,仍可以正常工作时,那么它属于普通变更。
  • 反之,下游使用者不做改动就无法正常工作时,那么它属于破坏性变更。

例如,构件修改了一个属性名,小产品 Storyboard 中需要使用新属性名才能工作,那么它就是破坏性变更。
又例如,构件还没有任何下游使用者,那么它的任何变更都是普通变更。

破坏性变更:

  • ⚠️ 本次 MR 包含破坏性变更的提交,请继续确认以下所有选项:
  • 没有更好的兼容方案,必须做破坏性变更。
  • 使用了 feat 作为提交类型。
  • 标注了 BREAKING CHANGE: 你的变更说明
  • 同时更新了本仓库中所有下游使用者的调用。
  • 同时更新了本仓库中所有下游使用者对该子包的依赖为即将发布的 major 版本。
  • 同时为其它仓库的 Migrating 做好了准备,例如文档或批量改动的方法。
  • 手动验证过破坏性变更在 Migrate 后可以正常工作。
  • 破坏性变更所在的提交没有意外携带其它子包的改动。

新特性:

  • 本次 MR 包含新特性的提交,且该提交不带有破坏性变更,并使用了 feat 作为提交类型。
  • 给新特性添加了单元测试。
  • 手动验证过新特性可以正常工作。

问题修复:

  • 本次 MR 包含问题修复的提交,且该提交不带有新特性或破坏性变更,并使用了 fix 作为提交类型。
  • 给问题修复添加了单元测试。
  • 手动验证过问题修复得到解决。

杂项工作:

即所有对下游使用者无任何影响、且没有必要显示在 CHANGELOG 中的改动,例如修改注释、测试用例、开发文档等:

  • 本次 MR 包含杂项工作的提交,且该提交不带有问题修复、新特性或破坏性变更,并使用了 chore, docs, test 等作为提交类型。

Summary by CodeRabbit

  • 新功能
    • 新增 matchRoute 公共 API,支持在单一路由中通过首页前缀的可选列表匹配多个路径(例如带方括号的逗号分隔形式),保持精确匹配与参数解析行为不变,提升路由配置灵活性。
  • 测试
    • 新增并完善 matchRoute 用例,覆盖命中与未命中场景及首页前缀列表匹配,确保与现有 matchRoutes 行为一致。

Copy link

coderabbitai bot commented Sep 4, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

在 runtime 内部路由匹配实现中新增并导出 matchRoute 并为其补充测试。路由解析引入常量 HOMEPAGE_PREFIX 与辅助函数 getRoutePath(route, homepage),支持以 ${APP.homepage} 开头的路径展开为单一路径或方括号逗号分隔的多路径阵列;matchRoute 调整为向 matchPath 传入字符串或字符串数组。

Changes

Cohort / File(s) Change Summary
Tests
packages/runtime/src/internal/matchRoutes.spec.ts
重命名测试套件并新增针对 matchRoute 的用例;从 @next-core/types 引入 RouteConf;验证以 ${APP.homepage} 前缀及方括号逗号分隔(如 ${APP.homepage}[,/b/([^/]+)])的匹配/不匹配行为。
Runtime 路由匹配逻辑
packages/runtime/src/internal/matchRoutes.ts
新增常量 HOMEPAGE_PREFIX 与内部函数 getRoutePath(route, homepage),当 route.path${APP.homepage} 开头时支持:去前缀并拼接首页、或解析方括号内逗号分隔为多路径数组;matchRoute 调整为使用 getRoutePath 的返回(stringstring[])并传入 matchPath;导出 matchRoute,保持既有匹配语义。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch steve/v3-route-path-array

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented Sep 4, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.22%. Comparing base (f26358f) to head (52ddc91).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##               v3    #4778   +/-   ##
=======================================
  Coverage   95.22%   95.22%           
=======================================
  Files         209      209           
  Lines        9166     9175    +9     
  Branches     1764     1766    +2     
=======================================
+ Hits         8728     8737    +9     
  Misses        324      324           
  Partials      114      114           
Files with missing lines Coverage Δ
packages/runtime/src/internal/matchRoutes.ts 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

cypress bot commented Sep 4, 2025

next-core    Run #11645

Run Properties:  status check passed Passed #11645  •  git commit aa6d97f22c ℹ️: Merge 52ddc918544b4bea021a8108956135797c81b029 into f26358f18cb64fd9e3bff3c2fb41...
Project next-core
Branch Review steve/v3-route-path-array
Run status status check passed Passed #11645
Run duration 00m 24s
Commit git commit aa6d97f22c ℹ️: Merge 52ddc918544b4bea021a8108956135797c81b029 into f26358f18cb64fd9e3bff3c2fb41...
Committer Shenwei Wang
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 17
View all changes introduced in this branch ↗︎

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/runtime/src/internal/matchRoutes.spec.ts (1)

6-28: 修复断言用法:.rejects 需要 Promise 而非函数

当前传入 () => matchRoutes(...) 会导致断言失效;应直接传入 Promise。另建议在用例结束后恢复 console.error 的 mock。

-  test("handle path not string", async () => {
-    await expect(() =>
-      matchRoutes(
+  test("handle path not string", async () => {
+    await expect(
+      matchRoutes(
         [{}] as any,
         {
           app: {
             homepage: "/x",
           },
           location: {
             pathname: "/x/y",
           },
         } as any
-      )
-    ).rejects.toMatchInlineSnapshot(
+      )
+    ).rejects.toMatchInlineSnapshot(
       `[Error: Invalid route with invalid type of path: undefined]`
     );
     expect(consoleError).toHaveBeenCalledWith(
       "Invalid route with invalid path:",
       {}
     );
   });

在文件末尾或合适位置补充:

afterAll(() => consoleError.mockRestore());
🧹 Nitpick comments (3)
packages/runtime/src/internal/matchRoutes.ts (2)

7-7: 常量定义可微调为字面量类型并考虑集中复用

建议加上 as const,并视情况将该前缀常量集中到共享常量处,避免散落各处定义。

-const HOMEPAGE_PREFIX = "${APP.homepage}";
+const HOMEPAGE_PREFIX = "${APP.homepage}" as const;

61-75: 多路径展开建议修剪空白并消除双斜杠

  • 当前 split(",") 后未 trim,若配置含空格会导致匹配失败。
  • 直接字符串拼接可能在 homepage 末尾含 / 或子路径不含前导 / 时产生 //

建议:

-    if (
+    if (
       restPath.startsWith("[") &&
       restPath.endsWith("]") &&
       restPath.includes(",")
     ) {
-      const paths = restPath.slice(1, -1).split(",");
-      return paths.map((p) => `${homepage}${p}`);
+      const paths = restPath.slice(1, -1).split(",");
+      return paths.map((p) => joinHome(homepage, p));
     }
-    return `${homepage}${restPath}`;
+    return joinHome(homepage, restPath);

在文件内新增一个安全拼接工具(变更范围外补充):

function joinHome(homepage: string, p: string): string {
  const home = homepage.endsWith("/") ? homepage.slice(0, -1) : homepage;
  const part = p.trim();
  if (part === "") return home;
  return `${home}${part.startsWith("/") ? "" : "/"}${part}`;
}
packages/runtime/src/internal/matchRoutes.spec.ts (1)

30-58: 补充边界测试:空白与尾斜杠、三分支以上

为避免回归,建议新增:

  • ${APP.homepage}[, /b](含空格)在 homepage="/home"homepage="/home/" 的等价匹配。
  • 三分支示例:${APP.homepage}[, /b, /c/d]

示例用例片段:

test("trim spaces and handle trailing slash", () => {
  const route: RouteConf = { path: "${APP.homepage}[, /b]", exact: true, bricks: [] };
  expect(matchRoute(route, "/home", "/home")).toBeTruthy();
  expect(matchRoute(route, "/home", "/home/b")).toBeTruthy();
  expect(matchRoute(route, "/home/", "/home")).toBeTruthy();
  expect(matchRoute(route, "/home/", "/home/b")).toBeTruthy();
});

test("multiple branches (3+)", () => {
  const route: RouteConf = { path: "${APP.homepage}[, /b, /c/d]", exact: true, bricks: [] };
  expect(matchRoute(route, "/home", "/home")).toBeTruthy();
  expect(matchRoute(route, "/home", "/home/b")).toBeTruthy();
  expect(matchRoute(route, "/home", "/home/c/d")).toBeTruthy();
});
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge Base: Disabled due to data retention organization setting

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f26358f and 4895487.

📒 Files selected for processing (2)
  • packages/runtime/src/internal/matchRoutes.spec.ts (2 hunks)
  • packages/runtime/src/internal/matchRoutes.ts (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build (20.x)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
packages/runtime/src/internal/matchRoutes.spec.ts (1)

1-2: 导入项合理

同时测试 matchRoutesmatchRoute 很好地覆盖了新增导出。

@weareoutman weareoutman requested a review from Copilot September 4, 2025 03:37
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for array-like path patterns in route configuration, allowing a single route to match multiple paths with a homepage prefix while maintaining exact matching and parameter parsing behavior.

  • Introduces getRoutePath function to handle array-like path syntax ${APP.homepage}[path1,path2]
  • Updates matchRoute function to use the new path processing logic
  • Adds comprehensive test cases for the new array path functionality

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
packages/runtime/src/internal/matchRoutes.ts Adds array path support with new getRoutePath function and HOMEPAGE_PREFIX constant
packages/runtime/src/internal/matchRoutes.spec.ts Adds test cases for array path matching scenarios

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@weareoutman weareoutman force-pushed the steve/v3-route-path-array branch from 4895487 to 52ddc91 Compare September 4, 2025 03:55
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
packages/runtime/src/internal/matchRoutes.ts (1)

49-59: 为 matchRoute 显式标注返回类型,并将 MatchResult 以 type-only 方式导入

  • 建议补上返回类型,稳定公开 API,避免隐式 any/回归。
  • 同时将 MatchResult 改为 import type,避免在启用 verbatimModuleSyntax 时产生无用的运行时导入。

可直接在本段落内修改函数签名:

-export function matchRoute(
+export function matchRoute(
   route: RouteConf,
   homepage: string,
   pathname: string
-) {
+): MatchResult | null {
   const path = getRoutePath(route, homepage);
   return matchPath(pathname, {
     path,
     exact: route.exact,
   });
 }

并在文件顶部将类型以 type-only 导入(此修改发生在变更片段外,作为补充说明):

// 顶部导入改为:
import { matchPath } from "./matchPath.js";
import type { MatchResult } from "./matchPath.js";

另外,matchRoute 作为公开导出,相比 matchRoutes 少了对 route.path 的类型守卫。若担心外部误用,可在本函数开头补一行防御式校验(可选)。

运行以下脚本快速确认 matchPath 的 path 参数是否确认为 string | string[],以及是否已有其它数组形态用例:

#!/bin/bash
# 1) 查看 matchPath 的签名与 path 类型
rg -nP -C3 --type=ts '\bexport\s+(?:function|const)\s+matchPath\b' packages/runtime/src/internal

# 2) 验证仓库内是否存在向 matchPath 传入数组 path 的用例
rg -nP -C2 --type=ts 'matchPath\([^,]+,\s*\{\s*path:\s*\[' packages

# 3) 检查是否启用了 verbatimModuleSyntax(决定是否必须使用 import type)
fd -a 'tsconfig*.json' | xargs -I{} sh -c 'echo "== {} =="; cat "{}"'
🧹 Nitpick comments (1)
packages/runtime/src/internal/matchRoutes.ts (1)

61-75: 提升路径拼接的健壮性:去重斜杠并裁剪逗号分隔项的空白

当前 ${homepage}${p}homepage/ 结尾或 p 未以 / 开头时,可能产生 // 或缺少分隔符,且未裁剪分隔项空白。建议在本函数内做轻量规范化,避免匹配失败的边缘情况(例如 homepage 配置为 /home/)。

-function getRoutePath(route: RouteConf, homepage: string): string | string[] {
+function getRoutePath(route: RouteConf, homepage: string): string | string[] {
   if (route.path.startsWith(HOMEPAGE_PREFIX)) {
     const restPath = route.path.slice(HOMEPAGE_PREFIX.length);
-    if (
+    if (
       restPath.startsWith("[") &&
       restPath.endsWith("]") &&
       restPath.includes(",")
     ) {
-      const paths = restPath.slice(1, -1).split(",");
-      return paths.map((p) => `${homepage}${p}`);
+      const raw = restPath.slice(1, -1).split(",");
+      const base = homepage.endsWith("/") ? homepage.slice(0, -1) : homepage;
+      const join = (seg: string) => {
+        const s = seg.trim();
+        const withSlash = s === "" || s.startsWith("/") ? s : `/${s}`;
+        return `${base}${withSlash}`;
+      };
+      return raw.map((p) => join(p));
     }
-    return `${homepage}${restPath}`;
+    const base = homepage.endsWith("/") ? homepage.slice(0, -1) : homepage;
+    const s = restPath.trim();
+    const withSlash = s === "" || s.startsWith("/") ? s : `/${s}`;
+    return `${base}${withSlash}`;
   }
   return route.path;
 }

说明:

  • 保留空字符串分支(例如 "[,/b/...]" 的首项),以便产生纯 homepage 路径。
  • 只进行 trim,不移除空项,避免改变语义。
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge Base: Disabled due to data retention organization setting

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4895487 and 52ddc91.

📒 Files selected for processing (2)
  • packages/runtime/src/internal/matchRoutes.spec.ts (2 hunks)
  • packages/runtime/src/internal/matchRoutes.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/runtime/src/internal/matchRoutes.spec.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build (20.x)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
packages/runtime/src/internal/matchRoutes.ts (1)

7-7: HOMEPAGE_PREFIX 命名与用途清晰,保持内部常量即可

当前用法简单直接,无需导出。继续保持即可。

@weareoutman weareoutman self-assigned this Sep 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant