rasengan 1.0.0-beta.1
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/LICENSE +21 -0
- package/lib/cli/dirname.d.ts +2 -0
- package/lib/cli/dirname.js +6 -0
- package/lib/cli/dirname.js.map +1 -0
- package/lib/cli/index.d.ts +2 -0
- package/lib/cli/index.js +101 -0
- package/lib/cli/index.js.map +1 -0
- package/lib/config/index.d.ts +39 -0
- package/lib/config/index.js +57 -0
- package/lib/config/index.js.map +1 -0
- package/lib/config/type.d.ts +68 -0
- package/lib/config/type.js +2 -0
- package/lib/config/type.js.map +1 -0
- package/lib/core/components/index.d.ts +26 -0
- package/lib/core/components/index.js +72 -0
- package/lib/core/components/index.js.map +1 -0
- package/lib/core/index.d.ts +2 -0
- package/lib/core/index.js +2 -0
- package/lib/core/index.js.map +1 -0
- package/lib/core/interfaces.d.ts +76 -0
- package/lib/core/interfaces.js +91 -0
- package/lib/core/interfaces.js.map +1 -0
- package/lib/core/types.d.ts +45 -0
- package/lib/core/types.js +2 -0
- package/lib/core/types.js.map +1 -0
- package/lib/decorators/index.d.ts +2 -0
- package/lib/decorators/index.js +3 -0
- package/lib/decorators/index.js.map +1 -0
- package/lib/decorators/route.d.ts +7 -0
- package/lib/decorators/route.js +25 -0
- package/lib/decorators/route.js.map +1 -0
- package/lib/decorators/router.d.ts +7 -0
- package/lib/decorators/router.js +24 -0
- package/lib/decorators/router.js.map +1 -0
- package/lib/decorators/types.d.ts +47 -0
- package/lib/decorators/types.js +2 -0
- package/lib/decorators/types.js.map +1 -0
- package/lib/entries/entry-client.d.ts +1 -0
- package/lib/entries/entry-client.js +15 -0
- package/lib/entries/entry-client.js.map +1 -0
- package/lib/entries/entry-server.d.ts +6 -0
- package/lib/entries/entry-server.js +20 -0
- package/lib/entries/entry-server.js.map +1 -0
- package/lib/hooks/index.d.ts +0 -0
- package/lib/hooks/index.js +1 -0
- package/lib/hooks/index.js.map +1 -0
- package/lib/index.d.ts +6 -0
- package/lib/index.js +10 -0
- package/lib/index.js.map +1 -0
- package/lib/routing/components/index.d.ts +32 -0
- package/lib/routing/components/index.js +69 -0
- package/lib/routing/components/index.js.map +1 -0
- package/lib/routing/index.d.ts +3 -0
- package/lib/routing/index.js +4 -0
- package/lib/routing/index.js.map +1 -0
- package/lib/routing/interfaces.d.ts +67 -0
- package/lib/routing/interfaces.js +88 -0
- package/lib/routing/interfaces.js.map +1 -0
- package/lib/routing/types.d.ts +4 -0
- package/lib/routing/types.js +2 -0
- package/lib/routing/types.js.map +1 -0
- package/lib/routing/utils/index.d.ts +40 -0
- package/lib/routing/utils/index.js +256 -0
- package/lib/routing/utils/index.js.map +1 -0
- package/lib/server/functions/vercel/api/index.d.ts +2 -0
- package/lib/server/functions/vercel/api/index.js +91 -0
- package/lib/server/functions/vercel/api/index.js.map +1 -0
- package/lib/server/functions/vercel/vercel.json +12 -0
- package/lib/server/utils/createFetchRequest.d.ts +5 -0
- package/lib/server/utils/createFetchRequest.js +34 -0
- package/lib/server/utils/createFetchRequest.js.map +1 -0
- package/lib/server/utils/getIp.d.ts +1 -0
- package/lib/server/utils/getIp.js +30 -0
- package/lib/server/utils/getIp.js.map +1 -0
- package/lib/server/utils/handleError.d.ts +2 -0
- package/lib/server/utils/handleError.js +28 -0
- package/lib/server/utils/handleError.js.map +1 -0
- package/lib/server/utils/index.d.ts +5 -0
- package/lib/server/utils/index.js +8 -0
- package/lib/server/utils/index.js.map +1 -0
- package/lib/server/utils/log.d.ts +6 -0
- package/lib/server/utils/log.js +69 -0
- package/lib/server/utils/log.js.map +1 -0
- package/package.json +75 -0
- package/server.js +229 -0
- package/src/cli/dirname.ts +7 -0
- package/src/cli/index.ts +134 -0
- package/src/config/index.ts +67 -0
- package/src/config/type.ts +76 -0
- package/src/core/components/index.tsx +111 -0
- package/src/core/index.ts +14 -0
- package/src/core/interfaces.tsx +129 -0
- package/src/core/types.ts +43 -0
- package/src/decorators/index.ts +2 -0
- package/src/decorators/route.ts +32 -0
- package/src/decorators/router.ts +30 -0
- package/src/decorators/types.ts +54 -0
- package/src/entries/entry-client.tsx +33 -0
- package/src/entries/entry-server.tsx +50 -0
- package/src/hooks/index.ts +0 -0
- package/src/index.ts +11 -0
- package/src/routing/components/index.tsx +125 -0
- package/src/routing/index.ts +23 -0
- package/src/routing/interfaces.ts +105 -0
- package/src/routing/types.ts +3 -0
- package/src/routing/utils/index.tsx +342 -0
- package/src/server/functions/vercel/api/index.ts +122 -0
- package/src/server/functions/vercel/vercel.json +12 -0
- package/src/server/utils/createFetchRequest.ts +40 -0
- package/src/server/utils/getIp.ts +37 -0
- package/src/server/utils/handleError.ts +36 -0
- package/src/server/utils/index.ts +15 -0
- package/src/server/utils/log.ts +115 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +30 -0
- package/tsconfig.lib.json +41 -0
- package/tsconfig.node.json +11 -0
- package/vite.config.ts +45 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { LoaderOptions, LoaderResponse, ReactComponentProps } from "./types.js";
|
|
3
|
+
import { Outlet } from "react-router-dom";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Layout component interface that defines the base structure of a Layout and a Page too.
|
|
7
|
+
*/
|
|
8
|
+
export interface ILayoutComponent {
|
|
9
|
+
/**
|
|
10
|
+
* Fonction Component that return a JSX Element for a UI
|
|
11
|
+
*/
|
|
12
|
+
render: React.FC<ReactComponentProps>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Layout component that represents a layout
|
|
17
|
+
*/
|
|
18
|
+
export abstract class LayoutComponent implements ILayoutComponent {
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
* Page path
|
|
22
|
+
*/
|
|
23
|
+
protected _path!: string;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Render method which is a React component
|
|
27
|
+
* @param props - props for the component
|
|
28
|
+
*/
|
|
29
|
+
abstract render(props?: ReactComponentProps): React.ReactNode;
|
|
30
|
+
|
|
31
|
+
// Getters
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get page path
|
|
35
|
+
*/
|
|
36
|
+
get path(): string {
|
|
37
|
+
return this._path;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Setters
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Set page path
|
|
44
|
+
*/
|
|
45
|
+
set path(path: string) {
|
|
46
|
+
this._path = path;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Default Layout
|
|
52
|
+
*/
|
|
53
|
+
export class DefaultLayout extends LayoutComponent {
|
|
54
|
+
constructor() {
|
|
55
|
+
super();
|
|
56
|
+
|
|
57
|
+
this._path = "/";
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
render(): React.ReactNode {
|
|
61
|
+
return (
|
|
62
|
+
<React.Fragment>
|
|
63
|
+
<Outlet />
|
|
64
|
+
</React.Fragment>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Page component that extends LayoutComponent and represents a page
|
|
71
|
+
*/
|
|
72
|
+
export abstract class PageComponent extends LayoutComponent {
|
|
73
|
+
/**
|
|
74
|
+
* Page title
|
|
75
|
+
*/
|
|
76
|
+
protected _title!: string;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Page description
|
|
80
|
+
*/
|
|
81
|
+
protected _description!: string;
|
|
82
|
+
|
|
83
|
+
// Getters
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Get page title
|
|
87
|
+
*/
|
|
88
|
+
get title(): string {
|
|
89
|
+
return this._title;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Get page description
|
|
94
|
+
*/
|
|
95
|
+
get description(): string {
|
|
96
|
+
return this._description;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Setters
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Set page title
|
|
103
|
+
*/
|
|
104
|
+
set title(title: string) {
|
|
105
|
+
this._title = title;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Set page description
|
|
110
|
+
*/
|
|
111
|
+
set description(description: string) {
|
|
112
|
+
this._description = description;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Loader method that will be called during a routing on the server side
|
|
117
|
+
* in order to get data for the page from the server
|
|
118
|
+
* @returns Promise<any>
|
|
119
|
+
*/
|
|
120
|
+
async loader(
|
|
121
|
+
_options: LoaderOptions
|
|
122
|
+
): Promise<LoaderResponse> {
|
|
123
|
+
return new Promise((resolve) => {
|
|
124
|
+
resolve({
|
|
125
|
+
props: {},
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { RouterComponent } from "../routing/interfaces.js";
|
|
2
|
+
import { PageComponent } from "./interfaces.js";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Props for App component
|
|
7
|
+
*/
|
|
8
|
+
export type AppProps = {
|
|
9
|
+
Component: React.FC<{ router: any }>;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Props for the base Component that takes the app router
|
|
14
|
+
*/
|
|
15
|
+
export type ComponentProps = {
|
|
16
|
+
router: RouterComponent;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type PageToRenderProps = {
|
|
20
|
+
page: PageComponent;
|
|
21
|
+
data: LoaderResponse;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Props for component react components
|
|
26
|
+
*/
|
|
27
|
+
export type ReactComponentProps = { [key: string]: any };
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Options for the loader function that loads data for a page from the server
|
|
31
|
+
*/
|
|
32
|
+
export type LoaderOptions = {
|
|
33
|
+
params: { [key: string]: any };
|
|
34
|
+
request: Request;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Data returned from the loader function
|
|
39
|
+
*/
|
|
40
|
+
export type LoaderResponse = {
|
|
41
|
+
props?: { [key: string]: any };
|
|
42
|
+
redirect?: string
|
|
43
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Router Decorators
|
|
2
|
+
|
|
3
|
+
import { RouteDecoratorProps } from "./types.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Decorator that add metadata for a page.
|
|
7
|
+
* @param props Object that define the necessary elements to create a router
|
|
8
|
+
* @returns
|
|
9
|
+
*/
|
|
10
|
+
export function Route(props: RouteDecoratorProps) {
|
|
11
|
+
return function (constructor: Function) {
|
|
12
|
+
// Handle errors
|
|
13
|
+
if (!props.path)
|
|
14
|
+
throw new Error("You must provide a path in the route decorator");
|
|
15
|
+
|
|
16
|
+
// Add values to properties
|
|
17
|
+
|
|
18
|
+
// Define path of the page
|
|
19
|
+
constructor.prototype._path = props.path;
|
|
20
|
+
|
|
21
|
+
// Define title of the page
|
|
22
|
+
constructor.prototype._title =
|
|
23
|
+
props.title ||
|
|
24
|
+
constructor.name.charAt(0).toUpperCase() + constructor.name.slice(1);
|
|
25
|
+
|
|
26
|
+
// Define description of the page
|
|
27
|
+
constructor.prototype._description = props.description || "";
|
|
28
|
+
|
|
29
|
+
Object.seal(constructor);
|
|
30
|
+
Object.seal(constructor.prototype);
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Router Decorators
|
|
2
|
+
|
|
3
|
+
import { DefaultLayout } from "../core/interfaces.js";
|
|
4
|
+
import { RouterDecoratorProps } from "./types.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Decorator that define a new router.
|
|
8
|
+
* @param props Object that define the necessary elements to create a router
|
|
9
|
+
* @returns
|
|
10
|
+
*/
|
|
11
|
+
export function Router(props: RouterDecoratorProps) {
|
|
12
|
+
return function (constructor: Function) {
|
|
13
|
+
// Handle errors
|
|
14
|
+
if (!props.pages) throw new Error("You must provide a list of pages in the router decorator");
|
|
15
|
+
|
|
16
|
+
// Add values to properties
|
|
17
|
+
|
|
18
|
+
// Define sub routers if provided or set and empty array
|
|
19
|
+
constructor.prototype["_routers"] = props.imports || [];
|
|
20
|
+
|
|
21
|
+
// Define layout if provided or set a default one.
|
|
22
|
+
constructor.prototype["_layout"] = props.layout || DefaultLayout;
|
|
23
|
+
|
|
24
|
+
// Define pages
|
|
25
|
+
constructor.prototype["_pages"] = props.pages;
|
|
26
|
+
|
|
27
|
+
Object.seal(constructor);
|
|
28
|
+
Object.seal(constructor.prototype);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { LayoutComponent, PageComponent } from "../core/interfaces.js";
|
|
2
|
+
import { RouterComponent } from "../routing/interfaces.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Props for Router Decorators
|
|
6
|
+
*/
|
|
7
|
+
export type RouterDecoratorProps = {
|
|
8
|
+
/**
|
|
9
|
+
* Usefull to collect sub routers
|
|
10
|
+
*/
|
|
11
|
+
imports?: Array<RouterComponent>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Usefull to define a layout
|
|
15
|
+
*/
|
|
16
|
+
layout?: LayoutComponent;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Usefull to collect pages
|
|
20
|
+
*/
|
|
21
|
+
pages: Array<PageComponent>;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Usefull to display a screen that let know to the user that the page is loading.
|
|
25
|
+
*/
|
|
26
|
+
loaderComponent?: React.FC;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Usefull to display a screen that let know to the user that the page is not found.
|
|
30
|
+
*/
|
|
31
|
+
notFoundComponent?: React.FC;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type RouteDecoratorProps = RouteLayoutDecoratorProps & {
|
|
35
|
+
/**
|
|
36
|
+
* Title of the page
|
|
37
|
+
*/
|
|
38
|
+
title?: string;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Description of the page
|
|
42
|
+
*/
|
|
43
|
+
description?: string;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Props for Layout Decorators
|
|
48
|
+
*/
|
|
49
|
+
export type RouteLayoutDecoratorProps = {
|
|
50
|
+
/**
|
|
51
|
+
* base path of the layout
|
|
52
|
+
*/
|
|
53
|
+
path: string;
|
|
54
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import ReactDOM from "react-dom/client";
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import App from "./../../../../src/main";
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
// import AppRouter from "./../../../../src/pages/app.router";
|
|
7
|
+
import { Component, ErrorBoundary } from "../core/components/index.js";
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
import config from "./../../../../rasengan.config.js";
|
|
10
|
+
|
|
11
|
+
import * as pkg from "react-helmet-async";
|
|
12
|
+
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
const { HelmetProvider } = pkg.default || pkg;
|
|
15
|
+
|
|
16
|
+
ReactDOM.hydrateRoot(
|
|
17
|
+
document.getElementById("root") as HTMLElement,
|
|
18
|
+
config.reactStrictMode ? (
|
|
19
|
+
<React.StrictMode>
|
|
20
|
+
<ErrorBoundary>
|
|
21
|
+
<HelmetProvider>
|
|
22
|
+
<App Component={Component} />
|
|
23
|
+
</HelmetProvider>
|
|
24
|
+
</ErrorBoundary>
|
|
25
|
+
</React.StrictMode>
|
|
26
|
+
) : (
|
|
27
|
+
<ErrorBoundary>
|
|
28
|
+
<HelmetProvider>
|
|
29
|
+
<App Component={Component} />
|
|
30
|
+
</HelmetProvider>
|
|
31
|
+
</ErrorBoundary>
|
|
32
|
+
)
|
|
33
|
+
);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import ReactDOMServer from "react-dom/server";
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import AppRouter from "./../../../../src/pages/app.router";
|
|
5
|
+
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
import {
|
|
8
|
+
generateStaticRoutes,
|
|
9
|
+
} from "../routing/utils/index.js";
|
|
10
|
+
import {
|
|
11
|
+
StaticHandlerContext,
|
|
12
|
+
StaticRouterProvider,
|
|
13
|
+
} from "react-router-dom/server.js";
|
|
14
|
+
import { Router } from "@remix-run/router";
|
|
15
|
+
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
import config from "./../../../../rasengan.config.js";
|
|
18
|
+
import { ErrorBoundary } from "../core/components";
|
|
19
|
+
|
|
20
|
+
import * as pkg from "react-helmet-async";
|
|
21
|
+
|
|
22
|
+
// @ts-ignore
|
|
23
|
+
const { HelmetProvider } = pkg.default || pkg;
|
|
24
|
+
|
|
25
|
+
export function render(
|
|
26
|
+
router: Router,
|
|
27
|
+
context: StaticHandlerContext,
|
|
28
|
+
helmetContext: any = {}
|
|
29
|
+
) {
|
|
30
|
+
const html = ReactDOMServer.renderToString(
|
|
31
|
+
config.reactStrictMode ? (
|
|
32
|
+
<React.StrictMode>
|
|
33
|
+
<ErrorBoundary>
|
|
34
|
+
<HelmetProvider context={helmetContext}>
|
|
35
|
+
<StaticRouterProvider router={router} context={context} />
|
|
36
|
+
</HelmetProvider>
|
|
37
|
+
</ErrorBoundary>
|
|
38
|
+
</React.StrictMode>
|
|
39
|
+
) : (
|
|
40
|
+
<ErrorBoundary>
|
|
41
|
+
<HelmetProvider context={helmetContext}>
|
|
42
|
+
<StaticRouterProvider router={router} context={context} />
|
|
43
|
+
</HelmetProvider>
|
|
44
|
+
</ErrorBoundary>
|
|
45
|
+
)
|
|
46
|
+
);
|
|
47
|
+
return { html };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const staticRoutes = generateStaticRoutes(AppRouter);
|
|
File without changes
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Imports
|
|
2
|
+
import createFetchRequest from "./server/utils/createFetchRequest.js";
|
|
3
|
+
|
|
4
|
+
// Exports
|
|
5
|
+
export * from "./core/index.js";
|
|
6
|
+
export * from "./routing/index.js";
|
|
7
|
+
export * from "./decorators/index.js";
|
|
8
|
+
export * from "./config/index.js";
|
|
9
|
+
export { createFetchRequest }
|
|
10
|
+
|
|
11
|
+
// export * as hooks from './hooks';
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { Suspense } from "react";
|
|
2
|
+
import { Link, useLoaderData, useRouteError } from "react-router-dom";
|
|
3
|
+
import { PageToRender } from "../../core/components/index.js";
|
|
4
|
+
import { PageComponent } from "../../core/interfaces.js";
|
|
5
|
+
import { LoaderResponse } from "../../core/types.js";
|
|
6
|
+
import { NotFoundComponentContainerProps } from "../types.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Error boundary component that will be displayed if an error occurs during a routing
|
|
10
|
+
* @returns
|
|
11
|
+
*/
|
|
12
|
+
export function ErrorBoundary() {
|
|
13
|
+
let error = useRouteError();
|
|
14
|
+
|
|
15
|
+
console.error(error);
|
|
16
|
+
|
|
17
|
+
return <div>Dang!</div>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Component that will be displayed during a routing on the server side
|
|
22
|
+
* @returns React.ReactNode
|
|
23
|
+
*/
|
|
24
|
+
export const ServerComponent = ({
|
|
25
|
+
page,
|
|
26
|
+
loader,
|
|
27
|
+
}: {
|
|
28
|
+
page: PageComponent;
|
|
29
|
+
loader: React.ReactNode;
|
|
30
|
+
}) => {
|
|
31
|
+
// Default data
|
|
32
|
+
const data = {
|
|
33
|
+
props: {},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<Suspense fallback={loader}>
|
|
38
|
+
<PageToRender page={page} data={data} />
|
|
39
|
+
</Suspense>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Component that will be displayed during a routing on the client side
|
|
45
|
+
* @returns React.ReactNode
|
|
46
|
+
*/
|
|
47
|
+
export const ClientComponent = ({
|
|
48
|
+
page,
|
|
49
|
+
loader,
|
|
50
|
+
}: {
|
|
51
|
+
page: PageComponent;
|
|
52
|
+
loader: React.ReactNode;
|
|
53
|
+
}) => {
|
|
54
|
+
// Default data
|
|
55
|
+
const defaultData = {
|
|
56
|
+
props: {},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const data = (useLoaderData() as LoaderResponse) || defaultData;
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<Suspense fallback={loader}>
|
|
63
|
+
<PageToRender page={page} data={data} />
|
|
64
|
+
</Suspense>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Component that will be displayed when a page is not found
|
|
70
|
+
* @returns React.ReactNode
|
|
71
|
+
*/
|
|
72
|
+
export const NotFoundPageComponent = () => {
|
|
73
|
+
return (
|
|
74
|
+
<section
|
|
75
|
+
style={{
|
|
76
|
+
display: "flex",
|
|
77
|
+
flexDirection: "column",
|
|
78
|
+
justifyContent: "center",
|
|
79
|
+
alignItems: "center",
|
|
80
|
+
height: "100vh",
|
|
81
|
+
width: "100vw",
|
|
82
|
+
}}
|
|
83
|
+
>
|
|
84
|
+
<h1
|
|
85
|
+
style={{
|
|
86
|
+
fontSize: "3rem",
|
|
87
|
+
fontWeight: "bold",
|
|
88
|
+
marginBottom: 10,
|
|
89
|
+
}}
|
|
90
|
+
>
|
|
91
|
+
404 Page Not Found
|
|
92
|
+
</h1>
|
|
93
|
+
|
|
94
|
+
<p
|
|
95
|
+
style={{
|
|
96
|
+
fontSize: "1.2rem",
|
|
97
|
+
marginBottom: 20,
|
|
98
|
+
}}
|
|
99
|
+
>
|
|
100
|
+
The page you are looking for does not exist or has been moved.
|
|
101
|
+
</p>
|
|
102
|
+
|
|
103
|
+
<Link
|
|
104
|
+
to="/"
|
|
105
|
+
style={{
|
|
106
|
+
fontSize: "1.2rem",
|
|
107
|
+
fontWeight: 800,
|
|
108
|
+
marginBottom: 20,
|
|
109
|
+
textDecoration: "none",
|
|
110
|
+
}}
|
|
111
|
+
>
|
|
112
|
+
Go back to home page
|
|
113
|
+
</Link>
|
|
114
|
+
</section>
|
|
115
|
+
);
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Component that will be displayed when a page is not found
|
|
120
|
+
*/
|
|
121
|
+
export const NotFoundComponentContainer = ({
|
|
122
|
+
content,
|
|
123
|
+
}: NotFoundComponentContainerProps) => {
|
|
124
|
+
return <>{content({})}</>;
|
|
125
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export {
|
|
2
|
+
defineRouteLayout,
|
|
3
|
+
defineRoutePage,
|
|
4
|
+
defineRouter,
|
|
5
|
+
} from "./utils/index.js";
|
|
6
|
+
export { RouterComponent } from "./interfaces.js";
|
|
7
|
+
export {
|
|
8
|
+
Outlet,
|
|
9
|
+
Link,
|
|
10
|
+
useLocation,
|
|
11
|
+
useNavigate,
|
|
12
|
+
useParams,
|
|
13
|
+
useSearchParams,
|
|
14
|
+
useFetcher,
|
|
15
|
+
useMatch,
|
|
16
|
+
useRoutes,
|
|
17
|
+
useResolvedPath,
|
|
18
|
+
matchRoutes,
|
|
19
|
+
generatePath,
|
|
20
|
+
matchPath,
|
|
21
|
+
createRoutesFromChildren,
|
|
22
|
+
Navigate,
|
|
23
|
+
} from "react-router-dom";
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { LayoutComponent, PageComponent } from "../core/interfaces.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Router component that define a routing system
|
|
5
|
+
*/
|
|
6
|
+
export class RouterComponent {
|
|
7
|
+
/**
|
|
8
|
+
* Defines the layout applied to the Router
|
|
9
|
+
*/
|
|
10
|
+
private _layout!: LayoutComponent;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Defines the list of sub routers
|
|
14
|
+
*/
|
|
15
|
+
private _routers!: Array<RouterComponent>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Defines the list of pages
|
|
19
|
+
*/
|
|
20
|
+
private _pages!: Array<PageComponent>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Defines the loader component to display when pages aren't available
|
|
24
|
+
*/
|
|
25
|
+
private _loaderComponent!: React.FC;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Defines the not found component to display when pages aren't available
|
|
29
|
+
*/
|
|
30
|
+
private _notFoundComponent!: React.FC;
|
|
31
|
+
|
|
32
|
+
// Getters
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Get the layout value
|
|
36
|
+
*/
|
|
37
|
+
get layout() {
|
|
38
|
+
return this._layout;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get the list of routers
|
|
43
|
+
*/
|
|
44
|
+
get routers() {
|
|
45
|
+
return this._routers;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Get the list of pages
|
|
50
|
+
*/
|
|
51
|
+
get pages() {
|
|
52
|
+
return this._pages;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get the loader component
|
|
57
|
+
*/
|
|
58
|
+
get loaderComponent() {
|
|
59
|
+
return this._loaderComponent;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get the not found component
|
|
64
|
+
*/
|
|
65
|
+
get notFoundComponent() {
|
|
66
|
+
return this._notFoundComponent;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Setters
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Set the layout value
|
|
73
|
+
*/
|
|
74
|
+
set layout(layout: LayoutComponent) {
|
|
75
|
+
this._layout = layout;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Set the list of routers
|
|
80
|
+
*/
|
|
81
|
+
set routers(routers: Array<RouterComponent>) {
|
|
82
|
+
this._routers = routers;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Set the list of pages
|
|
87
|
+
*/
|
|
88
|
+
set pages(pages: Array<PageComponent>) {
|
|
89
|
+
this._pages = pages;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Set the loader component
|
|
94
|
+
*/
|
|
95
|
+
set loaderComponent(loaderComponent: React.FC) {
|
|
96
|
+
this._loaderComponent = loaderComponent;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Set the not found component
|
|
101
|
+
*/
|
|
102
|
+
set notFoundComponent(notFoundComponent: React.FC) {
|
|
103
|
+
this._notFoundComponent = notFoundComponent;
|
|
104
|
+
}
|
|
105
|
+
}
|