@modern-js/types 1.21.3 → 2.0.0-beta.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.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,27 @@
1
1
  # @modern-js/types
2
2
 
3
- ## 1.21.3
3
+ ## 2.0.0-beta.0
4
+
5
+ ### Major Changes
6
+
7
+ - dda38c9: chore: v2
8
+
9
+ ### Patch Changes
10
+
11
+ - cc971eabf: refactor: move server plugin load logic in `@modern-js/core`
12
+ refactor:移除在 `@modern-js/core` 中的 server 插件加载逻辑
13
+ - 6bda14ed7: feat: refactor router with react-router@6.4
14
+
15
+ feat: 使用 react-router@6.4 重构路由模块
16
+
17
+ - 102d32e4b: feat(server): add `req` and `res` to SSR context
18
+
19
+ feat(server): 添加 `req` 和 `res` 到 SSR context 中
20
+
21
+ - 8b8e1bb57: feat: support nested routes
22
+ feat: 支持嵌套路由
23
+ - 3bbea92b2: feat: support Hook、Middleware new API
24
+ feat: 支持 Hook、Middleware 的新 API
4
25
 
5
26
  ## 1.21.2
6
27
 
package/cli/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import type { Merge } from 'type-fest';
2
+ import { InternalPlugins } from '../common';
1
3
  import { ServerRoute } from '../server';
2
4
 
3
5
  /**
@@ -6,6 +8,7 @@ import { ServerRoute } from '../server';
6
8
  export interface Entrypoint {
7
9
  entryName: string;
8
10
  entry: string;
11
+ nestedRoutesEntry?: string;
9
12
  isAutoMount?: boolean;
10
13
  customBootstrap?: string | false;
11
14
  fileSystemRoutes?: {
@@ -17,14 +20,57 @@ export interface Entrypoint {
17
20
  /**
18
21
  * file system routes.
19
22
  */
20
- export interface Route {
23
+ export type RouteLegacy = {
21
24
  path: string;
22
25
  exact: boolean;
23
26
  component: string;
24
27
  _component: string;
25
- routes?: Route[];
26
- parent?: Route;
27
- }
28
+ routes?: RouteLegacy[];
29
+ parent?: RouteLegacy;
30
+ };
31
+
32
+ export type Route = Partial<{
33
+ caseSensitive: boolean;
34
+ path: string;
35
+ id: string;
36
+ loader: any;
37
+ action: any;
38
+ hasErrorBoundary: boolean;
39
+ shouldRevalidate: any;
40
+ handle: any;
41
+ index: boolean;
42
+ children: Route[] | undefined;
43
+ element: React.ReactNode | null;
44
+ errorElement: React.ReactNode | null;
45
+ }> & {
46
+ type: string;
47
+ };
48
+
49
+ export type NestedRoute = Merge<
50
+ Route,
51
+ {
52
+ type: 'nested';
53
+ parentId?: string;
54
+ children?: NestedRoute[];
55
+ childIds?: string[];
56
+ filename?: string;
57
+ _component?: string;
58
+ component?: string;
59
+ loading?: string;
60
+ error?: string;
61
+ }
62
+ >;
63
+
64
+ export type PageRoute = Merge<
65
+ Route,
66
+ {
67
+ type: 'page';
68
+ parent?: PageRoute;
69
+ _component: string;
70
+ component: string;
71
+ children?: PageRoute[];
72
+ }
73
+ >;
28
74
 
29
75
  /**
30
76
  * custom html partials.
@@ -44,6 +90,7 @@ export interface IAppContext {
44
90
  appDirectory: string;
45
91
  configFile: string | false;
46
92
  serverConfigFile: string;
93
+ serverInternalPlugins: InternalPlugins;
47
94
  ip?: string;
48
95
  port?: number;
49
96
  distDirectory: string;
@@ -52,11 +99,7 @@ export interface IAppContext {
52
99
  sharedDirectory: string;
53
100
  nodeModulesDirectory: string;
54
101
  internalDirectory: string;
55
- plugins: {
56
- cli?: any;
57
- server?: any;
58
- serverPkg?: any;
59
- }[];
102
+ plugins: any[];
60
103
  entrypoints: Entrypoint[];
61
104
  checkedEntries: string[];
62
105
  serverRoutes: ServerRoute[];
@@ -65,3 +108,5 @@ export interface IAppContext {
65
108
  internalDirAlias: string;
66
109
  internalSrcAlias: string;
67
110
  }
111
+
112
+ export type { Merge } from 'type-fest';
@@ -0,0 +1,4 @@
1
+ export type InternalPlugins = Record<
2
+ string,
3
+ string | { path: string; forced?: boolean }
4
+ >;
package/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './server';
2
2
  export * from './cli';
3
+ export * from './common';
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "modern",
12
12
  "modern.js"
13
13
  ],
14
- "version": "1.21.3",
14
+ "version": "2.0.0-beta.0",
15
15
  "types": "./index.d.ts",
16
16
  "exports": {
17
17
  ".": "./index.d.ts",
@@ -20,33 +20,32 @@
20
20
  "default": "./server/index.d.ts"
21
21
  }
22
22
  },
23
+ "typesVersions": {
24
+ "*": {
25
+ ".": [
26
+ "./index.d.ts"
27
+ ],
28
+ "hoist-non-react-statics": [
29
+ "./packages/hoist-non-react-statics.d.ts"
30
+ ]
31
+ }
32
+ },
23
33
  "devDependencies": {
24
- "@scripts/build": "1.21.3",
25
- "@scripts/jest-config": "1.21.3",
34
+ "@scripts/build": "2.0.0-beta.0",
35
+ "@scripts/jest-config": "2.0.0-beta.0",
26
36
  "@types/jest": "^27",
27
37
  "@types/node": "^14",
28
38
  "http-proxy-middleware": "^2.0.4",
29
- "jest": "^27"
39
+ "jest": "^27",
40
+ "type-fest": "2.15.0"
30
41
  },
31
42
  "sideEffects": false,
32
43
  "publishConfig": {
33
44
  "registry": "https://registry.npmjs.org/",
34
45
  "access": "public"
35
46
  },
36
- "wireit": {
37
- "test": {
38
- "command": "jest --passWithNoTests",
39
- "files": [
40
- "src/**/*",
41
- "tsconfig.json",
42
- "package.json",
43
- "tests/**/*"
44
- ],
45
- "output": []
46
- }
47
- },
48
47
  "scripts": {
49
- "test": "wireit"
48
+ "test": "jest --passWithNoTests"
50
49
  },
51
50
  "main": ""
52
51
  }
@@ -0,0 +1,77 @@
1
+ // eslint-disable-next-line @typescript-eslint/naming-convention
2
+ interface REACT_STATICS {
3
+ childContextTypes: true;
4
+ contextType: true;
5
+ contextTypes: true;
6
+ defaultProps: true;
7
+ displayName: true;
8
+ getDefaultProps: true;
9
+ getDerivedStateFromError: true;
10
+ getDerivedStateFromProps: true;
11
+ mixins: true;
12
+ propTypes: true;
13
+ type: true;
14
+ }
15
+
16
+ // eslint-disable-next-line @typescript-eslint/naming-convention
17
+ interface KNOWN_STATICS {
18
+ name: true;
19
+ length: true;
20
+ prototype: true;
21
+ caller: true;
22
+ callee: true;
23
+ arguments: true;
24
+ arity: true;
25
+ }
26
+
27
+ // eslint-disable-next-line @typescript-eslint/naming-convention
28
+ interface MEMO_STATICS {
29
+ $$typeof: true;
30
+ compare: true;
31
+ defaultProps: true;
32
+ displayName: true;
33
+ propTypes: true;
34
+ type: true;
35
+ }
36
+
37
+ // eslint-disable-next-line @typescript-eslint/naming-convention
38
+ interface FORWARD_REF_STATICS {
39
+ $$typeof: true;
40
+ render: true;
41
+ defaultProps: true;
42
+ displayName: true;
43
+ propTypes: true;
44
+ }
45
+ declare namespace hoistNonReactStatics {
46
+ type NonReactStatics<
47
+ S extends React.ComponentType<any>,
48
+ C extends {
49
+ [key: string]: true;
50
+ // eslint-disable-next-line @typescript-eslint/ban-types
51
+ } = {},
52
+ > = {
53
+ [key in Exclude<
54
+ keyof S,
55
+ S extends React.MemoExoticComponent<any>
56
+ ? keyof MEMO_STATICS | keyof C
57
+ : S extends React.ForwardRefExoticComponent<any>
58
+ ? keyof FORWARD_REF_STATICS | keyof C
59
+ : keyof REACT_STATICS | keyof KNOWN_STATICS | keyof C
60
+ >]: S[key];
61
+ };
62
+ }
63
+ declare module 'hoist-non-react-statics' {
64
+ declare function hoistNonReactStatics<
65
+ T extends React.ComponentType<any>,
66
+ S extends React.ComponentType<any>,
67
+ C extends {
68
+ [key: string]: true;
69
+ // eslint-disable-next-line @typescript-eslint/ban-types
70
+ } = {},
71
+ >(
72
+ TargetComponent: T,
73
+ SourceComponent: S,
74
+ customStatic?: C,
75
+ ): T & hoistNonReactStatics.NonReactStatics<S, C>;
76
+ export default hoistNonReactStatics;
77
+ }
@@ -6,7 +6,7 @@ import { Metrics, Logger } from './utils';
6
6
  export interface ModernServerContext {
7
7
  req: IncomingMessage;
8
8
 
9
- res: ServerResponse;
9
+ res: ServerResponse & { locals?: Record<string, any> };
10
10
 
11
11
  params: Record<string, string>;
12
12
 
@@ -64,6 +64,7 @@ export type BaseSSRServerContext = {
64
64
  response: {
65
65
  setHeader: (key: string, value: string) => void;
66
66
  status: (code: number) => void;
67
+ locals: Record<string, any>;
67
68
  };
68
69
  redirection: { url?: string; status?: number };
69
70
  loadableStats: Record<string, any>;
@@ -87,8 +88,11 @@ export type BaseSSRServerContext = {
87
88
  ) => void;
88
89
  };
89
90
  cacheConfig?: any;
90
- };
91
91
 
92
+ req: ModernServerContext['req'];
93
+
94
+ res: ModernServerContext['res'];
95
+ };
92
96
  export interface ISAppContext {
93
97
  appDirectory: string;
94
98
  distDirectory: string;
package/server/hook.d.ts CHANGED
@@ -1,35 +1,66 @@
1
1
  import { IncomingMessage, ServerResponse } from 'http';
2
- import { ServerRoute as Route } from './route';
3
- import { NextFunction } from './utils';
4
- import { ModernServerContext } from './context';
5
2
 
6
- type Middleware = (
7
- req: IncomingMessage,
8
- res: ServerResponse,
9
- next: NextFunction,
10
- ) => Promise<void>;
3
+ export type CookieAPI = {
4
+ get: (key: string) => string;
5
+ set: (key: string, value: string) => void;
6
+ delete: (key: string) => void;
7
+ clear: () => void;
8
+ apply: () => void;
9
+ };
10
+
11
+ export interface ModernResponse {
12
+ get: (key: string) => string | number | string[] | undefined;
13
+ set: (key: string, value: string) => void;
14
+ status: (code: number) => void;
15
+ cookies: CookieAPI;
16
+ raw: (
17
+ body: string,
18
+ { status, headers }: { status: number; headers: Record<string, any> },
19
+ ) => void;
20
+ }
21
+
22
+ export interface ModernRequest {
23
+ host: string;
24
+ pathname: string;
25
+ query: Record<string, any>;
26
+ cookie: string;
27
+ cookies: Pick<CookieAPI, 'get'>;
28
+ headers: IncomingHttpHeaders;
29
+ }
30
+
31
+ export type HookContext = {
32
+ response: ModernResponse;
33
+ request: ModernRequest;
34
+ logger: Logger;
35
+ metrics?: Metrics;
36
+ };
11
37
 
12
- export type TemplateAPI = {
13
- get: () => Promise<string>;
14
- set: (html: string) => void;
15
- prependBody: (frag: string) => TemplateAPI;
16
- prependHead: (frag: string) => TemplateAPI;
17
- appendBody: (frag: string) => TemplateAPI;
18
- appendHead: (frag: string) => TemplateAPI;
19
- replace: (tag: string, frag: string) => TemplateAPI;
38
+ export type AfterMatchContext = HookContext & {
39
+ router: {
40
+ readonly current: string;
41
+ readonly url: string;
42
+ readonly status: number;
43
+ redirect: (url: string, status: number) => void;
44
+ rewrite: (entry: string) => void;
45
+ use: (entry: string) => void;
46
+ };
20
47
  };
21
48
 
22
- export type RouteAPI = {
23
- cur: () => Route;
24
- get: (entryName: string) => Route | undefined;
25
- use: (entryName: string) => boolean;
49
+ export type AfterRenderContext = HookContext & {
50
+ template: {
51
+ set: (content: string) => void;
52
+ get: () => string;
53
+ prependHead: (fragment: string) => void;
54
+ appendHead: (fragment: string) => void;
55
+ prependBody: (fragment: string) => void;
56
+ appendBody: (fragment: string) => void;
57
+ };
26
58
  };
27
59
 
28
- type HookHandler<Context> = (ctx: Context, next: NextFunction) => Promise<void>;
29
- type Hook<Context> = (fn: HookHandler<Context>) => void;
30
- export type ModernServerHook = {
31
- beforeMatch: Hook<ModernServerContext>;
32
- afterMatch: Hook<ModernServerContext & { router: RouteAPI }>;
33
- beforeRender: Hook<ModernServerContext>;
34
- afterRender: Hook<ModernServerContext & { template: TemplateAPI }>;
60
+ export type MiddlewareContext = HookContext & {
61
+ response: ModernResponse & { locals: Record<string, any> };
62
+ source: {
63
+ req: IncomingMessage;
64
+ res: ServerResponse;
65
+ };
35
66
  };