@modern-js/bff-core 1.0.1-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.
Files changed (43) hide show
  1. package/CHANGELOG.md +224 -0
  2. package/LICENSE +21 -0
  3. package/README.md +30 -0
  4. package/dist/js/modern/api.js +59 -0
  5. package/dist/js/modern/client/generate-client.js +64 -0
  6. package/dist/js/modern/client/index.js +1 -0
  7. package/dist/js/modern/client/result.js +20 -0
  8. package/dist/js/modern/errors/http.js +13 -0
  9. package/dist/js/modern/index.js +7 -0
  10. package/dist/js/modern/operators/http.js +183 -0
  11. package/dist/js/modern/router/constants.js +13 -0
  12. package/dist/js/modern/router/index.js +271 -0
  13. package/dist/js/modern/router/types.js +1 -0
  14. package/dist/js/modern/router/utils.js +53 -0
  15. package/dist/js/modern/types.js +42 -0
  16. package/dist/js/modern/utils.js +61 -0
  17. package/dist/js/node/api.js +71 -0
  18. package/dist/js/node/client/generate-client.js +82 -0
  19. package/dist/js/node/client/index.js +18 -0
  20. package/dist/js/node/client/result.js +32 -0
  21. package/dist/js/node/errors/http.js +25 -0
  22. package/dist/js/node/index.js +102 -0
  23. package/dist/js/node/operators/http.js +227 -0
  24. package/dist/js/node/router/constants.js +27 -0
  25. package/dist/js/node/router/index.js +317 -0
  26. package/dist/js/node/router/types.js +5 -0
  27. package/dist/js/node/router/utils.js +74 -0
  28. package/dist/js/node/types.js +53 -0
  29. package/dist/js/node/utils.js +85 -0
  30. package/dist/types/api.d.ts +3 -0
  31. package/dist/types/client/generate-client.d.ts +24 -0
  32. package/dist/types/client/index.d.ts +1 -0
  33. package/dist/types/client/result.d.ts +15 -0
  34. package/dist/types/errors/http.d.ts +5 -0
  35. package/dist/types/index.d.ts +7 -0
  36. package/dist/types/operators/http.d.ts +28 -0
  37. package/dist/types/router/constants.d.ts +16 -0
  38. package/dist/types/router/index.d.ts +46 -0
  39. package/dist/types/router/types.d.ts +17 -0
  40. package/dist/types/router/utils.d.ts +7 -0
  41. package/dist/types/types.d.ts +54 -0
  42. package/dist/types/utils.d.ts +7 -0
  43. package/package.json +89 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,224 @@
1
+ # @modern-js/adapter-helpers
2
+
3
+ ## 1.2.4
4
+
5
+ ### Patch Changes
6
+
7
+ - d32f35134: chore: add modern/jest/eslint/ts config files to .npmignore
8
+
9
+ ## 1.2.3
10
+
11
+ ### Patch Changes
12
+
13
+ - 6cffe99d: chore:
14
+ remove react eslint rules for `modern-js` rule set.
15
+ add .eslintrc for each package to speed up linting
16
+ - 60f7d8bf: feat: add tests dir to npmignore
17
+ - befd9e5b: fix: compatible with babel-plugin-resolver's handling of relative paths on windows
18
+ - 3bf4f8b0: feat: support start api server only
19
+
20
+ ## 1.2.2
21
+
22
+ ### Patch Changes
23
+
24
+ - 55e18278: chore: remove unused dependencies and devDependencies
25
+
26
+ ## 1.2.1
27
+
28
+ ### Patch Changes
29
+
30
+ - 83166714: change .npmignore
31
+
32
+ ## 1.2.0
33
+
34
+ ### Minor Changes
35
+
36
+ - cfe11628: Make Modern.js self bootstraping
37
+
38
+ ## 1.1.1
39
+
40
+ ### Patch Changes
41
+
42
+ - 0fa83663: support more .env files
43
+
44
+ ## 1.1.0
45
+
46
+ ### Minor Changes
47
+
48
+ - 96119db2: Relese v1.1.0
49
+
50
+ ## 1.0.0
51
+
52
+ ### Patch Changes
53
+
54
+ - 224f7fe: fix server route match
55
+ - 30ac27c: feat: add generator package description
56
+ - 0fd196e: feat: fix bugs
57
+ - 204c626: feat: initial
58
+ - 63be0a5: fix: #118 #104
59
+
60
+ ## 1.0.0-rc.23
61
+
62
+ ### Patch Changes
63
+
64
+ - 224f7fe: fix server route match
65
+ - 30ac27c: feat: add generator package description
66
+ - 0fd196e: feat: fix bugs
67
+ - 204c626: feat: initial
68
+ - 63be0a5: fix: #118 #104
69
+
70
+ ## 1.0.0-rc.22
71
+
72
+ ### Patch Changes
73
+
74
+ - 224f7fe: fix server route match
75
+ - 30ac27c: feat: add generator package description
76
+ - 0fd196e: feat: fix bugs
77
+ - 204c626: feat: initial
78
+ - 63be0a5: fix: #118 #104
79
+
80
+ ## 1.0.0-rc.21
81
+
82
+ ### Patch Changes
83
+
84
+ - 224f7fe: fix server route match
85
+ - 30ac27c: feat: add generator package description
86
+ - 0fd196e: feat: fix bugs
87
+ - 204c626: feat: initial
88
+ - 63be0a5: fix: #118 #104
89
+
90
+ ## 1.0.0-rc.20
91
+
92
+ ### Patch Changes
93
+
94
+ - 224f7fe: fix server route match
95
+ - 30ac27c: feat: add generator package description
96
+ - feat: fix bugs
97
+ - 204c626: feat: initial
98
+ - 63be0a5: fix: #118 #104
99
+
100
+ ## 1.0.0-rc.19
101
+
102
+ ### Patch Changes
103
+
104
+ - 224f7fe: fix server route match
105
+ - 30ac27c: feat: add generator package description
106
+ - 204c626: feat: initial
107
+ - 63be0a5: fix: #118 #104
108
+
109
+ ## 1.0.0-rc.18
110
+
111
+ ### Patch Changes
112
+
113
+ - 224f7fe: fix server route match
114
+ - 30ac27c: feat: add generator package description
115
+ - 204c626: feat: initial
116
+ - 63be0a5: fix: #118 #104
117
+
118
+ ## 1.0.0-rc.17
119
+
120
+ ### Patch Changes
121
+
122
+ - 224f7fe: fix server route match
123
+ - 30ac27c: feat: add generator package description
124
+ - 204c626: feat: initial
125
+ - fix: #118 #104
126
+
127
+ ## 1.0.0-rc.16
128
+
129
+ ### Patch Changes
130
+
131
+ - 224f7fe: fix server route match
132
+ - 30ac27c: feat: add generator package description
133
+ - 204c626: feat: initial
134
+
135
+ ## 1.0.0-rc.15
136
+
137
+ ### Patch Changes
138
+
139
+ - 224f7fe: fix server route match
140
+ - 30ac27c: feat: add generator package description
141
+ - 204c626: feat: initial
142
+
143
+ ## 1.0.0-rc.14
144
+
145
+ ### Patch Changes
146
+
147
+ - 224f7fe: fix server route match
148
+ - 204c626: feat: initial
149
+
150
+ ## 1.0.0-rc.13
151
+
152
+ ### Patch Changes
153
+
154
+ - 224f7fe: fix server route match
155
+ - 204c626: feat: initial
156
+
157
+ ## 1.0.0-rc.12
158
+
159
+ ### Patch Changes
160
+
161
+ - 224f7fe: fix server route match
162
+ - 204c626: feat: initial
163
+
164
+ ## 1.0.0-rc.11
165
+
166
+ ### Patch Changes
167
+
168
+ - 224f7fe: fix server route match
169
+ - 204c626: feat: initial
170
+
171
+ ## 1.0.0-rc.10
172
+
173
+ ### Patch Changes
174
+
175
+ - 224f7fe: fix server route match
176
+ - 204c626: feat: initial
177
+
178
+ ## 1.0.0-rc.9
179
+
180
+ ### Patch Changes
181
+
182
+ - 224f7fe: fix server route match
183
+ - 204c626: feat: initial
184
+
185
+ ## 1.0.0-rc.8
186
+
187
+ ### Patch Changes
188
+
189
+ - 224f7fe: fix server route match
190
+ - 204c626: feat: initial
191
+
192
+ ## 1.0.0-rc.7
193
+
194
+ ### Patch Changes
195
+
196
+ - 224f7fe: fix server route match
197
+ - 204c626: feat: initial
198
+
199
+ ## 1.0.0-rc.6
200
+
201
+ ### Patch Changes
202
+
203
+ - 224f7fe: fix server route match
204
+ - 204c626: feat: initial
205
+
206
+ ## 1.0.0-rc.5
207
+
208
+ ### Patch Changes
209
+
210
+ - 224f7fe: fix server route match
211
+ - 204c626: feat: initial
212
+
213
+ ## 1.0.0-rc.4
214
+
215
+ ### Patch Changes
216
+
217
+ - fix server route match
218
+ - 204c626: feat: initial
219
+
220
+ ## 1.0.0-rc.3
221
+
222
+ ### Patch Changes
223
+
224
+ - feat: initial
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Modern.js
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,30 @@
1
+
2
+ <p align="center">
3
+ <a href="https://modernjs.dev" target="blank"><img src="https://lf3-static.bytednsdoc.com/obj/eden-cn/ylaelkeh7nuhfnuhf/modernjs-cover.png" width="300" alt="Modern.js Logo" /></a>
4
+ </p>
5
+ <p align="center">
6
+ 现代 Web 工程体系
7
+ <br/>
8
+ <a href="https://modernjs.dev" target="blank">
9
+ modernjs.dev
10
+ </a>
11
+ </p>
12
+ <p align="center">
13
+ The meta-framework suite designed from scratch for frontend-focused modern web development
14
+ </p>
15
+
16
+ # Introduction
17
+
18
+ > The doc site ([modernjs.dev](https://modernjs.dev)) and articles are only available in Chinese for now, we are planning to add English versions soon.
19
+
20
+ - [Modern.js: Hello, World!](https://zhuanlan.zhihu.com/p/426707646)
21
+
22
+ ## Getting Started
23
+
24
+ - [Quick Start](https://modernjs.dev/docs/start)
25
+ - [Guides](https://modernjs.dev/docs/guides)
26
+ - [API References](https://modernjs.dev/docs/apis)
27
+
28
+ ## Contributing
29
+
30
+ - [Contributing Guide](https://github.com/modern-js-dev/modern.js/blob/main/CONTRIBUTING.md)
@@ -0,0 +1,59 @@
1
+ import 'reflect-metadata';
2
+ import compose from 'koa-compose';
3
+ import { validateFunction, HANDLER_WITH_META } from "./utils";
4
+ export function Api(...args) {
5
+ const handler = args.pop();
6
+ validateFunction(handler, 'Apihandler');
7
+ const operators = args;
8
+ const metadataHelper = {
9
+ getMetadata(key) {
10
+ return Reflect.getMetadata(key, runner);
11
+ },
12
+
13
+ setMetadata(key, value) {
14
+ return Reflect.defineMetadata(key, value, runner);
15
+ }
16
+
17
+ };
18
+
19
+ for (const operator of operators) {
20
+ if (operator.metadata) {
21
+ operator.metadata(metadataHelper);
22
+ }
23
+ }
24
+
25
+ const validateHandlers = operators.filter(operator => operator.validate).map(operator => operator.validate);
26
+
27
+ async function runner(inputs) {
28
+ // 错误组合传给用户哪些信息?
29
+ // 取出来所有的 schema,然后做校验
30
+ // 包裹中间件,怎么根据不同框架去包裹?
31
+ // 需要满足的需求,可以关闭某一样 schema 的校验
32
+ // 可以关闭某一个字段的校验
33
+ // 可以设置校验函数以替换 zod ?类型怎么搞?
34
+ // 全局可配置校验函数
35
+ // middleware 多框架实现要支持在路由上配,但这样 middleware 就要在校验之前先执行了
36
+ // 简易模式适配怎么处理?
37
+ // 不同框架适配,响应怎么处理?都传入 co ntext 给这个函数?
38
+ // 如何不依赖 zod 库?支持用户自定义 schema 库? Query,Data 实现可以统一代码,类型好像无解,除非这些函数是创建出来的,保证只有 http 中依赖 zod 吧
39
+ const executeHelper = {
40
+ result: null,
41
+
42
+ get inputs() {
43
+ return inputs;
44
+ }
45
+
46
+ };
47
+ const stack = [...validateHandlers];
48
+ stack.push(async (helper, next) => {
49
+ const res = await handler(inputs);
50
+ helper.result = res;
51
+ return next();
52
+ });
53
+ await compose(stack)(executeHelper);
54
+ return executeHelper.result;
55
+ }
56
+
57
+ runner[HANDLER_WITH_META] = true;
58
+ return runner;
59
+ }
@@ -0,0 +1,64 @@
1
+ import * as path from 'path';
2
+ import { ApiRouter } from "../router";
3
+ import { Ok, Err } from "./result";
4
+ export const DEFAULT_CLIENT_REQUEST_CREATOR = '@modern-js/create-request';
5
+ export const generateClient = async ({
6
+ resourcePath,
7
+ apiDir,
8
+ prefix,
9
+ port,
10
+ target,
11
+ requestCreator,
12
+ fetcher,
13
+ requireResolve: _requireResolve = require.resolve
14
+ }) => {
15
+ if (!requestCreator) {
16
+ // eslint-disable-next-line no-param-reassign
17
+ requestCreator = _requireResolve(`${DEFAULT_CLIENT_REQUEST_CREATOR}${target ? `/${target}` : ''}`).replace(/\\/g, '/');
18
+ } else {
19
+ // 这里约束传入的 requestCreator 包也必须有两个导出 client 和 server,因为目前的机制 client 和 server 要导出不同的 configure 函数;该 api 不对使用者暴露,后续可优化
20
+ let resolvedPath = requestCreator;
21
+
22
+ try {
23
+ resolvedPath = path.dirname(_requireResolve(requestCreator));
24
+ } catch (error) {} // eslint-disable-next-line no-param-reassign
25
+
26
+
27
+ requestCreator = `${resolvedPath}${target ? `/${target}` : ''}`.replace(/\\/g, '/');
28
+ }
29
+
30
+ const apiRouter = new ApiRouter({
31
+ apiDir,
32
+ prefix,
33
+ lambdaDir: apiDir
34
+ });
35
+ const handlerInfos = apiRouter.getSingleModuleHandlers(resourcePath);
36
+
37
+ if (!handlerInfos) {
38
+ return Err(`Cannot require module ${resourcePath}`);
39
+ }
40
+
41
+ let handlersCode = '';
42
+
43
+ for (const handlerInfo of handlerInfos) {
44
+ const {
45
+ name,
46
+ httpMethod,
47
+ routePath
48
+ } = handlerInfo;
49
+ let exportStatement = `const ${name} =`;
50
+
51
+ if (name.toLowerCase() === 'default') {
52
+ exportStatement = 'default';
53
+ }
54
+
55
+ const upperHttpMethod = httpMethod.toUpperCase();
56
+ const routeName = routePath;
57
+ handlersCode += `export ${exportStatement} createRequest('${routeName}', '${upperHttpMethod}', process.env.PORT || ${String(port)}${fetcher ? `, fetch` : ''});
58
+ `;
59
+ }
60
+
61
+ const importCode = `import { createRequest } from '${requestCreator}';
62
+ ${fetcher ? `import { fetch } from '${fetcher}';\n` : ''}`;
63
+ return Ok(`${importCode}\n${handlersCode}`);
64
+ };
@@ -0,0 +1 @@
1
+ export * from "./generate-client";
@@ -0,0 +1,20 @@
1
+ // eslint-disable-next-line @typescript-eslint/no-redeclare
2
+ export const Err = value => {
3
+ const err = {
4
+ kind: 'Err',
5
+ value,
6
+ isErr: true,
7
+ isOk: false
8
+ };
9
+ return err;
10
+ }; // eslint-disable-next-line @typescript-eslint/no-redeclare
11
+
12
+ export const Ok = value => {
13
+ const ok = {
14
+ kind: 'Ok',
15
+ value,
16
+ isErr: false,
17
+ isOk: true
18
+ };
19
+ return ok;
20
+ };
@@ -0,0 +1,13 @@
1
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
+
3
+ export class HttpError extends Error {
4
+ constructor(status, message) {
5
+ super(message);
6
+
7
+ _defineProperty(this, "status", void 0);
8
+
9
+ this.status = status;
10
+ }
11
+
12
+ }
13
+ export class ValidationError extends HttpError {}
@@ -0,0 +1,7 @@
1
+ export { Api } from "./api";
2
+ export { HttpError, ValidationError } from "./errors/http";
3
+ export * from "./router";
4
+ export * from "./types";
5
+ export * from "./utils";
6
+ export * from "./client";
7
+ export * from "./operators/http";
@@ -0,0 +1,183 @@
1
+ import { z } from 'zod';
2
+ import { HttpMetadata, OperatorType, HttpMethod, TriggerType } from "../types";
3
+ import { ValidationError } from "../errors/http";
4
+
5
+ const validateInput = async (schema, input) => {
6
+ try {
7
+ await schema.parseAsync(input);
8
+ } catch (error) {
9
+ if (error instanceof z.ZodError) {
10
+ throw new ValidationError(400, error.message);
11
+ }
12
+
13
+ throw error;
14
+ }
15
+ };
16
+
17
+ export const createHttpOperator = method => {
18
+ return urlPath => {
19
+ return {
20
+ name: method,
21
+
22
+ metadata({
23
+ setMetadata
24
+ }) {
25
+ setMetadata(OperatorType.Trigger, {
26
+ type: TriggerType.Http,
27
+ path: urlPath,
28
+ method
29
+ });
30
+ }
31
+
32
+ };
33
+ };
34
+ };
35
+ export const Get = createHttpOperator(HttpMethod.Get);
36
+ export const Post = createHttpOperator(HttpMethod.Post);
37
+ export const Put = createHttpOperator(HttpMethod.Put);
38
+ export const Delete = createHttpOperator(HttpMethod.Delete);
39
+ export const Connect = createHttpOperator(HttpMethod.Connect);
40
+ export const Trace = createHttpOperator(HttpMethod.Trace);
41
+ export const Patch = createHttpOperator(HttpMethod.Patch);
42
+ export const Option = createHttpOperator(HttpMethod.Option);
43
+ export const Head = createHttpOperator(HttpMethod.Head);
44
+ export const Data = schema => {
45
+ return {
46
+ name: HttpMetadata.Data,
47
+
48
+ metadata({
49
+ setMetadata
50
+ }) {
51
+ setMetadata(HttpMetadata.Data, schema);
52
+ },
53
+
54
+ async validate(helper, next) {
55
+ const {
56
+ inputs
57
+ } = helper;
58
+ const {
59
+ data
60
+ } = inputs;
61
+ await validateInput(schema, data);
62
+ return next();
63
+ }
64
+
65
+ };
66
+ };
67
+ export const Query = schema => {
68
+ return {
69
+ name: HttpMetadata.Query,
70
+
71
+ metadata({
72
+ setMetadata
73
+ }) {
74
+ setMetadata(HttpMetadata.Query, schema);
75
+ },
76
+
77
+ async validate(helper, next) {
78
+ const {
79
+ inputs
80
+ } = helper;
81
+ const {
82
+ query
83
+ } = inputs;
84
+ await validateInput(schema, query);
85
+ return next();
86
+ }
87
+
88
+ };
89
+ };
90
+ export const Params = schema => {
91
+ return {
92
+ name: HttpMetadata.Params,
93
+
94
+ metadata({
95
+ setMetadata
96
+ }) {
97
+ setMetadata(HttpMetadata.Params, schema);
98
+ },
99
+
100
+ async validate(helper, next) {
101
+ const {
102
+ inputs
103
+ } = helper;
104
+ const {
105
+ params
106
+ } = inputs;
107
+ await validateInput(schema, params);
108
+ return next();
109
+ }
110
+
111
+ };
112
+ };
113
+ export const Headers = schema => {
114
+ return {
115
+ name: HttpMetadata.Headers,
116
+
117
+ metadata({
118
+ setMetadata
119
+ }) {
120
+ setMetadata(HttpMetadata.Headers, schema);
121
+ },
122
+
123
+ async validate(helper, next) {
124
+ const {
125
+ inputs
126
+ } = helper;
127
+ const {
128
+ headers
129
+ } = inputs;
130
+ await validateInput(schema, headers);
131
+ return next();
132
+ }
133
+
134
+ };
135
+ };
136
+ export const HttpCode = statusCode => {
137
+ return {
138
+ name: 'HttpCode',
139
+
140
+ metadata({
141
+ setMetadata
142
+ }) {
143
+ setMetadata(HttpMetadata.StatusCode, statusCode);
144
+ }
145
+
146
+ };
147
+ };
148
+ export const SetHeaders = headers => {
149
+ return {
150
+ name: 'SetHeaders',
151
+
152
+ metadata({
153
+ setMetadata
154
+ }) {
155
+ setMetadata(HttpMetadata.ResponseHeaders, headers);
156
+ }
157
+
158
+ };
159
+ };
160
+ export const Redirect = url => {
161
+ return {
162
+ name: 'Redirect',
163
+
164
+ metadata({
165
+ setMetadata
166
+ }) {
167
+ setMetadata(HttpMetadata.Redirect, url);
168
+ }
169
+
170
+ };
171
+ };
172
+ export const Middleware = middleware => {
173
+ return {
174
+ name: 'Middleware',
175
+
176
+ metadata({
177
+ setMetadata
178
+ }) {
179
+ setMetadata(OperatorType.Middleware, middleware);
180
+ }
181
+
182
+ };
183
+ };
@@ -0,0 +1,13 @@
1
+ import { HttpMethod } from "../types";
2
+ export const AllHttpMethods = Object.values(HttpMethod);
3
+ export let APIMode;
4
+
5
+ (function (APIMode) {
6
+ APIMode["FARMEWORK"] = "FARMEWORK";
7
+ APIMode["FUNCTION"] = "FUNCTION";
8
+ })(APIMode || (APIMode = {}));
9
+
10
+ export const FRAMEWORK_MODE_LAMBDA_DIR = 'lambda';
11
+ export const INDEX_SUFFIX = 'index';
12
+ export const API_DIR = 'api';
13
+ export const API_FILE_RULES = ['**/*.[tj]s', '!**/_*', '!**/_*/**/*.[tj]s', '!**/*.test.js', '!**/*.test.ts', '!**/*.d.ts', '!__test__/*.ts', '!__tests__/*.ts', '!node_modules/**', '!bootstrap.js'];