@praxisjs/ssg 0.1.2 → 0.1.3
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/CHANGELOG.md +34 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +39 -15
- package/dist/index.js.map +1 -1
- package/dist/loader-hook.d.ts.map +1 -1
- package/dist/loader-hook.js +3 -13
- package/dist/loader-hook.js.map +1 -1
- package/dist/prerender.d.ts +10 -7
- package/dist/prerender.d.ts.map +1 -1
- package/dist/prerender.js +80 -63
- package/dist/prerender.js.map +1 -1
- package/package.json +16 -8
- package/src/index.ts +42 -16
- package/src/loader-hook.ts +3 -13
- package/src/prerender.ts +95 -80
- package/dist/__tests__/loader-hook.test.d.ts +0 -2
- package/dist/__tests__/loader-hook.test.d.ts.map +0 -1
- package/dist/__tests__/loader-hook.test.js +0 -66
- package/dist/__tests__/loader-hook.test.js.map +0 -1
- package/dist/__tests__/plugin.test.d.ts +0 -2
- package/dist/__tests__/plugin.test.d.ts.map +0 -1
- package/dist/__tests__/plugin.test.js +0 -128
- package/dist/__tests__/plugin.test.js.map +0 -1
- package/dist/__tests__/prerender.test.d.ts +0 -2
- package/dist/__tests__/prerender.test.d.ts.map +0 -1
- package/dist/__tests__/prerender.test.js +0 -211
- package/dist/__tests__/prerender.test.js.map +0 -1
- package/dist/__tests__/register-fallback.test.d.ts +0 -2
- package/dist/__tests__/register-fallback.test.d.ts.map +0 -1
- package/dist/__tests__/register-fallback.test.js +0 -20
- package/dist/__tests__/register-fallback.test.js.map +0 -1
- package/dist/__tests__/resolve-sync.test.d.ts +0 -2
- package/dist/__tests__/resolve-sync.test.d.ts.map +0 -1
- package/dist/__tests__/resolve-sync.test.js +0 -67
- package/dist/__tests__/resolve-sync.test.js.map +0 -1
- package/dist/__tests__/routes.test.d.ts +0 -2
- package/dist/__tests__/routes.test.d.ts.map +0 -1
- package/dist/__tests__/routes.test.js +0 -154
- package/dist/__tests__/routes.test.js.map +0 -1
- package/src/__tests__/loader-hook.test.ts +0 -76
- package/src/__tests__/plugin.test.ts +0 -161
- package/src/__tests__/prerender.test.ts +0 -181
- package/src/__tests__/register-fallback.test.ts +0 -23
- package/src/__tests__/resolve-sync.test.ts +0 -91
- package/src/__tests__/routes.test.ts +0 -175
- package/tsconfig.json +0 -11
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
-
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
-
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
-
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
-
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
-
var _, done = false;
|
|
7
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
-
var context = {};
|
|
9
|
-
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
-
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
-
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
-
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
-
if (kind === "accessor") {
|
|
14
|
-
if (result === void 0) continue;
|
|
15
|
-
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
-
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
-
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
-
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
-
}
|
|
20
|
-
else if (_ = accept(result)) {
|
|
21
|
-
if (kind === "field") initializers.unshift(_);
|
|
22
|
-
else descriptor[key] = _;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
-
done = true;
|
|
27
|
-
};
|
|
28
|
-
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
-
var useValue = arguments.length > 2;
|
|
30
|
-
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
-
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
-
}
|
|
33
|
-
return useValue ? value : void 0;
|
|
34
|
-
};
|
|
35
|
-
// @vitest-environment jsdom
|
|
36
|
-
import { describe, it, expect } from "vitest";
|
|
37
|
-
import { StatefulComponent } from "@praxisjs/core";
|
|
38
|
-
import { resource } from "@praxisjs/core/internal";
|
|
39
|
-
import { Head } from "@praxisjs/head";
|
|
40
|
-
import { Location } from "@praxisjs/router";
|
|
41
|
-
import { getCurrentScope, mountComponent, mountElement, render } from "@praxisjs/runtime";
|
|
42
|
-
import { prerender, withDomGlobals } from "../prerender";
|
|
43
|
-
const TEMPLATE = '<!doctype html><html><head><title>App</title></head><body><div id="app"></div></body></html>';
|
|
44
|
-
let Page = (() => {
|
|
45
|
-
let _classDecorators = [Head((self) => ({ title: `Page: ${self.location().path}` }))];
|
|
46
|
-
let _classDescriptor;
|
|
47
|
-
let _classExtraInitializers = [];
|
|
48
|
-
let _classThis;
|
|
49
|
-
let _classSuper = StatefulComponent;
|
|
50
|
-
let _location_decorators;
|
|
51
|
-
let _location_initializers = [];
|
|
52
|
-
let _location_extraInitializers = [];
|
|
53
|
-
var Page = class extends _classSuper {
|
|
54
|
-
static { _classThis = this; }
|
|
55
|
-
static {
|
|
56
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
57
|
-
_location_decorators = [Location()];
|
|
58
|
-
__esDecorate(null, null, _location_decorators, { kind: "field", name: "location", static: false, private: false, access: { has: obj => "location" in obj, get: obj => obj.location, set: (obj, value) => { obj.location = value; } }, metadata: _metadata }, _location_initializers, _location_extraInitializers);
|
|
59
|
-
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
60
|
-
Page = _classThis = _classDescriptor.value;
|
|
61
|
-
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
62
|
-
}
|
|
63
|
-
static __isComponent = true;
|
|
64
|
-
static __isStateless = false;
|
|
65
|
-
location = __runInitializers(this, _location_initializers, void 0);
|
|
66
|
-
render() {
|
|
67
|
-
return mountElement("main", {
|
|
68
|
-
id: "root",
|
|
69
|
-
children: [
|
|
70
|
-
mountElement("h1", { children: `Path: ${this.location().path}` }, getCurrentScope()),
|
|
71
|
-
mountElement("button", { id: "btn", onClick: () => { }, children: "Click" }, getCurrentScope()),
|
|
72
|
-
],
|
|
73
|
-
}, getCurrentScope());
|
|
74
|
-
}
|
|
75
|
-
constructor() {
|
|
76
|
-
super(...arguments);
|
|
77
|
-
__runInitializers(this, _location_extraInitializers);
|
|
78
|
-
}
|
|
79
|
-
static {
|
|
80
|
-
__runInitializers(_classThis, _classExtraInitializers);
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
return Page = _classThis;
|
|
84
|
-
})();
|
|
85
|
-
class AsyncPage extends StatefulComponent {
|
|
86
|
-
static __isComponent = true;
|
|
87
|
-
static __isStateless = false;
|
|
88
|
-
data = resource(() => Promise.resolve("loaded content"));
|
|
89
|
-
render() {
|
|
90
|
-
return mountElement("p", { id: "data", children: () => this.data.data() ?? "pending" }, getCurrentScope());
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
describe("prerender()", () => {
|
|
94
|
-
it("renders each static route to its own page with the hydration marker", async () => {
|
|
95
|
-
const routes = [
|
|
96
|
-
{ path: "/", component: Page },
|
|
97
|
-
{ path: "/about", component: Page },
|
|
98
|
-
];
|
|
99
|
-
const pages = await prerender({ root: Page, routes, template: TEMPLATE });
|
|
100
|
-
expect(pages.map((p) => p.path).sort()).toEqual(["/", "/about"]);
|
|
101
|
-
const home = pages.find((p) => p.path === "/");
|
|
102
|
-
expect(home.file).toBe("index.html");
|
|
103
|
-
expect(home.html).toContain("Path: /");
|
|
104
|
-
expect(home.html).toContain('data-praxis-ssg="1"');
|
|
105
|
-
const about = pages.find((p) => p.path === "/about");
|
|
106
|
-
expect(about.file).toBe("about/index.html");
|
|
107
|
-
expect(about.html).toContain("Path: /about");
|
|
108
|
-
});
|
|
109
|
-
it("omits the hydration marker when hydrate: false", async () => {
|
|
110
|
-
const routes = [{ path: "/", component: Page }];
|
|
111
|
-
const pages = await prerender({ root: Page, routes, template: TEMPLATE, hydrate: false });
|
|
112
|
-
expect(pages[0].html).not.toContain("data-praxis-ssg");
|
|
113
|
-
});
|
|
114
|
-
it("expands a dynamic route via getStaticPaths", async () => {
|
|
115
|
-
const routes = [{ path: "/blog/:slug", component: Page }];
|
|
116
|
-
const pages = await prerender({
|
|
117
|
-
root: Page,
|
|
118
|
-
routes,
|
|
119
|
-
template: TEMPLATE,
|
|
120
|
-
getStaticPaths: async () => ["/blog/hello", "/blog/world"],
|
|
121
|
-
});
|
|
122
|
-
expect(pages.map((p) => p.file).sort()).toEqual(["blog/hello/index.html", "blog/world/index.html"]);
|
|
123
|
-
});
|
|
124
|
-
it("waits for resource() data to settle before serializing", async () => {
|
|
125
|
-
const routes = [{ path: "/", component: AsyncPage }];
|
|
126
|
-
const pages = await prerender({ root: AsyncPage, routes, template: TEMPLATE });
|
|
127
|
-
expect(pages[0].html).toContain("loaded content");
|
|
128
|
-
expect(pages[0].html).not.toContain("pending");
|
|
129
|
-
});
|
|
130
|
-
it("sets per-route <title> via @Head and does not leak it across routes", async () => {
|
|
131
|
-
const routes = [
|
|
132
|
-
{ path: "/", component: Page },
|
|
133
|
-
{ path: "/about", component: Page },
|
|
134
|
-
];
|
|
135
|
-
const pages = await prerender({ root: Page, routes, template: TEMPLATE });
|
|
136
|
-
const home = pages.find((p) => p.path === "/");
|
|
137
|
-
const about = pages.find((p) => p.path === "/about");
|
|
138
|
-
expect(home.html).toContain("<title>Page: /</title>");
|
|
139
|
-
expect(about.html).toContain("<title>Page: /about</title>");
|
|
140
|
-
});
|
|
141
|
-
it("does not leak globalThis.document/window back to the caller's environment", async () => {
|
|
142
|
-
const outer = document;
|
|
143
|
-
const routes = [{ path: "/", component: Page }];
|
|
144
|
-
await prerender({ root: Page, routes, template: TEMPLATE });
|
|
145
|
-
expect(globalThis.document).toBe(outer);
|
|
146
|
-
});
|
|
147
|
-
it("throws a clear error when the container selector is not found in the template", async () => {
|
|
148
|
-
const routes = [{ path: "/", component: Page }];
|
|
149
|
-
await expect(prerender({ root: Page, routes, template: "<html><body></body></html>" })).rejects.toThrow(/No element matching/);
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
describe("withDomGlobals", () => {
|
|
153
|
-
it("deletes a patched global on restore when it had no prior descriptor, and restores others that did", async () => {
|
|
154
|
-
const priorDescriptor = Object.getOwnPropertyDescriptor(globalThis, "Comment");
|
|
155
|
-
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete -- simulating a Node environment where this global never existed
|
|
156
|
-
delete globalThis.Comment;
|
|
157
|
-
try {
|
|
158
|
-
let sawCommentDuring;
|
|
159
|
-
await withDomGlobals("<!doctype html><html><body></body></html>", "http://localhost/", async () => {
|
|
160
|
-
sawCommentDuring = globalThis.Comment;
|
|
161
|
-
// document existed before this call (vitest's jsdom environment) — restoreGlobals
|
|
162
|
-
// must put its original descriptor back, not delete it.
|
|
163
|
-
expect(globalThis.document).toBeDefined();
|
|
164
|
-
});
|
|
165
|
-
expect(sawCommentDuring).toBeDefined();
|
|
166
|
-
expect(Object.getOwnPropertyDescriptor(globalThis, "Comment")).toBeUndefined();
|
|
167
|
-
expect(globalThis.document).toBeDefined();
|
|
168
|
-
}
|
|
169
|
-
finally {
|
|
170
|
-
if (priorDescriptor)
|
|
171
|
-
Object.defineProperty(globalThis, "Comment", priorDescriptor);
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
describe("prerender() -> render() round trip", () => {
|
|
176
|
-
it("produces HTML the client can hydrate without recreating the adopted nodes", async () => {
|
|
177
|
-
const routes = [{ path: "/", component: Page }];
|
|
178
|
-
const pages = await prerender({ root: Page, routes, template: TEMPLATE });
|
|
179
|
-
const html = pages[0].html;
|
|
180
|
-
const parsed = new DOMParser().parseFromString(html, "text/html");
|
|
181
|
-
const appHTML = parsed.querySelector("#app")?.innerHTML ?? "";
|
|
182
|
-
const container = document.createElement("div");
|
|
183
|
-
container.innerHTML = appHTML;
|
|
184
|
-
container.setAttribute("data-praxis-ssg", "1");
|
|
185
|
-
document.body.appendChild(container);
|
|
186
|
-
const h1Before = container.querySelector("h1");
|
|
187
|
-
const btnBefore = container.querySelector("#btn");
|
|
188
|
-
expect(h1Before?.textContent).toBe("Path: /");
|
|
189
|
-
let clicks = 0;
|
|
190
|
-
class ClientPage extends StatefulComponent {
|
|
191
|
-
static __isComponent = true;
|
|
192
|
-
static __isStateless = false;
|
|
193
|
-
render() {
|
|
194
|
-
return mountElement("main", {
|
|
195
|
-
id: "root",
|
|
196
|
-
children: [
|
|
197
|
-
mountElement("h1", { children: "Path: /" }, getCurrentScope()),
|
|
198
|
-
mountElement("button", { id: "btn", onClick: () => { clicks++; }, children: "Click" }, getCurrentScope()),
|
|
199
|
-
],
|
|
200
|
-
}, getCurrentScope());
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
render(() => mountComponent(ClientPage, {}, getCurrentScope()), container);
|
|
204
|
-
expect(container.querySelector("h1")).toBe(h1Before);
|
|
205
|
-
expect(container.querySelector("#btn")).toBe(btnBefore);
|
|
206
|
-
container.querySelector("#btn")?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
|
207
|
-
expect(clicks).toBe(1);
|
|
208
|
-
document.body.removeChild(container);
|
|
209
|
-
});
|
|
210
|
-
});
|
|
211
|
-
//# sourceMappingURL=prerender.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prerender.test.js","sourceRoot":"","sources":["../../src/__tests__/prerender.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4BAA4B;AAC5B,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE1F,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEzD,MAAM,QAAQ,GACZ,8FAA8F,CAAC;IAG3F,IAAI;4BADT,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,SAAU,IAAa,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;;;;sBACpD,iBAAiB;;;;oBAAzB,SAAQ,WAAiB;;;;oCAGjC,QAAQ,EAAE;YAAC,0KAAA,QAAQ,6BAAR,QAAQ,2FAAiB;YAHvC,6KAcC;;;;QAbC,MAAM,CAAC,aAAa,GAAG,IAAa,CAAC;QACrC,MAAM,CAAC,aAAa,GAAG,KAAK,CAAC;QACjB,QAAQ,2DAAiB;QAErC,MAAM;YACJ,OAAO,YAAY,CAAC,MAAM,EAAE;gBAC1B,EAAE,EAAE,MAAM;gBACV,QAAQ,EAAE;oBACR,YAAY,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,SAAS,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC;oBACpF,YAAY,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,eAAe,EAAE,CAAC;iBAC/F;aACF,EAAE,eAAe,EAAE,CAAC,CAAC;QACxB,CAAC;;;;;;YAbG,uDAAI;;;;;AAgBV,MAAM,SAAU,SAAQ,iBAAiB;IACvC,MAAM,CAAC,aAAa,GAAG,IAAa,CAAC;IACrC,MAAM,CAAC,aAAa,GAAG,KAAK,CAAC;IAC7B,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEzD,MAAM;QACJ,OAAO,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,SAAS,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC;IAC7G,CAAC;;AAGH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;QACnF,MAAM,MAAM,GAAsB;YAChC,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,IAAa,EAAE;YACvC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAa,EAAE;SAC7C,CAAC;QAEF,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,EAAE,IAAI,EAAE,IAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QAEnF,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAE,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACvC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;QAEnD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAE,CAAC;QACtD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,MAAM,GAAsB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,IAAa,EAAE,CAAC,CAAC;QAC5E,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,EAAE,IAAI,EAAE,IAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QACnG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,MAAM,GAAsB,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,IAAa,EAAE,CAAC,CAAC;QACtF,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC;YAC5B,IAAI,EAAE,IAAa;YACnB,MAAM;YACN,QAAQ,EAAE,QAAQ;YAClB,cAAc,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,aAAa,EAAE,aAAa,CAAC;SAC3D,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,uBAAuB,EAAE,uBAAuB,CAAC,CAAC,CAAC;IACtG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,MAAM,GAAsB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,SAAkB,EAAE,CAAC,CAAC;QACjF,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,EAAE,IAAI,EAAE,SAAkB,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxF,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;QACnF,MAAM,MAAM,GAAsB;YAChC,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,IAAa,EAAE;YACvC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAa,EAAE;SAC7C,CAAC;QACF,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,EAAE,IAAI,EAAE,IAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnF,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAE,CAAC;QAChD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAE,CAAC;QACtD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;QACtD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;QACzF,MAAM,KAAK,GAAG,QAAQ,CAAC;QACvB,MAAM,MAAM,GAAsB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,IAAa,EAAE,CAAC,CAAC;QAC5E,MAAM,SAAS,CAAC,EAAE,IAAI,EAAE,IAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrE,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+EAA+E,EAAE,KAAK,IAAI,EAAE;QAC7F,MAAM,MAAM,GAAsB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,IAAa,EAAE,CAAC,CAAC;QAC5E,MAAM,MAAM,CACV,SAAS,CAAC,EAAE,IAAI,EAAE,IAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,4BAA4B,EAAE,CAAC,CACnF,CAAC,OAAO,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,mGAAmG,EAAE,KAAK,IAAI,EAAE;QACjH,MAAM,eAAe,GAAG,MAAM,CAAC,wBAAwB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC/E,iIAAiI;QACjI,OAAQ,UAAsC,CAAC,OAAO,CAAC;QAEvD,IAAI,CAAC;YACH,IAAI,gBAAyB,CAAC;YAC9B,MAAM,cAAc,CAAC,2CAA2C,EAAE,mBAAmB,EAAE,KAAK,IAAI,EAAE;gBAChG,gBAAgB,GAAG,UAAU,CAAC,OAAO,CAAC;gBACtC,kFAAkF;gBAClF,wDAAwD;gBACxD,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;YAC5C,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,gBAAgB,CAAC,CAAC,WAAW,EAAE,CAAC;YACvC,MAAM,CAAC,MAAM,CAAC,wBAAwB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;YAC/E,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAC5C,CAAC;gBAAS,CAAC;YACT,IAAI,eAAe;gBAAE,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;QACrF,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,EAAE,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;QACzF,MAAM,MAAM,GAAsB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,IAAa,EAAE,CAAC,CAAC;QAC5E,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,EAAE,IAAI,EAAE,IAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnF,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAE3B,MAAM,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAClE,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,SAAS,IAAI,EAAE,CAAC;QAE9D,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAChD,SAAS,CAAC,SAAS,GAAG,OAAO,CAAC;QAC9B,SAAS,CAAC,YAAY,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;QAC/C,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAErC,MAAM,QAAQ,GAAG,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,SAAS,GAAG,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE9C,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,MAAM,UAAW,SAAQ,iBAAiB;YACxC,MAAM,CAAC,aAAa,GAAG,IAAa,CAAC;YACrC,MAAM,CAAC,aAAa,GAAG,KAAK,CAAC;YAC7B,MAAM;gBACJ,OAAO,YAAY,CAAC,MAAM,EAAE;oBAC1B,EAAE,EAAE,MAAM;oBACV,QAAQ,EAAE;wBACR,YAAY,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,eAAe,EAAE,CAAC;wBAC9D,YAAY,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,eAAe,EAAE,CAAC;qBAC1G;iBACF,EAAE,eAAe,EAAE,CAAC,CAAC;YACxB,CAAC;;QAGH,MAAM,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,UAAmB,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;QAEpF,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrD,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAExD,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,IAAI,UAAU,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3F,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAEvB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"register-fallback.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/register-fallback.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from "vitest";
|
|
2
|
-
// Simulates Node < 22.15, which has no module.registerHooks — registerLoaderHook()
|
|
3
|
-
// must fall back to the older, off-thread module.register() API instead.
|
|
4
|
-
const { register } = vi.hoisted(() => ({
|
|
5
|
-
register: vi.fn(),
|
|
6
|
-
}));
|
|
7
|
-
vi.mock("node:module", async (importOriginal) => {
|
|
8
|
-
const actual = await importOriginal();
|
|
9
|
-
return { ...actual, registerHooks: undefined, register };
|
|
10
|
-
});
|
|
11
|
-
describe("registerLoaderHook() fallback (no module.registerHooks)", () => {
|
|
12
|
-
it("registers the standalone loader-hook module via module.register()", async () => {
|
|
13
|
-
const { registerLoaderHook } = await import("../index");
|
|
14
|
-
registerLoaderHook();
|
|
15
|
-
expect(register).toHaveBeenCalledOnce();
|
|
16
|
-
const [specifier] = register.mock.calls[0];
|
|
17
|
-
expect(specifier.href).toContain("loader-hook.js");
|
|
18
|
-
});
|
|
19
|
-
});
|
|
20
|
-
//# sourceMappingURL=register-fallback.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"register-fallback.test.js","sourceRoot":"","sources":["../../src/__tests__/register-fallback.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAElD,mFAAmF;AACnF,yEAAyE;AACzE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACrC,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE;CAClB,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE;IAC9C,MAAM,MAAM,GAAG,MAAM,cAAc,EAAgC,CAAC;IACpE,OAAO,EAAE,GAAG,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AAC3D,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,yDAAyD,EAAE,GAAG,EAAE;IACvE,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QACxD,kBAAkB,EAAE,CAAC;QAErB,MAAM,CAAC,QAAQ,CAAC,CAAC,oBAAoB,EAAE,CAAC;QACxC,MAAM,CAAC,SAAS,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAU,CAAC;QACpD,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-sync.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/resolve-sync.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from "vitest";
|
|
2
|
-
import { registerLoaderHook } from "../index";
|
|
3
|
-
const { registerHooks } = vi.hoisted(() => ({
|
|
4
|
-
registerHooks: vi.fn(),
|
|
5
|
-
}));
|
|
6
|
-
vi.mock("node:module", async (importOriginal) => {
|
|
7
|
-
const actual = await importOriginal();
|
|
8
|
-
return { ...actual, registerHooks, register: vi.fn() };
|
|
9
|
-
});
|
|
10
|
-
const CONTEXT = {};
|
|
11
|
-
function notFound() {
|
|
12
|
-
const err = new Error("not found");
|
|
13
|
-
err.code = "ERR_MODULE_NOT_FOUND";
|
|
14
|
-
throw err;
|
|
15
|
-
}
|
|
16
|
-
function ok(url) {
|
|
17
|
-
return { url, shortCircuit: true };
|
|
18
|
-
}
|
|
19
|
-
describe("resolveSync (registered via module.registerHooks())", () => {
|
|
20
|
-
registerLoaderHook();
|
|
21
|
-
const resolveSync = registerHooks.mock.calls[0][0].resolve;
|
|
22
|
-
it("registers exactly once via module.registerHooks()", () => {
|
|
23
|
-
expect(registerHooks).toHaveBeenCalledOnce();
|
|
24
|
-
});
|
|
25
|
-
it("returns nextResolve's result directly when it succeeds", () => {
|
|
26
|
-
const nextResolve = vi.fn(() => ok("file:///real.js"));
|
|
27
|
-
expect(resolveSync("./real", CONTEXT, nextResolve)).toEqual(ok("file:///real.js"));
|
|
28
|
-
expect(nextResolve).toHaveBeenCalledOnce();
|
|
29
|
-
});
|
|
30
|
-
it("rethrows without retrying for a bare (non-relative) specifier", () => {
|
|
31
|
-
const nextResolve = vi.fn(() => notFound());
|
|
32
|
-
expect(() => resolveSync("some-package", CONTEXT, nextResolve)).toThrow("not found");
|
|
33
|
-
expect(nextResolve).toHaveBeenCalledOnce();
|
|
34
|
-
});
|
|
35
|
-
it("rethrows without retrying when the error has no code", () => {
|
|
36
|
-
const nextResolve = vi.fn(() => {
|
|
37
|
-
throw new Error("weird failure");
|
|
38
|
-
});
|
|
39
|
-
expect(() => resolveSync("./router", CONTEXT, nextResolve)).toThrow("weird failure");
|
|
40
|
-
expect(nextResolve).toHaveBeenCalledOnce();
|
|
41
|
-
});
|
|
42
|
-
it("rethrows without retrying for a non-retryable error code", () => {
|
|
43
|
-
const nextResolve = vi.fn(() => {
|
|
44
|
-
const err = new Error("permission denied");
|
|
45
|
-
err.code = "EACCES";
|
|
46
|
-
throw err;
|
|
47
|
-
});
|
|
48
|
-
expect(() => resolveSync("./router", CONTEXT, nextResolve)).toThrow("permission denied");
|
|
49
|
-
expect(nextResolve).toHaveBeenCalledOnce();
|
|
50
|
-
});
|
|
51
|
-
it("retries with a .js suffix and returns it when that succeeds", () => {
|
|
52
|
-
const nextResolve = vi.fn((specifier) => specifier === "./router.js" ? ok("file:///router.js") : notFound());
|
|
53
|
-
expect(resolveSync("./router", CONTEXT, nextResolve)).toEqual(ok("file:///router.js"));
|
|
54
|
-
expect(nextResolve).toHaveBeenCalledTimes(2);
|
|
55
|
-
});
|
|
56
|
-
it("falls back to /index.js when the .js candidate also fails", () => {
|
|
57
|
-
const nextResolve = vi.fn((specifier) => specifier === "./router/index.js" ? ok("file:///router/index.js") : notFound());
|
|
58
|
-
expect(resolveSync("./router", CONTEXT, nextResolve)).toEqual(ok("file:///router/index.js"));
|
|
59
|
-
expect(nextResolve).toHaveBeenCalledTimes(3);
|
|
60
|
-
});
|
|
61
|
-
it("rethrows the original error when both retry candidates fail", () => {
|
|
62
|
-
const nextResolve = vi.fn(() => notFound());
|
|
63
|
-
expect(() => resolveSync("../router", CONTEXT, nextResolve)).toThrow("not found");
|
|
64
|
-
expect(nextResolve).toHaveBeenCalledTimes(3);
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
//# sourceMappingURL=resolve-sync.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-sync.test.js","sourceRoot":"","sources":["../../src/__tests__/resolve-sync.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"routes.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/routes.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { flattenRoutes, isStaticPath, pathToOutputFile, resolvePaths } from "../routes";
|
|
3
|
-
const Noop = class {
|
|
4
|
-
};
|
|
5
|
-
describe("flattenRoutes", () => {
|
|
6
|
-
it("flattens a flat route list unchanged", () => {
|
|
7
|
-
const routes = [
|
|
8
|
-
{ path: "/", component: Noop },
|
|
9
|
-
{ path: "/about", component: Noop },
|
|
10
|
-
];
|
|
11
|
-
expect(flattenRoutes(routes).map((r) => r.fullPath)).toEqual(["/", "/about"]);
|
|
12
|
-
});
|
|
13
|
-
it("prefixes nested children with the parent path", () => {
|
|
14
|
-
const routes = [
|
|
15
|
-
{
|
|
16
|
-
path: "/blog",
|
|
17
|
-
component: Noop,
|
|
18
|
-
children: [
|
|
19
|
-
{ path: "/", component: Noop },
|
|
20
|
-
{ path: "/:slug", component: Noop },
|
|
21
|
-
],
|
|
22
|
-
},
|
|
23
|
-
];
|
|
24
|
-
expect(flattenRoutes(routes).map((r) => r.fullPath)).toEqual(["/blog", "/blog/", "/blog/:slug"]);
|
|
25
|
-
});
|
|
26
|
-
it("treats a root parent's prefix as empty, matching RouterInstance.addRoute", () => {
|
|
27
|
-
const routes = [
|
|
28
|
-
{
|
|
29
|
-
path: "/",
|
|
30
|
-
component: Noop,
|
|
31
|
-
children: [{ path: "/dashboard", component: Noop }],
|
|
32
|
-
},
|
|
33
|
-
];
|
|
34
|
-
expect(flattenRoutes(routes).map((r) => r.fullPath)).toEqual(["/", "/dashboard"]);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
describe("isStaticPath", () => {
|
|
38
|
-
it("treats plain paths as static", () => {
|
|
39
|
-
expect(isStaticPath("/about")).toBe(true);
|
|
40
|
-
expect(isStaticPath("/")).toBe(true);
|
|
41
|
-
});
|
|
42
|
-
it("treats :param segments as dynamic", () => {
|
|
43
|
-
expect(isStaticPath("/blog/:slug")).toBe(false);
|
|
44
|
-
});
|
|
45
|
-
it("treats optional :param? segments as dynamic", () => {
|
|
46
|
-
expect(isStaticPath("/users/:id?")).toBe(false);
|
|
47
|
-
});
|
|
48
|
-
it("treats ** catch-alls as dynamic", () => {
|
|
49
|
-
expect(isStaticPath("/docs/**")).toBe(false);
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
describe("resolvePaths", () => {
|
|
53
|
-
it("returns static paths as-is", async () => {
|
|
54
|
-
const routes = [
|
|
55
|
-
{ path: "/", component: Noop },
|
|
56
|
-
{ path: "/about", component: Noop },
|
|
57
|
-
];
|
|
58
|
-
expect(await resolvePaths({ routes })).toEqual(["/", "/about"]);
|
|
59
|
-
});
|
|
60
|
-
it("expands a dynamic route via getStaticPaths", async () => {
|
|
61
|
-
const routes = [{ path: "/blog/:slug", component: Noop }];
|
|
62
|
-
const paths = await resolvePaths({
|
|
63
|
-
routes,
|
|
64
|
-
getStaticPaths: async () => ["/blog/hello", "/blog/world"],
|
|
65
|
-
});
|
|
66
|
-
expect(paths).toEqual(["/blog/hello", "/blog/world"]);
|
|
67
|
-
});
|
|
68
|
-
it("skips dynamic routes with no getStaticPaths", async () => {
|
|
69
|
-
const routes = [
|
|
70
|
-
{ path: "/", component: Noop },
|
|
71
|
-
{ path: "/blog/:slug", component: Noop },
|
|
72
|
-
];
|
|
73
|
-
expect(await resolvePaths({ routes })).toEqual(["/"]);
|
|
74
|
-
});
|
|
75
|
-
it("passes the route and its full path pattern to getStaticPaths", async () => {
|
|
76
|
-
const target = { path: "/blog/:slug", component: Noop };
|
|
77
|
-
const routes = [target];
|
|
78
|
-
let seen;
|
|
79
|
-
await resolvePaths({
|
|
80
|
-
routes,
|
|
81
|
-
getStaticPaths: async (route, fullPath) => {
|
|
82
|
-
seen = [route, fullPath];
|
|
83
|
-
return [];
|
|
84
|
-
},
|
|
85
|
-
});
|
|
86
|
-
expect(seen).toEqual([target, "/blog/:slug"]);
|
|
87
|
-
});
|
|
88
|
-
it("de-duplicates paths across routes", async () => {
|
|
89
|
-
const routes = [
|
|
90
|
-
{ path: "/blog/:slug", component: Noop },
|
|
91
|
-
{ path: "/other/:slug", component: Noop },
|
|
92
|
-
];
|
|
93
|
-
const paths = await resolvePaths({
|
|
94
|
-
routes,
|
|
95
|
-
getStaticPaths: async () => ["/shared"],
|
|
96
|
-
});
|
|
97
|
-
expect(paths).toEqual(["/shared"]);
|
|
98
|
-
});
|
|
99
|
-
it("expands a dynamic route via its own colocated getStaticPaths, with no global fallback needed", async () => {
|
|
100
|
-
const routes = [
|
|
101
|
-
{ path: "/blog/:slug", component: Noop, getStaticPaths: async () => ["/blog/hello", "/blog/world"] },
|
|
102
|
-
];
|
|
103
|
-
expect(await resolvePaths({ routes })).toEqual(["/blog/hello", "/blog/world"]);
|
|
104
|
-
});
|
|
105
|
-
it("passes the route's own full path to its colocated getStaticPaths", async () => {
|
|
106
|
-
let seen;
|
|
107
|
-
const routes = [
|
|
108
|
-
{
|
|
109
|
-
path: "/blog/:slug",
|
|
110
|
-
component: Noop,
|
|
111
|
-
getStaticPaths: async (fullPath) => {
|
|
112
|
-
seen = fullPath;
|
|
113
|
-
return [];
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
];
|
|
117
|
-
await resolvePaths({ routes });
|
|
118
|
-
expect(seen).toBe("/blog/:slug");
|
|
119
|
-
});
|
|
120
|
-
it("prefers a route's own getStaticPaths over the global fallback", async () => {
|
|
121
|
-
const routes = [
|
|
122
|
-
{ path: "/blog/:slug", component: Noop, getStaticPaths: async () => ["/blog/own"] },
|
|
123
|
-
];
|
|
124
|
-
const paths = await resolvePaths({
|
|
125
|
-
routes,
|
|
126
|
-
getStaticPaths: async () => ["/blog/global"],
|
|
127
|
-
});
|
|
128
|
-
expect(paths).toEqual(["/blog/own"]);
|
|
129
|
-
});
|
|
130
|
-
it("falls back to the global getStaticPaths for routes with no colocated one, alongside routes that have their own", async () => {
|
|
131
|
-
const routes = [
|
|
132
|
-
{ path: "/blog/:slug", component: Noop, getStaticPaths: async () => ["/blog/own"] },
|
|
133
|
-
{ path: "/other/:slug", component: Noop },
|
|
134
|
-
];
|
|
135
|
-
const paths = await resolvePaths({
|
|
136
|
-
routes,
|
|
137
|
-
getStaticPaths: async (_route, fullPath) => (fullPath === "/other/:slug" ? ["/other/global"] : []),
|
|
138
|
-
});
|
|
139
|
-
expect(paths).toEqual(["/blog/own", "/other/global"]);
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
describe("pathToOutputFile", () => {
|
|
143
|
-
it("maps the root path to index.html", () => {
|
|
144
|
-
expect(pathToOutputFile("/")).toBe("index.html");
|
|
145
|
-
});
|
|
146
|
-
it("maps a nested path to <path>/index.html", () => {
|
|
147
|
-
expect(pathToOutputFile("/about")).toBe("about/index.html");
|
|
148
|
-
expect(pathToOutputFile("/blog/hello-world")).toBe("blog/hello-world/index.html");
|
|
149
|
-
});
|
|
150
|
-
it("normalizes surrounding slashes", () => {
|
|
151
|
-
expect(pathToOutputFile("/about/")).toBe("about/index.html");
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
//# sourceMappingURL=routes.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"routes.test.js","sourceRoot":"","sources":["../../src/__tests__/routes.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from "vitest";
|
|
2
|
-
|
|
3
|
-
import type { ResolveFnOutput, ResolveHookContext } from "node:module";
|
|
4
|
-
|
|
5
|
-
import { resolve } from "../loader-hook";
|
|
6
|
-
|
|
7
|
-
const CONTEXT = {} as ResolveHookContext;
|
|
8
|
-
|
|
9
|
-
function notFound(): never {
|
|
10
|
-
const err = new Error("not found") as Error & { code?: string };
|
|
11
|
-
err.code = "ERR_MODULE_NOT_FOUND";
|
|
12
|
-
throw err;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function ok(url: string): ResolveFnOutput {
|
|
16
|
-
return { url, shortCircuit: true } as ResolveFnOutput;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
describe("loader-hook resolve()", () => {
|
|
20
|
-
it("returns nextResolve's result directly when it succeeds", async () => {
|
|
21
|
-
const nextResolve = vi.fn(async () => ok("file:///real.js"));
|
|
22
|
-
const result = await resolve("./real", CONTEXT, nextResolve);
|
|
23
|
-
expect(result).toEqual(ok("file:///real.js"));
|
|
24
|
-
expect(nextResolve).toHaveBeenCalledOnce();
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("rethrows without retrying for a bare (non-relative) specifier", async () => {
|
|
28
|
-
const nextResolve = vi.fn(async () => notFound());
|
|
29
|
-
await expect(resolve("some-package", CONTEXT, nextResolve)).rejects.toThrow("not found");
|
|
30
|
-
expect(nextResolve).toHaveBeenCalledOnce();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it("rethrows without retrying when the error has no code", async () => {
|
|
34
|
-
const nextResolve = vi.fn(async () => {
|
|
35
|
-
throw new Error("weird failure");
|
|
36
|
-
});
|
|
37
|
-
await expect(resolve("./router", CONTEXT, nextResolve)).rejects.toThrow("weird failure");
|
|
38
|
-
expect(nextResolve).toHaveBeenCalledOnce();
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it("rethrows without retrying for a non-retryable error code", async () => {
|
|
42
|
-
const nextResolve = vi.fn(async () => {
|
|
43
|
-
const err = new Error("permission denied") as Error & { code?: string };
|
|
44
|
-
err.code = "EACCES";
|
|
45
|
-
throw err;
|
|
46
|
-
});
|
|
47
|
-
await expect(resolve("./router", CONTEXT, nextResolve)).rejects.toThrow("permission denied");
|
|
48
|
-
expect(nextResolve).toHaveBeenCalledOnce();
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it("retries with a .js suffix and returns it when that succeeds", async () => {
|
|
52
|
-
const nextResolve = vi.fn(async (specifier: string) => {
|
|
53
|
-
if (specifier === "./router.js") return ok("file:///router.js");
|
|
54
|
-
return notFound();
|
|
55
|
-
});
|
|
56
|
-
const result = await resolve("./router", CONTEXT, nextResolve);
|
|
57
|
-
expect(result).toEqual(ok("file:///router.js"));
|
|
58
|
-
expect(nextResolve).toHaveBeenCalledTimes(2);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it("falls back to /index.js when the .js candidate also fails", async () => {
|
|
62
|
-
const nextResolve = vi.fn(async (specifier: string) => {
|
|
63
|
-
if (specifier === "./router/index.js") return ok("file:///router/index.js");
|
|
64
|
-
return notFound();
|
|
65
|
-
});
|
|
66
|
-
const result = await resolve("./router", CONTEXT, nextResolve);
|
|
67
|
-
expect(result).toEqual(ok("file:///router/index.js"));
|
|
68
|
-
expect(nextResolve).toHaveBeenCalledTimes(3);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it("rethrows the original error when both retry candidates fail", async () => {
|
|
72
|
-
const nextResolve = vi.fn(async () => notFound());
|
|
73
|
-
await expect(resolve("../router", CONTEXT, nextResolve)).rejects.toThrow("not found");
|
|
74
|
-
expect(nextResolve).toHaveBeenCalledTimes(3);
|
|
75
|
-
});
|
|
76
|
-
});
|