livemark 0.16.0 → 0.17.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.
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from "vite-plus/test";
2
- import { matchSection, partitionBySection } from "./section.js";
2
+ import { customSectionActive, matchSection, partitionBySection, } from "./section.js";
3
3
  describe("matchSection", () => {
4
4
  const sections = [
5
5
  { title: "Docs", prefix: "/" },
@@ -59,4 +59,34 @@ describe("partitionBySection", () => {
59
59
  ]);
60
60
  });
61
61
  });
62
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdGlvbi51bml0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc291cmNlL2hlbHBlcnMvc2VjdGlvbi51bml0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBQ3JELE9BQU8sRUFBRSxZQUFZLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxjQUFjLENBQUE7QUFFL0QsUUFBUSxDQUFDLGNBQWMsRUFBRSxHQUFHLEVBQUU7SUFDNUIsTUFBTSxRQUFRLEdBQUc7UUFDZixFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRTtRQUM5QixFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRTtRQUNqQyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRTtLQUM1QyxDQUFBO0lBRUQsRUFBRSxDQUFDLHVDQUF1QyxFQUFFLEdBQUcsRUFBRTtRQUMvQyxNQUFNLENBQUMsWUFBWSxDQUFDLGtCQUFrQixFQUFFLFFBQVEsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUM1RSxDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQywwREFBMEQsRUFBRSxHQUFHLEVBQUU7UUFDbEUsTUFBTSxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUUsUUFBUSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ2xFLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLHVDQUF1QyxFQUFFLEdBQUcsRUFBRTtRQUMvQyxNQUFNLENBQUMsWUFBWSxDQUFDLG1CQUFtQixFQUFFLFFBQVEsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUN6RSxD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cmliZSwgZXhwZWN0LCBpdCB9IGZyb20gXCJ2aXRlLXBsdXMvdGVzdFwiXG5pbXBvcnQgeyBtYXRjaFNlY3Rpb24sIHBhcnRpdGlvbkJ5U2VjdGlvbiB9IGZyb20gXCIuL3NlY3Rpb24udHNcIlxuXG5kZXNjcmliZShcIm1hdGNoU2VjdGlvblwiLCAoKSA9PiB7XG4gIGNvbnN0IHNlY3Rpb25zID0gW1xuICAgIHsgdGl0bGU6IFwiRG9jc1wiLCBwcmVmaXg6IFwiL1wiIH0sXG4gICAgeyB0aXRsZTogXCJBUElcIiwgcHJlZml4OiBcIi9hcGkvXCIgfSxcbiAgICB7IHRpdGxlOiBcIkFQSSBBdXRoXCIsIHByZWZpeDogXCIvYXBpL2F1dGgvXCIgfSxcbiAgXVxuXG4gIGl0KFwic2hvdWxkIG1hdGNoIHRoZSBtb3N0IHNwZWNpZmljIHByZWZpeFwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KG1hdGNoU2VjdGlvbihcIi9hcGkvYXV0aC9sb2dpbi9cIiwgc2VjdGlvbnMpPy50aXRsZSkudG9CZShcIkFQSSBBdXRoXCIpXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgbWF0Y2ggYSBsZXNzIHNwZWNpZmljIHByZWZpeCB3aGVuIG5vIGRlZXBlciBtYXRjaFwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KG1hdGNoU2VjdGlvbihcIi9hcGkvdXNlcnMvXCIsIHNlY3Rpb25zKT8udGl0bGUpLnRvQmUoXCJBUElcIilcbiAgfSlcblxuICBpdChcInNob3VsZCBtYXRjaCByb290IHNlY3Rpb24gYXMgZmFsbGJhY2tcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChtYXRjaFNlY3Rpb24oXCIvZ2V0dGluZy1zdGFydGVkL1wiLCBzZWN0aW9ucyk/LnRpdGxlKS50b0JlKFwiRG9jc1wiKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIHJldHVybiB1bmRlZmluZWQgd2hlbiBubyBzZWN0aW9uIG1hdGNoZXNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IG5hcnJvdyA9IFt7IHRpdGxlOiBcIkFQSVwiLCBwcmVmaXg6IFwiL2FwaS9cIiB9XVxuICAgIGV4cGVjdChtYXRjaFNlY3Rpb24oXCIvZ2V0dGluZy1zdGFydGVkL1wiLCBuYXJyb3cpKS50b0JlVW5kZWZpbmVkKClcbiAgfSlcblxuICBpdChcInNob3VsZCBtYXRjaCBhIHNpbmdsZSByb290IHNlY3Rpb24gZm9yIGFsbCBhcnRpY2xlc1wiLCAoKSA9PiB7XG4gICAgY29uc3Qgcm9vdCA9IFt7IHRpdGxlOiBcIkRvY3NcIiwgcHJlZml4OiBcIi9cIiB9XVxuICAgIGV4cGVjdChtYXRjaFNlY3Rpb24oXCIvYW55dGhpbmcvZGVlcC9wYXRoL1wiLCByb290KT8udGl0bGUpLnRvQmUoXCJEb2NzXCIpXG4gIH0pXG59KVxuXG5kZXNjcmliZShcInBhcnRpdGlvbkJ5U2VjdGlvblwiLCAoKSA9PiB7XG4gIGNvbnN0IHNlY3Rpb25zID0gW1xuICAgIHsgdGl0bGU6IFwiRG9jc1wiLCBwcmVmaXg6IFwiL1wiIH0sXG4gICAgeyB0aXRsZTogXCJBUElcIiwgcHJlZml4OiBcIi9hcGkvXCIgfSxcbiAgXVxuXG4gIGNvbnN0IGFydGljbGVzID0gW1xuICAgIHsgcGF0aDogXCIvZ2V0dGluZy1zdGFydGVkL1wiIH0sXG4gICAgeyBwYXRoOiBcIi9ndWlkZS9cIiB9LFxuICAgIHsgcGF0aDogXCIvYXBpL3VzZXJzL1wiIH0sXG4gICAgeyBwYXRoOiBcIi9hcGkvYXV0aC9cIiB9LFxuICBdXG5cbiAgaXQoXCJzaG91bGQgc3BsaXQgYXJ0aWNsZXMgaW50byBzZWN0aW9uIGJ1Y2tldHNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IHBhcnRpdGlvbkJ5U2VjdGlvbihhcnRpY2xlcywgc2VjdGlvbnMpXG4gICAgZXhwZWN0KHJlc3VsdC5nZXQoXCIvXCIpPy5tYXAoYSA9PiBhLnBhdGgpKS50b0VxdWFsKFtcbiAgICAgIFwiL2dldHRpbmctc3RhcnRlZC9cIixcbiAgICAgIFwiL2d1aWRlL1wiLFxuICAgIF0pXG4gICAgZXhwZWN0KHJlc3VsdC5nZXQoXCIvYXBpL1wiKT8ubWFwKGEgPT4gYS5wYXRoKSkudG9FcXVhbChbXG4gICAgICBcIi9hcGkvdXNlcnMvXCIsXG4gICAgICBcIi9hcGkvYXV0aC9cIixcbiAgICBdKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIHB1dCB1bm1hdGNoZWQgYXJ0aWNsZXMgaW4gX19kZWZhdWx0X18gYnVja2V0XCIsICgpID0+IHtcbiAgICBjb25zdCBuYXJyb3cgPSBbeyB0aXRsZTogXCJBUElcIiwgcHJlZml4OiBcIi9hcGkvXCIgfV1cbiAgICBjb25zdCByZXN1bHQgPSBwYXJ0aXRpb25CeVNlY3Rpb24oYXJ0aWNsZXMsIG5hcnJvdylcbiAgICBleHBlY3QocmVzdWx0LmdldChcIl9fZGVmYXVsdF9fXCIpPy5tYXAoYSA9PiBhLnBhdGgpKS50b0VxdWFsKFtcbiAgICAgIFwiL2dldHRpbmctc3RhcnRlZC9cIixcbiAgICAgIFwiL2d1aWRlL1wiLFxuICAgIF0pXG4gICAgZXhwZWN0KHJlc3VsdC5nZXQoXCIvYXBpL1wiKT8ubWFwKGEgPT4gYS5wYXRoKSkudG9FcXVhbChbXG4gICAgICBcIi9hcGkvdXNlcnMvXCIsXG4gICAgICBcIi9hcGkvYXV0aC9cIixcbiAgICBdKVxuICB9KVxufSlcbiJdfQ==
62
+ describe("customSectionActive", () => {
63
+ it("should not match an absolute http url", () => {
64
+ expect(customSectionActive("https://x.com/y", "/y/")).toBe(false);
65
+ expect(customSectionActive("http://x.com/y", "/y/")).toBe(false);
66
+ });
67
+ it("should not match a protocol-relative url", () => {
68
+ expect(customSectionActive("//cdn.x.com/y", "/y/")).toBe(false);
69
+ });
70
+ it("should not match a hash url", () => {
71
+ expect(customSectionActive("#section", "/section/")).toBe(false);
72
+ });
73
+ it("should match the exact path", () => {
74
+ expect(customSectionActive("/about", "/about/")).toBe(true);
75
+ expect(customSectionActive("/about/", "/about/")).toBe(true);
76
+ });
77
+ it("should match a descendant path", () => {
78
+ expect(customSectionActive("/about", "/about/team/")).toBe(true);
79
+ });
80
+ it("should not match a sibling path with shared prefix", () => {
81
+ expect(customSectionActive("/about", "/aboutus/")).toBe(false);
82
+ });
83
+ it("should match exact root only", () => {
84
+ expect(customSectionActive("/", "/")).toBe(true);
85
+ expect(customSectionActive("/", "/about/")).toBe(false);
86
+ });
87
+ it("should ignore query and hash on the url", () => {
88
+ expect(customSectionActive("/about?x=1", "/about/")).toBe(true);
89
+ expect(customSectionActive("/about#top", "/about/team/")).toBe(true);
90
+ });
91
+ });
92
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdGlvbi51bml0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc291cmNlL2hlbHBlcnMvc2VjdGlvbi51bml0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBQ3JELE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsWUFBWSxFQUNaLGtCQUFrQixHQUNuQixNQUFNLGNBQWMsQ0FBQTtBQUVyQixRQUFRLENBQUMsY0FBYyxFQUFFLEdBQUcsRUFBRTtJQUM1QixNQUFNLFFBQVEsR0FBRztRQUNmLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFO1FBQzlCLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFO1FBQ2pDLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFO0tBQzVDLENBQUE7SUFFRCxFQUFFLENBQUMsdUNBQXVDLEVBQUUsR0FBRyxFQUFFO1FBQy9DLE1BQU0sQ0FBQyxZQUFZLENBQUMsa0JBQWtCLEVBQUUsUUFBUSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQzVFLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLDBEQUEwRCxFQUFFLEdBQUcsRUFBRTtRQUNsRSxNQUFNLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxRQUFRLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDbEUsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsdUNBQXVDLEVBQUUsR0FBRyxFQUFFO1FBQy9DLE1BQU0sQ0FBQyxZQUFZLENBQUMsbUJBQW1CLEVBQUUsUUFBUSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FB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QUFFLENBQUMsb0RBQW9ELEVBQUUsR0FBRyxFQUFFO1FBQzVELE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDaEUsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsOEJBQThCLEVBQUUsR0FBRyxFQUFFO1FBQ3RDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDaEQsTUFBTSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUN6RCxDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQyx5Q0FBeUMsRUFBRSxHQUFHLEVBQUU7UUFDakQsTUFBTSxDQUFDLG1CQUFtQixDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUMvRCxNQUFNLENBQUMsbUJBQW1CLENBQUMsWUFBWSxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ3RFLENBQUMsQ0FBQyxDQUFBO0FBQ0osQ0FBQyxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBkZXNjcmliZSwgZXhwZWN0LCBpdCB9IGZyb20gXCJ2aXRlLXBsdXMvdGVzdFwiXG5pbXBvcnQge1xuICBjdXN0b21TZWN0aW9uQWN0aXZlLFxuICBtYXRjaFNlY3Rpb24sXG4gIHBhcnRpdGlvbkJ5U2VjdGlvbixcbn0gZnJvbSBcIi4vc2VjdGlvbi50c1wiXG5cbmRlc2NyaWJlKFwibWF0Y2hTZWN0aW9uXCIsICgpID0+IHtcbiAgY29uc3Qgc2VjdGlvbnMgPSBbXG4gICAgeyB0aXRsZTogXCJEb2NzXCIsIHByZWZpeDogXCIvXCIgfSxcbiAgICB7IHRpdGxlOiBcIkFQSVwiLCBwcmVmaXg6IFwiL2FwaS9cIiB9LFxuICAgIHsgdGl0bGU6IFwiQVBJIEF1dGhcIiwgcHJlZml4OiBcIi9hcGkvYXV0aC9cIiB9LFxuICBdXG5cbiAgaXQoXCJzaG91bGQgbWF0Y2ggdGhlIG1vc3Qgc3BlY2lmaWMgcHJlZml4XCIsICgpID0+IHtcbiAgICBleHBlY3QobWF0Y2hTZWN0aW9uKFwiL2FwaS9hdXRoL2xvZ2luL1wiLCBzZWN0aW9ucyk/LnRpdGxlKS50b0JlKFwiQVBJIEF1dGhcIilcbiAgfSlcblxuICBpdChcInNob3VsZCBtYXRjaCBhIGxlc3Mgc3BlY2lmaWMgcHJlZml4IHdoZW4gbm8gZGVlcGVyIG1hdGNoXCIsICgpID0+IHtcbiAgICBleHBlY3QobWF0Y2hTZWN0aW9uKFwiL2FwaS91c2Vycy9cIiwgc2VjdGlvbnMpPy50aXRsZSkudG9CZShcIkFQSVwiKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIG1hdGNoIHJvb3Qgc2VjdGlvbiBhcyBmYWxsYmFja1wiLCAoKSA9PiB7XG4gICAgZXhwZWN0KG1hdGNoU2VjdGlvbihcIi9nZXR0aW5nLXN0YXJ0ZWQvXCIsIHNlY3Rpb25zKT8udGl0bGUpLnRvQmUoXCJEb2NzXCIpXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgcmV0dXJuIHVuZGVmaW5lZCB3aGVuIG5vIHNlY3Rpb24gbWF0Y2hlc1wiLCAoKSA9PiB7XG4gICAgY29uc3QgbmFycm93ID0gW3sgdGl0bGU6IFwiQVBJXCIsIHByZWZpeDogXCIvYXBpL1wiIH1dXG4gICAgZXhwZWN0KG1hdGNoU2VjdGlvbihcIi9nZXR0aW5nLXN0YXJ0ZWQvXCIsIG5hcnJvdykpLnRvQmVVbmRlZmluZWQoKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIG1hdGNoIGEgc2luZ2xlIHJvb3Qgc2VjdGlvbiBmb3IgYWxsIGFydGljbGVzXCIsICgpID0+IHtcbiAgICBjb25zdCByb290ID0gW3sgdGl0bGU6IFwiRG9jc1wiLCBwcmVmaXg6IFwiL1wiIH1dXG4gICAgZXhwZWN0KG1hdGNoU2VjdGlvbihcIi9hbnl0aGluZy9kZWVwL3BhdGgvXCIsIHJvb3QpPy50aXRsZSkudG9CZShcIkRvY3NcIilcbiAgfSlcbn0pXG5cbmRlc2NyaWJlKFwicGFydGl0aW9uQnlTZWN0aW9uXCIsICgpID0+IHtcbiAgY29uc3Qgc2VjdGlvbnMgPSBbXG4gICAgeyB0aXRsZTogXCJEb2NzXCIsIHByZWZpeDogXCIvXCIgfSxcbiAgICB7IHRpdGxlOiBcIkFQSVwiLCBwcmVmaXg6IFwiL2FwaS9cIiB9LFxuICBdXG5cbiAgY29uc3QgYXJ0aWNsZXMgPSBbXG4gICAgeyBwYXRoOiBcIi9nZXR0aW5nLXN0YXJ0ZWQvXCIgfSxcbiAgICB7IHBhdGg6IFwiL2d1aWRlL1wiIH0sXG4gICAgeyBwYXRoOiBcIi9hcGkvdXNlcnMvXCIgfSxcbiAgICB7IHBhdGg6IFwiL2FwaS9hdXRoL1wiIH0sXG4gIF1cblxuICBpdChcInNob3VsZCBzcGxpdCBhcnRpY2xlcyBpbnRvIHNlY3Rpb24gYnVja2V0c1wiLCAoKSA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gcGFydGl0aW9uQnlTZWN0aW9uKGFydGljbGVzLCBzZWN0aW9ucylcbiAgICBleHBlY3QocmVzdWx0LmdldChcIi9cIik/Lm1hcChhID0+IGEucGF0aCkpLnRvRXF1YWwoW1xuICAgICAgXCIvZ2V0dGluZy1zdGFydGVkL1wiLFxuICAgICAgXCIvZ3VpZGUvXCIsXG4gICAgXSlcbiAgICBleHBlY3QocmVzdWx0LmdldChcIi9hcGkvXCIpPy5tYXAoYSA9PiBhLnBhdGgpKS50b0VxdWFsKFtcbiAgICAgIFwiL2FwaS91c2Vycy9cIixcbiAgICAgIFwiL2FwaS9hdXRoL1wiLFxuICAgIF0pXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgcHV0IHVubWF0Y2hlZCBhcnRpY2xlcyBpbiBfX2RlZmF1bHRfXyBidWNrZXRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IG5hcnJvdyA9IFt7IHRpdGxlOiBcIkFQSVwiLCBwcmVmaXg6IFwiL2FwaS9cIiB9XVxuICAgIGNvbnN0IHJlc3VsdCA9IHBhcnRpdGlvbkJ5U2VjdGlvbihhcnRpY2xlcywgbmFycm93KVxuICAgIGV4cGVjdChyZXN1bHQuZ2V0KFwiX19kZWZhdWx0X19cIik/Lm1hcChhID0+IGEucGF0aCkpLnRvRXF1YWwoW1xuICAgICAgXCIvZ2V0dGluZy1zdGFydGVkL1wiLFxuICAgICAgXCIvZ3VpZGUvXCIsXG4gICAgXSlcbiAgICBleHBlY3QocmVzdWx0LmdldChcIi9hcGkvXCIpPy5tYXAoYSA9PiBhLnBhdGgpKS50b0VxdWFsKFtcbiAgICAgIFwiL2FwaS91c2Vycy9cIixcbiAgICAgIFwiL2FwaS9hdXRoL1wiLFxuICAgIF0pXG4gIH0pXG59KVxuXG5kZXNjcmliZShcImN1c3RvbVNlY3Rpb25BY3RpdmVcIiwgKCkgPT4ge1xuICBpdChcInNob3VsZCBub3QgbWF0Y2ggYW4gYWJzb2x1dGUgaHR0cCB1cmxcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChjdXN0b21TZWN0aW9uQWN0aXZlKFwiaHR0cHM6Ly94LmNvbS95XCIsIFwiL3kvXCIpKS50b0JlKGZhbHNlKVxuICAgIGV4cGVjdChjdXN0b21TZWN0aW9uQWN0aXZlKFwiaHR0cDovL3guY29tL3lcIiwgXCIveS9cIikpLnRvQmUoZmFsc2UpXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgbm90IG1hdGNoIGEgcHJvdG9jb2wtcmVsYXRpdmUgdXJsXCIsICgpID0+IHtcbiAgICBleHBlY3QoY3VzdG9tU2VjdGlvbkFjdGl2ZShcIi8vY2RuLnguY29tL3lcIiwgXCIveS9cIikpLnRvQmUoZmFsc2UpXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgbm90IG1hdGNoIGEgaGFzaCB1cmxcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChjdXN0b21TZWN0aW9uQWN0aXZlKFwiI3NlY3Rpb25cIiwgXCIvc2VjdGlvbi9cIikpLnRvQmUoZmFsc2UpXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgbWF0Y2ggdGhlIGV4YWN0IHBhdGhcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChjdXN0b21TZWN0aW9uQWN0aXZlKFwiL2Fib3V0XCIsIFwiL2Fib3V0L1wiKSkudG9CZSh0cnVlKVxuICAgIGV4cGVjdChjdXN0b21TZWN0aW9uQWN0aXZlKFwiL2Fib3V0L1wiLCBcIi9hYm91dC9cIikpLnRvQmUodHJ1ZSlcbiAgfSlcblxuICBpdChcInNob3VsZCBtYXRjaCBhIGRlc2NlbmRhbnQgcGF0aFwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KGN1c3RvbVNlY3Rpb25BY3RpdmUoXCIvYWJvdXRcIiwgXCIvYWJvdXQvdGVhbS9cIikpLnRvQmUodHJ1ZSlcbiAgfSlcblxuICBpdChcInNob3VsZCBub3QgbWF0Y2ggYSBzaWJsaW5nIHBhdGggd2l0aCBzaGFyZWQgcHJlZml4XCIsICgpID0+IHtcbiAgICBleHBlY3QoY3VzdG9tU2VjdGlvbkFjdGl2ZShcIi9hYm91dFwiLCBcIi9hYm91dHVzL1wiKSkudG9CZShmYWxzZSlcbiAgfSlcblxuICBpdChcInNob3VsZCBtYXRjaCBleGFjdCByb290IG9ubHlcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChjdXN0b21TZWN0aW9uQWN0aXZlKFwiL1wiLCBcIi9cIikpLnRvQmUodHJ1ZSlcbiAgICBleHBlY3QoY3VzdG9tU2VjdGlvbkFjdGl2ZShcIi9cIiwgXCIvYWJvdXQvXCIpKS50b0JlKGZhbHNlKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIGlnbm9yZSBxdWVyeSBhbmQgaGFzaCBvbiB0aGUgdXJsXCIsICgpID0+IHtcbiAgICBleHBlY3QoY3VzdG9tU2VjdGlvbkFjdGl2ZShcIi9hYm91dD94PTFcIiwgXCIvYWJvdXQvXCIpKS50b0JlKHRydWUpXG4gICAgZXhwZWN0KGN1c3RvbVNlY3Rpb25BY3RpdmUoXCIvYWJvdXQjdG9wXCIsIFwiL2Fib3V0L3RlYW0vXCIpKS50b0JlKHRydWUpXG4gIH0pXG59KVxuIl19
@@ -7,15 +7,27 @@ import type { ConfigEnv, UserConfig as ViteUserConfig } from "vite";
7
7
  * merge, etc. Use this for deployment-target tweaks (e.g. CF Workers
8
8
  * via `environments.ssr.resolve.conditions: ["workerd", ...]`). */
9
9
  export type ViteOverride = ViteUserConfig | ((env: ConfigEnv) => ViteUserConfig | Promise<ViteUserConfig>);
10
+ /** Sub-path mount. String form is used as-is; function form is called
11
+ * with Vite's `command` (`"serve"` in dev, `"build"` in production) so
12
+ * the user can branch (typical case: serve at `/` in dev but at
13
+ * `/repo/` in production for GitHub Pages). The build pipeline
14
+ * resolves it to a string before any runtime sees it. */
15
+ export type Base = string | ((command: "build" | "serve") => string | undefined);
10
16
  /**
11
17
  * User-provided configuration for Livemark.
18
+ *
19
+ * `vite` and `base` are lifted from `unknown` to their public types so
20
+ * `defineConfig` shows the right shape in editors. Use this type for
21
+ * the input to `defineConfig` — it keeps defaulted fields optional
22
+ * (because zod input ≠ output for fields with `.default()`).
12
23
  */
13
- export type UserConfig = Omit<z.infer<typeof UserConfig>, "vite"> & {
24
+ export type UserConfig = Omit<z.input<typeof UserConfig>, "vite" | "base"> & {
14
25
  vite?: ViteOverride;
26
+ base?: Base;
15
27
  };
16
28
  export declare const UserConfig: z.ZodObject<{
17
29
  site: z.ZodOptional<z.ZodString>;
18
- base: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string | undefined, string | undefined>>;
30
+ base: z.ZodOptional<z.ZodUnknown>;
19
31
  favicon: z.ZodOptional<z.ZodString>;
20
32
  logo: z.ZodOptional<z.ZodString>;
21
33
  title: z.ZodDefault<z.ZodString>;
@@ -137,7 +149,7 @@ export declare const UserConfig: z.ZodObject<{
137
149
  header: "header";
138
150
  sidebar: "sidebar";
139
151
  }>>;
140
- type: z.ZodLiteral<"external">;
152
+ type: z.ZodLiteral<"custom">;
141
153
  url: z.ZodString;
142
154
  }, z.core.$strip>], "type">>>>;
143
155
  patches: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -164,11 +176,12 @@ export declare const UserConfig: z.ZodObject<{
164
176
  }, z.core.$strip>>>;
165
177
  vite: z.ZodOptional<z.ZodUnknown>;
166
178
  }, z.core.$strip>;
167
- /** Website configuration injected at build time via Vite define */
179
+ /** Website configuration injected at build time via Vite define.
180
+ * `base` is strictly a string here — the build pipeline has already
181
+ * resolved any function form via `resolveBase()`. */
168
182
  export type WebsiteConfig = z.infer<typeof WebsiteConfig>;
169
183
  export declare const WebsiteConfig: z.ZodObject<{
170
184
  site: z.ZodOptional<z.ZodString>;
171
- base: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string | undefined, string | undefined>>;
172
185
  favicon: z.ZodOptional<z.ZodString>;
173
186
  logo: z.ZodOptional<z.ZodString>;
174
187
  title: z.ZodDefault<z.ZodString>;
@@ -219,9 +232,10 @@ export declare const WebsiteConfig: z.ZodObject<{
219
232
  header: "header";
220
233
  sidebar: "sidebar";
221
234
  }>>;
222
- type: z.ZodLiteral<"external">;
235
+ type: z.ZodLiteral<"custom">;
223
236
  url: z.ZodString;
224
237
  }, z.core.$strip>], "type">>>>;
238
+ base: z.ZodOptional<z.ZodString>;
225
239
  }, z.core.$strip>;
226
240
  /**
227
241
  * System-computed configuration derived from the config file location.
@@ -234,14 +248,18 @@ export declare const SystemConfig: z.ZodObject<{
234
248
  /**
235
249
  * Fully resolved Livemark configuration.
236
250
  *
237
- * `vite` stays `unknown` here because that's what the runtime schema
251
+ * `vite` stays `unknown` because that's what the runtime schema
238
252
  * produces — consumer-facing typing happens via {@link UserConfig} so
239
- * `defineConfig` shows the right shape in editors.
253
+ * `defineConfig` shows the right shape in editors. `base` is lifted to
254
+ * `string | undefined` because `loadConfig()` resolves any function
255
+ * form via `resolveBase()` before returning.
240
256
  */
241
- export type Config = z.infer<typeof Config>;
257
+ export type Config = Omit<z.infer<typeof Config>, "base"> & {
258
+ base?: string;
259
+ };
242
260
  export declare const Config: z.ZodObject<{
243
261
  site: z.ZodOptional<z.ZodString>;
244
- base: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string | undefined, string | undefined>>;
262
+ base: z.ZodOptional<z.ZodUnknown>;
245
263
  favicon: z.ZodOptional<z.ZodString>;
246
264
  logo: z.ZodOptional<z.ZodString>;
247
265
  title: z.ZodDefault<z.ZodString>;
@@ -363,7 +381,7 @@ export declare const Config: z.ZodObject<{
363
381
  header: "header";
364
382
  sidebar: "sidebar";
365
383
  }>>;
366
- type: z.ZodLiteral<"external">;
384
+ type: z.ZodLiteral<"custom">;
367
385
  url: z.ZodString;
368
386
  }, z.core.$strip>], "type">>>>;
369
387
  patches: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -5,15 +5,12 @@ import { Section } from "./section.js";
5
5
  import { CodeThemeDark, CodeThemeLight } from "./theme.js";
6
6
  export const UserConfig = z.object({
7
7
  site: z.string().optional(),
8
- base: z
9
- .string()
10
- .optional()
11
- .transform(v => {
12
- if (!v)
13
- return undefined;
14
- const trimmed = v.replace(/^\/|\/$/g, "");
15
- return trimmed ? `/${trimmed}` : undefined;
16
- }),
8
+ // Stored as `unknown` in the schema (zod can't type a function and
9
+ // string union meaningfully); the public TypeScript surface above
10
+ // lifts it back to `Base` for editor support. The build pipeline
11
+ // resolves it via `resolveBase()` before any runtime consumer sees
12
+ // it, so the runtime `WebsiteConfig.base` is strictly `string`.
13
+ base: z.unknown().optional(),
17
14
  favicon: z.string().optional(),
18
15
  logo: z.string().optional(),
19
16
  title: z.string().default("Livemark"),
@@ -34,15 +31,16 @@ export const WebsiteConfig = UserConfig.pick({
34
31
  title: true,
35
32
  description: true,
36
33
  site: true,
37
- base: true,
38
34
  favicon: true,
39
35
  logo: true,
40
36
  links: true,
41
37
  sections: true,
38
+ }).extend({
39
+ base: z.string().optional(),
42
40
  });
43
41
  export const SystemConfig = z.object({
44
42
  root: z.string(),
45
43
  configPath: z.string(),
46
44
  });
47
45
  export const Config = UserConfig.merge(SystemConfig);
48
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc291cmNlL21vZGVscy9jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEtBQUssQ0FBQTtBQUV2QixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQ2hDLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDbEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQTtBQUN0QyxPQUFPLEVBQUUsYUFBYSxFQUFFLGNBQWMsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQWtCMUQsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDakMsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDM0IsSUFBSSxFQUFFLENBQUM7U0FDSixNQUFNLEVBQUU7U0FDUixRQUFRLEVBQUU7U0FDVixTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUU7UUFDYixJQUFJLENBQUMsQ0FBQztZQUFFLE9BQU8sU0FBUyxDQUFBO1FBQ3hCLE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFBO1FBQ3pDLE9BQU8sT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUE7SUFDNUMsQ0FBQyxDQUFDO0lBQ0osT0FBTyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDOUIsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDM0IsS0FBSyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDO0lBQ3JDLFdBQVcsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsT0FBTyxDQUFDLHlCQUF5QixDQUFDO0lBQzFELE9BQU8sRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUM7SUFDdEUsT0FBTyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFO0lBQzlELGNBQWMsRUFBRSxjQUFjLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDO0lBQzFELGFBQWEsRUFBRSxhQUFhLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDO0lBQ3hELEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRTtJQUMvQixRQUFRLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUU7SUFDckMsT0FBTyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxFQUFFO0lBQ2xDLHNFQUFzRTtJQUN0RSxtRUFBbUU7SUFDbkUsa0VBQWtFO0lBQ2xFLElBQUksRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFO0NBQzdCLENBQUMsQ0FBQTtBQUlGLE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDO0lBQzNDLEtBQUssRUFBRSxJQUFJO0lBQ1gsV0FBVyxFQUFFLElBQUk7SUFDakIsSUFBSSxFQUFFLElBQUk7SUFDVixJQUFJLEVBQUUsSUFBSTtJQUNWLE9BQU8sRUFBRSxJQUFJO0lBQ2IsSUFBSSxFQUFFLElBQUk7SUFDVixLQUFLLEVBQUUsSUFBSTtJQUNYLFFBQVEsRUFBRSxJQUFJO0NBQ2YsQ0FBQyxDQUFBO0FBTUYsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDbkMsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUU7SUFDaEIsVUFBVSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUU7Q0FDdkIsQ0FBQyxDQUFBO0FBVUYsTUFBTSxDQUFDLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiXG5pbXBvcnQgdHlwZSB7IENvbmZpZ0VudiwgVXNlckNvbmZpZyBhcyBWaXRlVXNlckNvbmZpZyB9IGZyb20gXCJ2aXRlXCJcbmltcG9ydCB7IExpbmsgfSBmcm9tIFwiLi9saW5rLnRzXCJcbmltcG9ydCB7IFBhdGNoIH0gZnJvbSBcIi4vcGF0Y2gudHNcIlxuaW1wb3J0IHsgU2VjdGlvbiB9IGZyb20gXCIuL3NlY3Rpb24udHNcIlxuaW1wb3J0IHsgQ29kZVRoZW1lRGFyaywgQ29kZVRoZW1lTGlnaHQgfSBmcm9tIFwiLi90aGVtZS50c1wiXG5cbi8qKiBFc2NhcGUgaGF0Y2ggZm9yIGFyYml0cmFyeSBWaXRlIGNvbmZpZyDigJQgYWNjZXB0cyBlaXRoZXIgYSBjb25maWdcbiAqICBvYmplY3QgKHNpbXBsZSBvdmVycmlkZXMpIG9yIGEgZnVuY3Rpb24gZm9ybSAoYChlbnYpID0+IGNvbmZpZ2AsXG4gKiAgbWF0Y2hpbmcgVml0ZSdzIG93biBgZGVmaW5lQ29uZmlnYCkuIE1lcmdlZCBvbiB0b3Agb2YgbGl2ZW1hcmsnc1xuICogIGRlZmF1bHRzIHZpYSBgbWVyZ2VDb25maWdgLCBzbyBwbHVnaW4gYXJyYXlzIGNvbmNhdGVuYXRlLCBkZWZpbmVzXG4gKiAgbWVyZ2UsIGV0Yy4gVXNlIHRoaXMgZm9yIGRlcGxveW1lbnQtdGFyZ2V0IHR3ZWFrcyAoZS5nLiBDRiBXb3JrZXJzXG4gKiAgdmlhIGBlbnZpcm9ubWVudHMuc3NyLnJlc29sdmUuY29uZGl0aW9uczogW1wid29ya2VyZFwiLCAuLi5dYCkuICovXG5leHBvcnQgdHlwZSBWaXRlT3ZlcnJpZGUgPVxuICB8IFZpdGVVc2VyQ29uZmlnXG4gIHwgKChlbnY6IENvbmZpZ0VudikgPT4gVml0ZVVzZXJDb25maWcgfCBQcm9taXNlPFZpdGVVc2VyQ29uZmlnPilcblxuLyoqXG4gKiBVc2VyLXByb3ZpZGVkIGNvbmZpZ3VyYXRpb24gZm9yIExpdmVtYXJrLlxuICovXG5leHBvcnQgdHlwZSBVc2VyQ29uZmlnID0gT21pdDx6LmluZmVyPHR5cGVvZiBVc2VyQ29uZmlnPiwgXCJ2aXRlXCI+ICYge1xuICB2aXRlPzogVml0ZU92ZXJyaWRlXG59XG5leHBvcnQgY29uc3QgVXNlckNvbmZpZyA9IHoub2JqZWN0KHtcbiAgc2l0ZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICBiYXNlOiB6XG4gICAgLnN0cmluZygpXG4gICAgLm9wdGlvbmFsKClcbiAgICAudHJhbnNmb3JtKHYgPT4ge1xuICAgICAgaWYgKCF2KSByZXR1cm4gdW5kZWZpbmVkXG4gICAgICBjb25zdCB0cmltbWVkID0gdi5yZXBsYWNlKC9eXFwvfFxcLyQvZywgXCJcIilcbiAgICAgIHJldHVybiB0cmltbWVkID8gYC8ke3RyaW1tZWR9YCA6IHVuZGVmaW5lZFxuICAgIH0pLFxuICBmYXZpY29uOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gIGxvZ286IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgdGl0bGU6IHouc3RyaW5nKCkuZGVmYXVsdChcIkxpdmVtYXJrXCIpLFxuICBkZXNjcmlwdGlvbjogei5zdHJpbmcoKS5kZWZhdWx0KFwiTWFya2Rvd24gc2l0ZSBnZW5lcmF0b3JcIiksXG4gIGluY2x1ZGU6IHoudW5pb24oW3ouc3RyaW5nKCksIHouYXJyYXkoei5zdHJpbmcoKSldKS5kZWZhdWx0KFwiKiovKi5tZFwiKSxcbiAgZXhjbHVkZTogei51bmlvbihbei5zdHJpbmcoKSwgei5hcnJheSh6LnN0cmluZygpKV0pLm9wdGlvbmFsKCksXG4gIGNvZGVUaGVtZUxpZ2h0OiBDb2RlVGhlbWVMaWdodC5kZWZhdWx0KFwiY2F0cHB1Y2Npbi1sYXR0ZVwiKSxcbiAgY29kZVRoZW1lRGFyazogQ29kZVRoZW1lRGFyay5kZWZhdWx0KFwiY2F0cHB1Y2Npbi1tb2NoYVwiKSxcbiAgbGlua3M6IHouYXJyYXkoTGluaykub3B0aW9uYWwoKSxcbiAgc2VjdGlvbnM6IHouYXJyYXkoU2VjdGlvbikub3B0aW9uYWwoKSxcbiAgcGF0Y2hlczogei5hcnJheShQYXRjaCkub3B0aW9uYWwoKSxcbiAgLy8gU3RvcmVkIGFzIGB1bmtub3duYCBpbiB0aGUgc2NoZW1hICh6b2QgY2FuJ3QgdHlwZSBhIFZpdGUgVXNlckNvbmZpZ1xuICAvLyBvciBhIGZ1bmN0aW9uIHJldHVybmluZyBvbmUgbWVhbmluZ2Z1bGx5KTsgdGhlIHB1YmxpYyBUeXBlU2NyaXB0XG4gIC8vIHN1cmZhY2UgYWJvdmUgbGlmdHMgaXQgYmFjayB0byBWaXRlT3ZlcnJpZGUgZm9yIGVkaXRvciBzdXBwb3J0LlxuICB2aXRlOiB6LnVua25vd24oKS5vcHRpb25hbCgpLFxufSlcblxuLyoqIFdlYnNpdGUgY29uZmlndXJhdGlvbiBpbmplY3RlZCBhdCBidWlsZCB0aW1lIHZpYSBWaXRlIGRlZmluZSAqL1xuZXhwb3J0IHR5cGUgV2Vic2l0ZUNvbmZpZyA9IHouaW5mZXI8dHlwZW9mIFdlYnNpdGVDb25maWc+XG5leHBvcnQgY29uc3QgV2Vic2l0ZUNvbmZpZyA9IFVzZXJDb25maWcucGljayh7XG4gIHRpdGxlOiB0cnVlLFxuICBkZXNjcmlwdGlvbjogdHJ1ZSxcbiAgc2l0ZTogdHJ1ZSxcbiAgYmFzZTogdHJ1ZSxcbiAgZmF2aWNvbjogdHJ1ZSxcbiAgbG9nbzogdHJ1ZSxcbiAgbGlua3M6IHRydWUsXG4gIHNlY3Rpb25zOiB0cnVlLFxufSlcblxuLyoqXG4gKiBTeXN0ZW0tY29tcHV0ZWQgY29uZmlndXJhdGlvbiBkZXJpdmVkIGZyb20gdGhlIGNvbmZpZyBmaWxlIGxvY2F0aW9uLlxuICovXG5leHBvcnQgdHlwZSBTeXN0ZW1Db25maWcgPSB6LmluZmVyPHR5cGVvZiBTeXN0ZW1Db25maWc+XG5leHBvcnQgY29uc3QgU3lzdGVtQ29uZmlnID0gei5vYmplY3Qoe1xuICByb290OiB6LnN0cmluZygpLFxuICBjb25maWdQYXRoOiB6LnN0cmluZygpLFxufSlcblxuLyoqXG4gKiBGdWxseSByZXNvbHZlZCBMaXZlbWFyayBjb25maWd1cmF0aW9uLlxuICpcbiAqIGB2aXRlYCBzdGF5cyBgdW5rbm93bmAgaGVyZSBiZWNhdXNlIHRoYXQncyB3aGF0IHRoZSBydW50aW1lIHNjaGVtYVxuICogcHJvZHVjZXMg4oCUIGNvbnN1bWVyLWZhY2luZyB0eXBpbmcgaGFwcGVucyB2aWEge0BsaW5rIFVzZXJDb25maWd9IHNvXG4gKiBgZGVmaW5lQ29uZmlnYCBzaG93cyB0aGUgcmlnaHQgc2hhcGUgaW4gZWRpdG9ycy5cbiAqL1xuZXhwb3J0IHR5cGUgQ29uZmlnID0gei5pbmZlcjx0eXBlb2YgQ29uZmlnPlxuZXhwb3J0IGNvbnN0IENvbmZpZyA9IFVzZXJDb25maWcubWVyZ2UoU3lzdGVtQ29uZmlnKVxuIl19
46
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc291cmNlL21vZGVscy9jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEtBQUssQ0FBQTtBQUV2QixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQ2hDLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDbEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQTtBQUN0QyxPQUFPLEVBQUUsYUFBYSxFQUFFLGNBQWMsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQStCMUQsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDakMsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDM0IsbUVBQW1FO0lBQ25FLGtFQUFrRTtJQUNsRSxpRUFBaUU7SUFDakUsbUVBQW1FO0lBQ25FLGdFQUFnRTtJQUNoRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUM1QixPQUFPLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUM5QixJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUMzQixLQUFLLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUM7SUFDckMsV0FBVyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMseUJBQXlCLENBQUM7SUFDMUQsT0FBTyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQztJQUN0RSxPQUFPLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUU7SUFDOUQsY0FBYyxFQUFFLGNBQWMsQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUM7SUFDMUQsYUFBYSxFQUFFLGFBQWEsQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUM7SUFDeEQsS0FBSyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFO0lBQy9CLFFBQVEsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsRUFBRTtJQUNyQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLEVBQUU7SUFDbEMsc0VBQXNFO0lBQ3RFLG1FQUFtRTtJQUNuRSxrRUFBa0U7SUFDbEUsSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLEVBQUU7Q0FDN0IsQ0FBQyxDQUFBO0FBTUYsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUM7SUFDM0MsS0FBSyxFQUFFLElBQUk7SUFDWCxXQUFXLEVBQUUsSUFBSTtJQUNqQixJQUFJLEVBQUUsSUFBSTtJQUNWLE9BQU8sRUFBRSxJQUFJO0lBQ2IsSUFBSSxFQUFFLElBQUk7SUFDVixLQUFLLEVBQUUsSUFBSTtJQUNYLFFBQVEsRUFBRSxJQUFJO0NBQ2YsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUNSLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0NBQzVCLENBQUMsQ0FBQTtBQU1GLE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQ25DLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFO0lBQ2hCLFVBQVUsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFO0NBQ3ZCLENBQUMsQ0FBQTtBQWNGLE1BQU0sQ0FBQyxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIlxuaW1wb3J0IHR5cGUgeyBDb25maWdFbnYsIFVzZXJDb25maWcgYXMgVml0ZVVzZXJDb25maWcgfSBmcm9tIFwidml0ZVwiXG5pbXBvcnQgeyBMaW5rIH0gZnJvbSBcIi4vbGluay50c1wiXG5pbXBvcnQgeyBQYXRjaCB9IGZyb20gXCIuL3BhdGNoLnRzXCJcbmltcG9ydCB7IFNlY3Rpb24gfSBmcm9tIFwiLi9zZWN0aW9uLnRzXCJcbmltcG9ydCB7IENvZGVUaGVtZURhcmssIENvZGVUaGVtZUxpZ2h0IH0gZnJvbSBcIi4vdGhlbWUudHNcIlxuXG4vKiogRXNjYXBlIGhhdGNoIGZvciBhcmJpdHJhcnkgVml0ZSBjb25maWcg4oCUIGFjY2VwdHMgZWl0aGVyIGEgY29uZmlnXG4gKiAgb2JqZWN0IChzaW1wbGUgb3ZlcnJpZGVzKSBvciBhIGZ1bmN0aW9uIGZvcm0gKGAoZW52KSA9PiBjb25maWdgLFxuICogIG1hdGNoaW5nIFZpdGUncyBvd24gYGRlZmluZUNvbmZpZ2ApLiBNZXJnZWQgb24gdG9wIG9mIGxpdmVtYXJrJ3NcbiAqICBkZWZhdWx0cyB2aWEgYG1lcmdlQ29uZmlnYCwgc28gcGx1Z2luIGFycmF5cyBjb25jYXRlbmF0ZSwgZGVmaW5lc1xuICogIG1lcmdlLCBldGMuIFVzZSB0aGlzIGZvciBkZXBsb3ltZW50LXRhcmdldCB0d2Vha3MgKGUuZy4gQ0YgV29ya2Vyc1xuICogIHZpYSBgZW52aXJvbm1lbnRzLnNzci5yZXNvbHZlLmNvbmRpdGlvbnM6IFtcIndvcmtlcmRcIiwgLi4uXWApLiAqL1xuZXhwb3J0IHR5cGUgVml0ZU92ZXJyaWRlID1cbiAgfCBWaXRlVXNlckNvbmZpZ1xuICB8ICgoZW52OiBDb25maWdFbnYpID0+IFZpdGVVc2VyQ29uZmlnIHwgUHJvbWlzZTxWaXRlVXNlckNvbmZpZz4pXG5cbi8qKiBTdWItcGF0aCBtb3VudC4gU3RyaW5nIGZvcm0gaXMgdXNlZCBhcy1pczsgZnVuY3Rpb24gZm9ybSBpcyBjYWxsZWRcbiAqICB3aXRoIFZpdGUncyBgY29tbWFuZGAgKGBcInNlcnZlXCJgIGluIGRldiwgYFwiYnVpbGRcImAgaW4gcHJvZHVjdGlvbikgc29cbiAqICB0aGUgdXNlciBjYW4gYnJhbmNoICh0eXBpY2FsIGNhc2U6IHNlcnZlIGF0IGAvYCBpbiBkZXYgYnV0IGF0XG4gKiAgYC9yZXBvL2AgaW4gcHJvZHVjdGlvbiBmb3IgR2l0SHViIFBhZ2VzKS4gVGhlIGJ1aWxkIHBpcGVsaW5lXG4gKiAgcmVzb2x2ZXMgaXQgdG8gYSBzdHJpbmcgYmVmb3JlIGFueSBydW50aW1lIHNlZXMgaXQuICovXG5leHBvcnQgdHlwZSBCYXNlID0gc3RyaW5nIHwgKChjb21tYW5kOiBcImJ1aWxkXCIgfCBcInNlcnZlXCIpID0+IHN0cmluZyB8IHVuZGVmaW5lZClcblxuLyoqXG4gKiBVc2VyLXByb3ZpZGVkIGNvbmZpZ3VyYXRpb24gZm9yIExpdmVtYXJrLlxuICpcbiAqIGB2aXRlYCBhbmQgYGJhc2VgIGFyZSBsaWZ0ZWQgZnJvbSBgdW5rbm93bmAgdG8gdGhlaXIgcHVibGljIHR5cGVzIHNvXG4gKiBgZGVmaW5lQ29uZmlnYCBzaG93cyB0aGUgcmlnaHQgc2hhcGUgaW4gZWRpdG9ycy4gVXNlIHRoaXMgdHlwZSBmb3JcbiAqIHRoZSBpbnB1dCB0byBgZGVmaW5lQ29uZmlnYCDigJQgaXQga2VlcHMgZGVmYXVsdGVkIGZpZWxkcyBvcHRpb25hbFxuICogKGJlY2F1c2Ugem9kIGlucHV0IOKJoCBvdXRwdXQgZm9yIGZpZWxkcyB3aXRoIGAuZGVmYXVsdCgpYCkuXG4gKi9cbmV4cG9ydCB0eXBlIFVzZXJDb25maWcgPSBPbWl0PHouaW5wdXQ8dHlwZW9mIFVzZXJDb25maWc+LCBcInZpdGVcIiB8IFwiYmFzZVwiPiAmIHtcbiAgdml0ZT86IFZpdGVPdmVycmlkZVxuICBiYXNlPzogQmFzZVxufVxuZXhwb3J0IGNvbnN0IFVzZXJDb25maWcgPSB6Lm9iamVjdCh7XG4gIHNpdGU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgLy8gU3RvcmVkIGFzIGB1bmtub3duYCBpbiB0aGUgc2NoZW1hICh6b2QgY2FuJ3QgdHlwZSBhIGZ1bmN0aW9uIGFuZFxuICAvLyBzdHJpbmcgdW5pb24gbWVhbmluZ2Z1bGx5KTsgdGhlIHB1YmxpYyBUeXBlU2NyaXB0IHN1cmZhY2UgYWJvdmVcbiAgLy8gbGlmdHMgaXQgYmFjayB0byBgQmFzZWAgZm9yIGVkaXRvciBzdXBwb3J0LiBUaGUgYnVpbGQgcGlwZWxpbmVcbiAgLy8gcmVzb2x2ZXMgaXQgdmlhIGByZXNvbHZlQmFzZSgpYCBiZWZvcmUgYW55IHJ1bnRpbWUgY29uc3VtZXIgc2Vlc1xuICAvLyBpdCwgc28gdGhlIHJ1bnRpbWUgYFdlYnNpdGVDb25maWcuYmFzZWAgaXMgc3RyaWN0bHkgYHN0cmluZ2AuXG4gIGJhc2U6IHoudW5rbm93bigpLm9wdGlvbmFsKCksXG4gIGZhdmljb246IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgbG9nbzogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICB0aXRsZTogei5zdHJpbmcoKS5kZWZhdWx0KFwiTGl2ZW1hcmtcIiksXG4gIGRlc2NyaXB0aW9uOiB6LnN0cmluZygpLmRlZmF1bHQoXCJNYXJrZG93biBzaXRlIGdlbmVyYXRvclwiKSxcbiAgaW5jbHVkZTogei51bmlvbihbei5zdHJpbmcoKSwgei5hcnJheSh6LnN0cmluZygpKV0pLmRlZmF1bHQoXCIqKi8qLm1kXCIpLFxuICBleGNsdWRlOiB6LnVuaW9uKFt6LnN0cmluZygpLCB6LmFycmF5KHouc3RyaW5nKCkpXSkub3B0aW9uYWwoKSxcbiAgY29kZVRoZW1lTGlnaHQ6IENvZGVUaGVtZUxpZ2h0LmRlZmF1bHQoXCJjYXRwcHVjY2luLWxhdHRlXCIpLFxuICBjb2RlVGhlbWVEYXJrOiBDb2RlVGhlbWVEYXJrLmRlZmF1bHQoXCJjYXRwcHVjY2luLW1vY2hhXCIpLFxuICBsaW5rczogei5hcnJheShMaW5rKS5vcHRpb25hbCgpLFxuICBzZWN0aW9uczogei5hcnJheShTZWN0aW9uKS5vcHRpb25hbCgpLFxuICBwYXRjaGVzOiB6LmFycmF5KFBhdGNoKS5vcHRpb25hbCgpLFxuICAvLyBTdG9yZWQgYXMgYHVua25vd25gIGluIHRoZSBzY2hlbWEgKHpvZCBjYW4ndCB0eXBlIGEgVml0ZSBVc2VyQ29uZmlnXG4gIC8vIG9yIGEgZnVuY3Rpb24gcmV0dXJuaW5nIG9uZSBtZWFuaW5nZnVsbHkpOyB0aGUgcHVibGljIFR5cGVTY3JpcHRcbiAgLy8gc3VyZmFjZSBhYm92ZSBsaWZ0cyBpdCBiYWNrIHRvIFZpdGVPdmVycmlkZSBmb3IgZWRpdG9yIHN1cHBvcnQuXG4gIHZpdGU6IHoudW5rbm93bigpLm9wdGlvbmFsKCksXG59KVxuXG4vKiogV2Vic2l0ZSBjb25maWd1cmF0aW9uIGluamVjdGVkIGF0IGJ1aWxkIHRpbWUgdmlhIFZpdGUgZGVmaW5lLlxuICogIGBiYXNlYCBpcyBzdHJpY3RseSBhIHN0cmluZyBoZXJlIOKAlCB0aGUgYnVpbGQgcGlwZWxpbmUgaGFzIGFscmVhZHlcbiAqICByZXNvbHZlZCBhbnkgZnVuY3Rpb24gZm9ybSB2aWEgYHJlc29sdmVCYXNlKClgLiAqL1xuZXhwb3J0IHR5cGUgV2Vic2l0ZUNvbmZpZyA9IHouaW5mZXI8dHlwZW9mIFdlYnNpdGVDb25maWc+XG5leHBvcnQgY29uc3QgV2Vic2l0ZUNvbmZpZyA9IFVzZXJDb25maWcucGljayh7XG4gIHRpdGxlOiB0cnVlLFxuICBkZXNjcmlwdGlvbjogdHJ1ZSxcbiAgc2l0ZTogdHJ1ZSxcbiAgZmF2aWNvbjogdHJ1ZSxcbiAgbG9nbzogdHJ1ZSxcbiAgbGlua3M6IHRydWUsXG4gIHNlY3Rpb25zOiB0cnVlLFxufSkuZXh0ZW5kKHtcbiAgYmFzZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxufSlcblxuLyoqXG4gKiBTeXN0ZW0tY29tcHV0ZWQgY29uZmlndXJhdGlvbiBkZXJpdmVkIGZyb20gdGhlIGNvbmZpZyBmaWxlIGxvY2F0aW9uLlxuICovXG5leHBvcnQgdHlwZSBTeXN0ZW1Db25maWcgPSB6LmluZmVyPHR5cGVvZiBTeXN0ZW1Db25maWc+XG5leHBvcnQgY29uc3QgU3lzdGVtQ29uZmlnID0gei5vYmplY3Qoe1xuICByb290OiB6LnN0cmluZygpLFxuICBjb25maWdQYXRoOiB6LnN0cmluZygpLFxufSlcblxuLyoqXG4gKiBGdWxseSByZXNvbHZlZCBMaXZlbWFyayBjb25maWd1cmF0aW9uLlxuICpcbiAqIGB2aXRlYCBzdGF5cyBgdW5rbm93bmAgYmVjYXVzZSB0aGF0J3Mgd2hhdCB0aGUgcnVudGltZSBzY2hlbWFcbiAqIHByb2R1Y2VzIOKAlCBjb25zdW1lci1mYWNpbmcgdHlwaW5nIGhhcHBlbnMgdmlhIHtAbGluayBVc2VyQ29uZmlnfSBzb1xuICogYGRlZmluZUNvbmZpZ2Agc2hvd3MgdGhlIHJpZ2h0IHNoYXBlIGluIGVkaXRvcnMuIGBiYXNlYCBpcyBsaWZ0ZWQgdG9cbiAqIGBzdHJpbmcgfCB1bmRlZmluZWRgIGJlY2F1c2UgYGxvYWRDb25maWcoKWAgcmVzb2x2ZXMgYW55IGZ1bmN0aW9uXG4gKiBmb3JtIHZpYSBgcmVzb2x2ZUJhc2UoKWAgYmVmb3JlIHJldHVybmluZy5cbiAqL1xuZXhwb3J0IHR5cGUgQ29uZmlnID0gT21pdDx6LmluZmVyPHR5cGVvZiBDb25maWc+LCBcImJhc2VcIj4gJiB7XG4gIGJhc2U/OiBzdHJpbmdcbn1cbmV4cG9ydCBjb25zdCBDb25maWcgPSBVc2VyQ29uZmlnLm1lcmdlKFN5c3RlbUNvbmZpZylcbiJdfQ==
@@ -37,16 +37,18 @@ export declare const ChangelogSection: z.ZodObject<{
37
37
  source: z.ZodString;
38
38
  version: z.ZodOptional<z.ZodBoolean>;
39
39
  }, z.core.$strip>;
40
- /** External section: renders as a link to an arbitrary URL. */
41
- export type ExternalSection = z.infer<typeof ExternalSection>;
42
- export declare const ExternalSection: z.ZodObject<{
40
+ /** Custom section: renders as a link to an arbitrary URL — absolute
41
+ * (`https://…`) or internal (`/changelog`). Internal URLs participate
42
+ * in active-state highlighting like routed sections. */
43
+ export type CustomSection = z.infer<typeof CustomSection>;
44
+ export declare const CustomSection: z.ZodObject<{
43
45
  icon: z.ZodOptional<z.ZodString>;
44
46
  title: z.ZodString;
45
47
  position: z.ZodDefault<z.ZodEnum<{
46
48
  header: "header";
47
49
  sidebar: "sidebar";
48
50
  }>>;
49
- type: z.ZodLiteral<"external">;
51
+ type: z.ZodLiteral<"custom">;
50
52
  url: z.ZodString;
51
53
  }, z.core.$strip>;
52
54
  /**
@@ -91,6 +93,6 @@ export declare const Section: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodD
91
93
  header: "header";
92
94
  sidebar: "sidebar";
93
95
  }>>;
94
- type: z.ZodLiteral<"external">;
96
+ type: z.ZodLiteral<"custom">;
95
97
  url: z.ZodString;
96
98
  }, z.core.$strip>], "type">>;
@@ -18,8 +18,8 @@ export const ChangelogSection = BaseSection.extend({
18
18
  source: z.string(),
19
19
  version: z.boolean().optional(),
20
20
  });
21
- export const ExternalSection = BaseSection.extend({
22
- type: z.literal("external"),
21
+ export const CustomSection = BaseSection.extend({
22
+ type: z.literal("custom"),
23
23
  url: z.string(),
24
24
  });
25
25
  export const Section = z.preprocess(input => {
@@ -32,6 +32,6 @@ export const Section = z.preprocess(input => {
32
32
  ArticleSection,
33
33
  BlogSection,
34
34
  ChangelogSection,
35
- ExternalSection,
35
+ CustomSection,
36
36
  ]));
37
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NvdXJjZS9tb2RlbHMvc2VjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sS0FBSyxDQUFBO0FBRXZCLE1BQU0sV0FBVyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDM0IsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDM0IsS0FBSyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUU7SUFDakIsUUFBUSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO0NBQzFELENBQUMsQ0FBQTtBQUlGLE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDO0lBQy9DLElBQUksRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQztJQUMxQixNQUFNLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRTtDQUNuQixDQUFDLENBQUE7QUFJRixNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQztJQUM1QyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7SUFDdkIsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUU7Q0FDbkIsQ0FBQyxDQUFBO0FBSUYsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQztJQUNqRCxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUM7SUFDNUIsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUU7SUFDbEIsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUU7SUFDbEIsT0FBTyxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLEVBQUU7Q0FDaEMsQ0FBQyxDQUFBO0FBSUYsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUM7SUFDaEQsSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDO0lBQzNCLEdBQUcsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFO0NBQ2hCLENBQUMsQ0FBQTtBQVFGLE1BQU0sQ0FBQyxNQUFNLE9BQU8sR0FBRyxDQUFDLENBQUMsVUFBVSxDQUNqQyxLQUFLLENBQUMsRUFBRTtJQUNOLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3hFLE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLEtBQWdDLENBQUE7SUFDL0MsT0FBTyxNQUFNLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxNQUFNLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxDQUFBO0FBQ25FLENBQUMsRUFDRCxDQUFDLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFO0lBQzNCLGNBQWM7SUFDZCxXQUFXO0lBQ1gsZ0JBQWdCO0lBQ2hCLGVBQWU7Q0FDaEIsQ0FBQyxDQUNILENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiXG5cbmNvbnN0IEJhc2VTZWN0aW9uID0gei5vYmplY3Qoe1xuICBpY29uOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gIHRpdGxlOiB6LnN0cmluZygpLFxuICBwb3NpdGlvbjogei5lbnVtKFtcImhlYWRlclwiLCBcInNpZGViYXJcIl0pLmRlZmF1bHQoXCJoZWFkZXJcIiksXG59KVxuXG4vKiogRGVmYXVsdCBzZWN0aW9uOiByZW5kZXJzIGFydGljbGVzLiAqL1xuZXhwb3J0IHR5cGUgQXJ0aWNsZVNlY3Rpb24gPSB6LmluZmVyPHR5cGVvZiBBcnRpY2xlU2VjdGlvbj5cbmV4cG9ydCBjb25zdCBBcnRpY2xlU2VjdGlvbiA9IEJhc2VTZWN0aW9uLmV4dGVuZCh7XG4gIHR5cGU6IHoubGl0ZXJhbChcImFydGljbGVcIiksXG4gIHByZWZpeDogei5zdHJpbmcoKSxcbn0pXG5cbi8qKiBCbG9nIHNlY3Rpb246IGRhdGUtc29ydGVkIHBvc3RzIHdpdGggdGFncyBhbmQgaW5kZXguICovXG5leHBvcnQgdHlwZSBCbG9nU2VjdGlvbiA9IHouaW5mZXI8dHlwZW9mIEJsb2dTZWN0aW9uPlxuZXhwb3J0IGNvbnN0IEJsb2dTZWN0aW9uID0gQmFzZVNlY3Rpb24uZXh0ZW5kKHtcbiAgdHlwZTogei5saXRlcmFsKFwiYmxvZ1wiKSxcbiAgcHJlZml4OiB6LnN0cmluZygpLFxufSlcblxuLyoqIENoYW5nZWxvZyBzZWN0aW9uOiBzaW5nbGUgZmlsZSBvciBHaXRIdWIgcmVsZWFzZXMsIHNwbGl0IHBlciB2ZXJzaW9uLiAqL1xuZXhwb3J0IHR5cGUgQ2hhbmdlbG9nU2VjdGlvbiA9IHouaW5mZXI8dHlwZW9mIENoYW5nZWxvZ1NlY3Rpb24+XG5leHBvcnQgY29uc3QgQ2hhbmdlbG9nU2VjdGlvbiA9IEJhc2VTZWN0aW9uLmV4dGVuZCh7XG4gIHR5cGU6IHoubGl0ZXJhbChcImNoYW5nZWxvZ1wiKSxcbiAgcHJlZml4OiB6LnN0cmluZygpLFxuICBzb3VyY2U6IHouc3RyaW5nKCksXG4gIHZlcnNpb246IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG59KVxuXG4vKiogRXh0ZXJuYWwgc2VjdGlvbjogcmVuZGVycyBhcyBhIGxpbmsgdG8gYW4gYXJiaXRyYXJ5IFVSTC4gKi9cbmV4cG9ydCB0eXBlIEV4dGVybmFsU2VjdGlvbiA9IHouaW5mZXI8dHlwZW9mIEV4dGVybmFsU2VjdGlvbj5cbmV4cG9ydCBjb25zdCBFeHRlcm5hbFNlY3Rpb24gPSBCYXNlU2VjdGlvbi5leHRlbmQoe1xuICB0eXBlOiB6LmxpdGVyYWwoXCJleHRlcm5hbFwiKSxcbiAgdXJsOiB6LnN0cmluZygpLFxufSlcblxuLyoqXG4gKiBBIHNpdGUgc2VjdGlvbi4gRGlzY3JpbWluYXRlZCBvbiBgdHlwZWAuXG4gKiBXaGVuIGB0eXBlYCBpcyBvbWl0dGVkLCBpdCBkZWZhdWx0cyB0byBcImFydGljbGVcIiBzbyBwbGFpblxuICogYHsgdGl0bGUsIHByZWZpeCB9YCBlbnRyaWVzIGtlZXAgd29ya2luZy5cbiAqL1xuZXhwb3J0IHR5cGUgU2VjdGlvbiA9IHouaW5mZXI8dHlwZW9mIFNlY3Rpb24+XG5leHBvcnQgY29uc3QgU2VjdGlvbiA9IHoucHJlcHJvY2VzcyhcbiAgaW5wdXQgPT4ge1xuICAgIGlmIChpbnB1dCA9PT0gbnVsbCB8fCB0eXBlb2YgaW5wdXQgIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShpbnB1dCkpIHtcbiAgICAgIHJldHVybiBpbnB1dFxuICAgIH1cbiAgICBjb25zdCByZWNvcmQgPSBpbnB1dCBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuICAgIHJldHVybiBcInR5cGVcIiBpbiByZWNvcmQgPyByZWNvcmQgOiB7IC4uLnJlY29yZCwgdHlwZTogXCJhcnRpY2xlXCIgfVxuICB9LFxuICB6LmRpc2NyaW1pbmF0ZWRVbmlvbihcInR5cGVcIiwgW1xuICAgIEFydGljbGVTZWN0aW9uLFxuICAgIEJsb2dTZWN0aW9uLFxuICAgIENoYW5nZWxvZ1NlY3Rpb24sXG4gICAgRXh0ZXJuYWxTZWN0aW9uLFxuICBdKSxcbilcbiJdfQ==
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NvdXJjZS9tb2RlbHMvc2VjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sS0FBSyxDQUFBO0FBRXZCLE1BQU0sV0FBVyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDM0IsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDM0IsS0FBSyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUU7SUFDakIsUUFBUSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO0NBQzFELENBQUMsQ0FBQTtBQUlGLE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDO0lBQy9DLElBQUksRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQztJQUMxQixNQUFNLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRTtDQUNuQixDQUFDLENBQUE7QUFJRixNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQztJQUM1QyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7SUFDdkIsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUU7Q0FDbkIsQ0FBQyxDQUFBO0FBSUYsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQztJQUNqRCxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUM7SUFDNUIsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUU7SUFDbEIsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUU7SUFDbEIsT0FBTyxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLEVBQUU7Q0FDaEMsQ0FBQyxDQUFBO0FBTUYsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUM7SUFDOUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO0lBQ3pCLEdBQUcsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFO0NBQ2hCLENBQUMsQ0FBQTtBQVFGLE1BQU0sQ0FBQyxNQUFNLE9BQU8sR0FBRyxDQUFDLENBQUMsVUFBVSxDQUNqQyxLQUFLLENBQUMsRUFBRTtJQUNOLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3hFLE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLEtBQWdDLENBQUE7SUFDL0MsT0FBTyxNQUFNLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxNQUFNLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxDQUFBO0FBQ25FLENBQUMsRUFDRCxDQUFDLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFO0lBQzNCLGNBQWM7SUFDZCxXQUFXO0lBQ1gsZ0JBQWdCO0lBQ2hCLGFBQWE7Q0FDZCxDQUFDLENBQ0gsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHogfSBmcm9tIFwiem9kXCJcblxuY29uc3QgQmFzZVNlY3Rpb24gPSB6Lm9iamVjdCh7XG4gIGljb246IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgdGl0bGU6IHouc3RyaW5nKCksXG4gIHBvc2l0aW9uOiB6LmVudW0oW1wiaGVhZGVyXCIsIFwic2lkZWJhclwiXSkuZGVmYXVsdChcImhlYWRlclwiKSxcbn0pXG5cbi8qKiBEZWZhdWx0IHNlY3Rpb246IHJlbmRlcnMgYXJ0aWNsZXMuICovXG5leHBvcnQgdHlwZSBBcnRpY2xlU2VjdGlvbiA9IHouaW5mZXI8dHlwZW9mIEFydGljbGVTZWN0aW9uPlxuZXhwb3J0IGNvbnN0IEFydGljbGVTZWN0aW9uID0gQmFzZVNlY3Rpb24uZXh0ZW5kKHtcbiAgdHlwZTogei5saXRlcmFsKFwiYXJ0aWNsZVwiKSxcbiAgcHJlZml4OiB6LnN0cmluZygpLFxufSlcblxuLyoqIEJsb2cgc2VjdGlvbjogZGF0ZS1zb3J0ZWQgcG9zdHMgd2l0aCB0YWdzIGFuZCBpbmRleC4gKi9cbmV4cG9ydCB0eXBlIEJsb2dTZWN0aW9uID0gei5pbmZlcjx0eXBlb2YgQmxvZ1NlY3Rpb24+XG5leHBvcnQgY29uc3QgQmxvZ1NlY3Rpb24gPSBCYXNlU2VjdGlvbi5leHRlbmQoe1xuICB0eXBlOiB6LmxpdGVyYWwoXCJibG9nXCIpLFxuICBwcmVmaXg6IHouc3RyaW5nKCksXG59KVxuXG4vKiogQ2hhbmdlbG9nIHNlY3Rpb246IHNpbmdsZSBmaWxlIG9yIEdpdEh1YiByZWxlYXNlcywgc3BsaXQgcGVyIHZlcnNpb24uICovXG5leHBvcnQgdHlwZSBDaGFuZ2Vsb2dTZWN0aW9uID0gei5pbmZlcjx0eXBlb2YgQ2hhbmdlbG9nU2VjdGlvbj5cbmV4cG9ydCBjb25zdCBDaGFuZ2Vsb2dTZWN0aW9uID0gQmFzZVNlY3Rpb24uZXh0ZW5kKHtcbiAgdHlwZTogei5saXRlcmFsKFwiY2hhbmdlbG9nXCIpLFxuICBwcmVmaXg6IHouc3RyaW5nKCksXG4gIHNvdXJjZTogei5zdHJpbmcoKSxcbiAgdmVyc2lvbjogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbn0pXG5cbi8qKiBDdXN0b20gc2VjdGlvbjogcmVuZGVycyBhcyBhIGxpbmsgdG8gYW4gYXJiaXRyYXJ5IFVSTCDigJQgYWJzb2x1dGVcbiAqICAoYGh0dHBzOi8v4oCmYCkgb3IgaW50ZXJuYWwgKGAvY2hhbmdlbG9nYCkuIEludGVybmFsIFVSTHMgcGFydGljaXBhdGVcbiAqICBpbiBhY3RpdmUtc3RhdGUgaGlnaGxpZ2h0aW5nIGxpa2Ugcm91dGVkIHNlY3Rpb25zLiAqL1xuZXhwb3J0IHR5cGUgQ3VzdG9tU2VjdGlvbiA9IHouaW5mZXI8dHlwZW9mIEN1c3RvbVNlY3Rpb24+XG5leHBvcnQgY29uc3QgQ3VzdG9tU2VjdGlvbiA9IEJhc2VTZWN0aW9uLmV4dGVuZCh7XG4gIHR5cGU6IHoubGl0ZXJhbChcImN1c3RvbVwiKSxcbiAgdXJsOiB6LnN0cmluZygpLFxufSlcblxuLyoqXG4gKiBBIHNpdGUgc2VjdGlvbi4gRGlzY3JpbWluYXRlZCBvbiBgdHlwZWAuXG4gKiBXaGVuIGB0eXBlYCBpcyBvbWl0dGVkLCBpdCBkZWZhdWx0cyB0byBcImFydGljbGVcIiBzbyBwbGFpblxuICogYHsgdGl0bGUsIHByZWZpeCB9YCBlbnRyaWVzIGtlZXAgd29ya2luZy5cbiAqL1xuZXhwb3J0IHR5cGUgU2VjdGlvbiA9IHouaW5mZXI8dHlwZW9mIFNlY3Rpb24+XG5leHBvcnQgY29uc3QgU2VjdGlvbiA9IHoucHJlcHJvY2VzcyhcbiAgaW5wdXQgPT4ge1xuICAgIGlmIChpbnB1dCA9PT0gbnVsbCB8fCB0eXBlb2YgaW5wdXQgIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShpbnB1dCkpIHtcbiAgICAgIHJldHVybiBpbnB1dFxuICAgIH1cbiAgICBjb25zdCByZWNvcmQgPSBpbnB1dCBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuICAgIHJldHVybiBcInR5cGVcIiBpbiByZWNvcmQgPyByZWNvcmQgOiB7IC4uLnJlY29yZCwgdHlwZTogXCJhcnRpY2xlXCIgfVxuICB9LFxuICB6LmRpc2NyaW1pbmF0ZWRVbmlvbihcInR5cGVcIiwgW1xuICAgIEFydGljbGVTZWN0aW9uLFxuICAgIEJsb2dTZWN0aW9uLFxuICAgIENoYW5nZWxvZ1NlY3Rpb24sXG4gICAgQ3VzdG9tU2VjdGlvbixcbiAgXSksXG4pXG4iXX0=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livemark",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "Livemark description",
5
5
  "license": "MIT",
6
6
  "author": "Evgeny Karev",
@@ -1,11 +1,9 @@
1
- import type { z } from "zod"
2
- import { UserConfig } from "../../models/config.ts"
1
+ import { UserConfig as UserConfigSchema } from "../../models/config.ts"
2
+ import type { UserConfig } from "../../models/config.ts"
3
3
 
4
4
  /**
5
5
  * Validate and fill defaults for a partial config object.
6
6
  */
7
- export function defineConfig(
8
- input: z.input<typeof UserConfig>,
9
- ): z.output<typeof UserConfig> {
10
- return UserConfig.parse(input)
7
+ export function defineConfig(input: UserConfig) {
8
+ return UserConfigSchema.parse(input)
11
9
  }
@@ -1,11 +1,27 @@
1
1
  import { existsSync } from "node:fs"
2
2
  import { dirname, resolve } from "node:path"
3
3
  import { pathToFileURL } from "node:url"
4
- import type { z } from "zod"
5
- import type { Config } from "../../models/config.ts"
6
- import { UserConfig } from "../../models/config.ts"
4
+ import type { Config, UserConfig } from "../../models/config.ts"
5
+ import { resolveBase } from "../../helpers/resolve-base.ts"
7
6
  import { defineConfig } from "./define.ts"
8
7
 
8
+ /** Map livemark CLI verbs to the Vite-equivalent `command` string used by
9
+ * `resolveBase()`. `preview` serves the production build's artifacts so
10
+ * it uses the build-mode base. Default to `"build"` for safety when no
11
+ * recognised verb is in argv (the common path is `livemark <verb> ...`). */
12
+ const COMMAND_BY_VERB: Record<string, "build" | "serve"> = {
13
+ start: "serve",
14
+ build: "build",
15
+ preview: "build",
16
+ }
17
+
18
+ function detectCommand() {
19
+ for (const arg of process.argv.slice(2)) {
20
+ if (arg in COMMAND_BY_VERB) return COMMAND_BY_VERB[arg]!
21
+ }
22
+ return "build" as const
23
+ }
24
+
9
25
  /**
10
26
  * Load and validate a config file, checking --config/-c CLI arg, then cwd.
11
27
  *
@@ -23,15 +39,19 @@ export async function loadConfig(path?: string): Promise<Config> {
23
39
  const cliPath = configIndex !== -1 ? process.argv[configIndex + 1] : undefined
24
40
  const explicit = path ?? cliPath
25
41
  const resolved = resolve(explicit ?? "livemark.config.ts")
26
- let input: z.input<typeof UserConfig> = {}
42
+ let input: UserConfig = {}
27
43
  if (existsSync(resolved)) {
28
44
  // Cache-bust the ESM import so dev-server restart reloads edits on disk.
29
45
  const url = `${pathToFileURL(resolved).href}?t=${Date.now()}`
30
46
  const module: Record<string, unknown> = await import(url)
31
- input = (module.default as z.input<typeof UserConfig>) ?? {}
47
+ input = (module.default as UserConfig) ?? {}
32
48
  } else if (explicit) {
33
49
  throw new Error(`Config file not found: ${resolved}`)
34
50
  }
35
51
  const validated = defineConfig(input)
36
- return { ...validated, root: dirname(resolved), configPath: resolved }
52
+ // Resolve the function form of `base` once, here, using the livemark
53
+ // CLI verb. Downstream consumers (Vite plugin, content-collections,
54
+ // runtime) get a plain string|undefined and never see the function.
55
+ const base = resolveBase(validated.base, detectCommand())
56
+ return { ...validated, base, root: dirname(resolved), configPath: resolved }
37
57
  }
@@ -9,7 +9,7 @@ import {
9
9
  } from "../content/article.ts"
10
10
  import { DynamicIcon } from "../helpers/dynamic-icon.tsx"
11
11
  import { prefixUrl } from "../helpers/prefix-url.ts"
12
- import { sectionIcon } from "../helpers/section.ts"
12
+ import { customSectionActive, sectionIcon } from "../helpers/section.ts"
13
13
  import {
14
14
  SidebarInset,
15
15
  SidebarProvider,
@@ -69,17 +69,20 @@ export function Layout(props: {
69
69
  sections
70
70
  .filter(section => section.position === "header")
71
71
  .map(section => {
72
- if (section.type === "external") {
72
+ const icon = sectionIcon(section)
73
+ if (section.type === "custom") {
74
+ const isActive = customSectionActive(section.url, pathname)
73
75
  return (
74
76
  <a
75
77
  key={section.url}
76
78
  href={prefixUrl(section.url, config.base)}
77
- className="inline-flex items-center gap-1.5 text-foreground opacity-80 hover:opacity-100 transition-opacity"
79
+ className={`inline-flex items-center gap-1.5 text-foreground ${
80
+ isActive
81
+ ? "font-medium border-b-2 border-foreground pb-0.5 -mb-0.5"
82
+ : "opacity-80 hover:opacity-100 transition-opacity"
83
+ }`}
78
84
  >
79
- <DynamicIcon
80
- name={sectionIcon(section)}
81
- className="size-3.5"
82
- />
85
+ {icon && <DynamicIcon name={icon} className="size-3.5" />}
83
86
  <span>{section.title}</span>
84
87
  </a>
85
88
  )
@@ -107,10 +110,7 @@ export function Layout(props: {
107
110
  : "opacity-80 hover:opacity-100 transition-opacity"
108
111
  }`}
109
112
  >
110
- <DynamicIcon
111
- name={sectionIcon(section)}
112
- className="size-3.5"
113
- />
113
+ {icon && <DynamicIcon name={icon} className="size-3.5" />}
114
114
  <span>
115
115
  {section.title}
116
116
  {latestVersion && (
@@ -3,7 +3,7 @@ import { Link, useLocation, useMatch } from "@tanstack/react-router"
3
3
  import { currentSection, sectionFirstArticle } from "../content/article.ts"
4
4
  import { DynamicIcon } from "../helpers/dynamic-icon.tsx"
5
5
  import { prefixUrl } from "../helpers/prefix-url.ts"
6
- import { sectionIcon } from "../helpers/section.ts"
6
+ import { customSectionActive, sectionIcon } from "../helpers/section.ts"
7
7
  import {
8
8
  SidebarGroup,
9
9
  SidebarGroupContent,
@@ -40,17 +40,20 @@ export function SidebarSections() {
40
40
  <SidebarMenu>
41
41
  {sections.map(s => {
42
42
  const mobileOnly = s.position !== "sidebar"
43
- if (s.type === "external") {
43
+ const icon = sectionIcon(s)
44
+ if (s.type === "custom") {
45
+ const active = customSectionActive(s.url, pathname)
44
46
  return (
45
47
  <SidebarMenuItem
46
48
  key={s.url}
47
49
  className={mobileOnly ? "md:hidden" : undefined}
48
50
  >
49
51
  <SidebarMenuButton
50
- className="opacity-75"
52
+ isActive={active}
53
+ className={active ? "" : "opacity-75"}
51
54
  render={<a href={prefixUrl(s.url, config.base)} />}
52
55
  >
53
- <DynamicIcon name={sectionIcon(s)} className="size-4" />
56
+ {icon && <DynamicIcon name={icon} className="size-4" />}
54
57
  <span>{s.title}</span>
55
58
  </SidebarMenuButton>
56
59
  </SidebarMenuItem>
@@ -76,7 +79,7 @@ export function SidebarSections() {
76
79
  />
77
80
  }
78
81
  >
79
- <DynamicIcon name={sectionIcon(s)} className="size-4" />
82
+ {icon && <DynamicIcon name={icon} className="size-4" />}
80
83
  <span>{s.title}</span>
81
84
  </SidebarMenuButton>
82
85
  </SidebarMenuItem>
@@ -33,9 +33,9 @@ function orderKey(order?: number) {
33
33
 
34
34
  const configSections = config.sections
35
35
 
36
- /** Route-bound sections (everything except `external`). External sections
36
+ /** Route-bound sections (everything except `custom`). Custom sections
37
37
  * are pure links — they have no `prefix` and don't claim a URL space. */
38
- const routedSections = configSections?.filter(s => s.type !== "external") ?? []
38
+ const routedSections = configSections?.filter(s => s.type !== "custom") ?? []
39
39
 
40
40
  /** Per-section article tree, keyed by section prefix */
41
41
  export const sectionArticleTrees = new Map<string, ArticleNode[]>()
@@ -0,0 +1,11 @@
1
+ /** Resolve a base config field — accepts a string, a function of the
2
+ * form `(command) => string | undefined` (where `command` matches
3
+ * Vite's `ConfigEnv.command`), or undefined. Normalizes the result to
4
+ * either `undefined` (no base) or a leading-slash, no-trailing-slash
5
+ * string (e.g. `"repo"` and `"/repo/"` both → `"/repo"`). */
6
+ export function resolveBase(input: unknown, command: "build" | "serve") {
7
+ const raw = typeof input === "function" ? input(command) : input
8
+ if (typeof raw !== "string" || !raw) return undefined
9
+ const trimmed = raw.replace(/^\/|\/$/g, "")
10
+ return trimmed ? `/${trimmed}` : undefined
11
+ }
@@ -0,0 +1,61 @@
1
+ import { describe, expect, it } from "vite-plus/test"
2
+ import { resolveBase } from "./resolve-base.ts"
3
+
4
+ describe("resolveBase", () => {
5
+ it("should return undefined for undefined input", () => {
6
+ expect(resolveBase(undefined, "build")).toBeUndefined()
7
+ expect(resolveBase(undefined, "serve")).toBeUndefined()
8
+ })
9
+
10
+ it("should return undefined for empty or root-only string", () => {
11
+ expect(resolveBase("", "build")).toBeUndefined()
12
+ expect(resolveBase("/", "build")).toBeUndefined()
13
+ })
14
+
15
+ it("should normalize a string without slashes", () => {
16
+ expect(resolveBase("repo", "build")).toBe("/repo")
17
+ })
18
+
19
+ it("should normalize a string with leading slash", () => {
20
+ expect(resolveBase("/repo", "build")).toBe("/repo")
21
+ })
22
+
23
+ it("should normalize a string with trailing slash", () => {
24
+ expect(resolveBase("repo/", "build")).toBe("/repo")
25
+ })
26
+
27
+ it("should normalize a string with both slashes", () => {
28
+ expect(resolveBase("/repo/", "build")).toBe("/repo")
29
+ })
30
+
31
+ it("should preserve multi-segment paths", () => {
32
+ expect(resolveBase("/a/b/", "build")).toBe("/a/b")
33
+ })
34
+
35
+ it("should call a function with command=build", () => {
36
+ const fn = (cmd: "build" | "serve") => (cmd === "build" ? "prod" : "dev")
37
+ expect(resolveBase(fn, "build")).toBe("/prod")
38
+ })
39
+
40
+ it("should call a function with command=serve", () => {
41
+ const fn = (cmd: "build" | "serve") => (cmd === "build" ? "prod" : "dev")
42
+ expect(resolveBase(fn, "serve")).toBe("/dev")
43
+ })
44
+
45
+ it("should handle a function returning undefined", () => {
46
+ const fn = (cmd: "build" | "serve") =>
47
+ cmd === "serve" ? undefined : "prod"
48
+ expect(resolveBase(fn, "serve")).toBeUndefined()
49
+ expect(resolveBase(fn, "build")).toBe("/prod")
50
+ })
51
+
52
+ it("should handle a function returning empty string", () => {
53
+ const fn = () => ""
54
+ expect(resolveBase(fn, "build")).toBeUndefined()
55
+ })
56
+
57
+ it("should normalize the function-returned string", () => {
58
+ const fn = () => "/repo/"
59
+ expect(resolveBase(fn, "build")).toBe("/repo")
60
+ })
61
+ })
@@ -1,17 +1,32 @@
1
1
  import type { Section } from "../models/section.ts"
2
2
 
3
- const DEFAULT_ICONS: Record<Section["type"], string> = {
3
+ const DEFAULT_ICONS: Partial<Record<Section["type"], string>> = {
4
4
  article: "book-open",
5
5
  blog: "rss",
6
6
  changelog: "history",
7
- external: "external-link",
8
7
  }
9
8
 
10
- /** Return the section's icon, falling back to a type-based default */
9
+ /** Return the section's icon, falling back to a type-based default.
10
+ * Custom sections have no default — the user opts in via `icon`. */
11
11
  export function sectionIcon(section: Pick<Section, "icon" | "type">) {
12
12
  return section.icon ?? DEFAULT_ICONS[section.type]
13
13
  }
14
14
 
15
+ /** Whether a custom section's URL should highlight as active for the
16
+ * current pathname. Only `/`-leading internal paths participate;
17
+ * protocol-absolute (`https://…`, `//cdn…`) URLs never highlight.
18
+ * Match semantics mirror routed sections — exact path or any
19
+ * descendant. A URL of `/` only highlights the home page itself
20
+ * (otherwise it would always match). */
21
+ export function customSectionActive(url: string, pathname: string) {
22
+ if (!url.startsWith("/") || url.startsWith("//")) return false
23
+ const stripped = url.split(/[?#]/)[0] ?? ""
24
+ const target = `/${stripped.replace(/^\/|\/$/g, "")}/`
25
+ const current = `/${pathname.replace(/^\/|\/$/g, "")}/`
26
+ if (target === "/") return current === "/"
27
+ return current === target || current.startsWith(target)
28
+ }
29
+
15
30
  /** Find the section whose prefix is the longest prefix of the article path */
16
31
  export function matchSection<S extends { prefix: string }>(
17
32
  articlePath: string,