@alepha/react 0.13.2 → 0.13.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/dist/auth/index.browser.js +5 -0
- package/dist/auth/index.browser.js.map +1 -1
- package/dist/auth/index.d.ts +139 -68
- package/dist/auth/index.js +5 -0
- package/dist/auth/index.js.map +1 -1
- package/dist/core/index.browser.js +31 -10
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +113 -83
- package/dist/core/index.js +40 -13
- package/dist/core/index.js.map +1 -1
- package/dist/head/index.browser.js +21 -10
- package/dist/head/index.browser.js.map +1 -1
- package/dist/head/index.d.ts +41 -38
- package/dist/head/index.js +22 -10
- package/dist/head/index.js.map +1 -1
- package/package.json +6 -6
- package/src/auth/services/ReactAuth.ts +10 -0
- package/src/core/components/NestedView.tsx +5 -1
- package/src/core/components/NotFound.tsx +10 -6
- package/src/core/providers/ReactBrowserRouterProvider.ts +1 -0
- package/src/core/providers/ReactPageProvider.ts +3 -0
- package/src/core/providers/ReactServerProvider.ts +23 -12
- package/src/core/services/ReactRouter.ts +16 -0
- package/src/head/interfaces/Head.ts +1 -0
- package/src/head/primitives/$head.ts +4 -1
- package/src/head/providers/BrowserHeadProvider.ts +13 -0
- package/src/head/providers/HeadProvider.ts +11 -9
- package/src/head/providers/ServerHeadProvider.ts +6 -0
|
@@ -184,19 +184,17 @@ export class ReactServerProvider {
|
|
|
184
184
|
}
|
|
185
185
|
|
|
186
186
|
for (const page of this.pageApi.getPages()) {
|
|
187
|
-
if (page.
|
|
188
|
-
|
|
187
|
+
if (page.component || page.lazy) {
|
|
188
|
+
this.log.debug(`+ ${page.match} -> ${page.name}`);
|
|
189
|
+
|
|
190
|
+
this.serverRouterProvider.createRoute({
|
|
191
|
+
...page,
|
|
192
|
+
schema: undefined, // schema is handled by the page primitive provider for now (shared by browser and server)
|
|
193
|
+
method: "GET",
|
|
194
|
+
path: page.match,
|
|
195
|
+
handler: this.createHandler(page, templateLoader),
|
|
196
|
+
});
|
|
189
197
|
}
|
|
190
|
-
|
|
191
|
-
this.log.debug(`+ ${page.match} -> ${page.name}`);
|
|
192
|
-
|
|
193
|
-
this.serverRouterProvider.createRoute({
|
|
194
|
-
...page,
|
|
195
|
-
schema: undefined, // schema is handled by the page primitive provider for now (shared by browser and server)
|
|
196
|
-
method: "GET",
|
|
197
|
-
path: page.match,
|
|
198
|
-
handler: this.createHandler(page, templateLoader),
|
|
199
|
-
});
|
|
200
198
|
}
|
|
201
199
|
}
|
|
202
200
|
|
|
@@ -339,6 +337,8 @@ export class ReactServerProvider {
|
|
|
339
337
|
|
|
340
338
|
const state = entry as ReactRouterState;
|
|
341
339
|
|
|
340
|
+
state.name = route.name;
|
|
341
|
+
|
|
342
342
|
if (this.alepha.has(ServerLinksProvider)) {
|
|
343
343
|
this.alepha.store.set(
|
|
344
344
|
"alepha.server.request.apiLinks",
|
|
@@ -352,6 +352,9 @@ export class ReactServerProvider {
|
|
|
352
352
|
let target: PageRoute | undefined = route; // TODO: move to PagePrimitiveProvider
|
|
353
353
|
while (target) {
|
|
354
354
|
if (route.can && !route.can()) {
|
|
355
|
+
this.log.warn(
|
|
356
|
+
`Access to page '${route.name}' is forbidden by can() check`,
|
|
357
|
+
)
|
|
355
358
|
// if the page is not accessible, return 403
|
|
356
359
|
reply.status = 403;
|
|
357
360
|
reply.headers["content-type"] = "text/plain";
|
|
@@ -383,6 +386,9 @@ export class ReactServerProvider {
|
|
|
383
386
|
this.serverTimingProvider.endTiming("createLayers");
|
|
384
387
|
|
|
385
388
|
if (redirect) {
|
|
389
|
+
this.log.debug("Resolver resulted in redirection", {
|
|
390
|
+
redirect,
|
|
391
|
+
});
|
|
386
392
|
return reply.redirect(redirect);
|
|
387
393
|
}
|
|
388
394
|
|
|
@@ -402,9 +408,14 @@ export class ReactServerProvider {
|
|
|
402
408
|
? html.redirect
|
|
403
409
|
: this.pageApi.href(html.redirect),
|
|
404
410
|
);
|
|
411
|
+
this.log.debug("Rendering resulted in redirection", {
|
|
412
|
+
redirect: html.redirect,
|
|
413
|
+
});
|
|
405
414
|
return;
|
|
406
415
|
}
|
|
407
416
|
|
|
417
|
+
this.log.trace("Page rendered to HTML successfully");
|
|
418
|
+
|
|
408
419
|
const event = {
|
|
409
420
|
request: serverRequest,
|
|
410
421
|
state,
|
|
@@ -51,6 +51,22 @@ export class ReactRouter<T extends object> {
|
|
|
51
51
|
return isActive;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
public node(
|
|
55
|
+
name: keyof VirtualRouter<T> | string,
|
|
56
|
+
config: {
|
|
57
|
+
params?: Record<string, any>;
|
|
58
|
+
query?: Record<string, any>;
|
|
59
|
+
} = {},
|
|
60
|
+
) {
|
|
61
|
+
const page = this.pageApi.page(name as string);
|
|
62
|
+
return {
|
|
63
|
+
...page,
|
|
64
|
+
label: page.label ?? page.name,
|
|
65
|
+
href: this.path(name, config),
|
|
66
|
+
children: undefined,
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
54
70
|
public path(
|
|
55
71
|
name: keyof VirtualRouter<T> | string,
|
|
56
72
|
config: {
|
|
@@ -18,7 +18,10 @@ export type HeadPrimitiveOptions = Head | (() => Head);
|
|
|
18
18
|
export class HeadPrimitive extends Primitive<HeadPrimitiveOptions> {
|
|
19
19
|
protected readonly provider = $inject(HeadProvider);
|
|
20
20
|
protected onInit() {
|
|
21
|
-
this.provider.global =
|
|
21
|
+
this.provider.global = [
|
|
22
|
+
...(this.provider.global ?? []),
|
|
23
|
+
this.options,
|
|
24
|
+
];
|
|
22
25
|
}
|
|
23
26
|
}
|
|
24
27
|
|
|
@@ -101,5 +101,18 @@ export class BrowserHeadProvider {
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
|
+
|
|
105
|
+
if (head.link) {
|
|
106
|
+
for (const it of head.link) {
|
|
107
|
+
const { rel, href } = it;
|
|
108
|
+
let link = document.querySelector(`link[rel="${rel}"][href="${href}"]`);
|
|
109
|
+
if (!link) {
|
|
110
|
+
link = document.createElement("link");
|
|
111
|
+
link.setAttribute("rel", rel);
|
|
112
|
+
link.setAttribute("href", href);
|
|
113
|
+
document.head.appendChild(link);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
104
117
|
}
|
|
105
118
|
}
|
|
@@ -2,21 +2,23 @@ import type { PageRoute, ReactRouterState } from "@alepha/react";
|
|
|
2
2
|
import type { Head } from "../interfaces/Head.ts";
|
|
3
3
|
|
|
4
4
|
export class HeadProvider {
|
|
5
|
-
public global?: Head | (() => Head);
|
|
6
|
-
|
|
7
|
-
protected getGlobalHead(): Head | undefined {
|
|
8
|
-
if (typeof this.global === "function") {
|
|
9
|
-
return this.global();
|
|
10
|
-
}
|
|
11
|
-
return this.global;
|
|
12
|
-
}
|
|
5
|
+
public global?: Array<Head | (() => Head)> = [];
|
|
13
6
|
|
|
14
7
|
public fillHead(state: ReactRouterState) {
|
|
15
8
|
state.head = {
|
|
16
9
|
...state.head,
|
|
17
|
-
...this.getGlobalHead(),
|
|
18
10
|
};
|
|
19
11
|
|
|
12
|
+
for (const h of this.global ?? []) {
|
|
13
|
+
const head =
|
|
14
|
+
typeof h === "function" ? h() : h;
|
|
15
|
+
state.head = {
|
|
16
|
+
...state.head,
|
|
17
|
+
...head,
|
|
18
|
+
meta: [...(state.head.meta ?? []), ...(head.meta ?? [])],
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
20
22
|
for (const layer of state.layers) {
|
|
21
23
|
if (layer.route?.head && !layer.error) {
|
|
22
24
|
this.fillHeadByPage(layer.route, state, layer.props ?? {});
|
|
@@ -62,6 +62,12 @@ export class ServerHeadProvider {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
if (head.link) {
|
|
66
|
+
for (const link of head.link) {
|
|
67
|
+
headContent += `<link rel="${this.escapeHtml(link.rel)}" href="${this.escapeHtml(link.href)}">\n`;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
65
71
|
// Inject into <head>...</head>
|
|
66
72
|
result = result.replace(
|
|
67
73
|
/<head([^>]*)>(.*?)<\/head>/is,
|