@modern-js/bff-core 1.21.2-beta.1 → 1.21.2-beta.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/js/modern/api.js +54 -0
- package/dist/js/modern/client/generate-client.js +63 -0
- package/dist/js/modern/client/index.js +1 -0
- package/dist/js/modern/client/result.js +20 -0
- package/dist/js/modern/errors/http.js +22 -0
- package/dist/js/modern/index.js +7 -0
- package/dist/js/modern/operators/http.js +187 -0
- package/dist/js/modern/router/constants.js +14 -0
- package/dist/js/modern/router/index.js +299 -0
- package/dist/js/modern/router/types.js +1 -0
- package/dist/js/modern/router/utils.js +101 -0
- package/dist/js/modern/types.js +47 -0
- package/dist/js/modern/utils/alias.js +91 -0
- package/dist/js/modern/utils/debug.js +2 -0
- package/dist/js/modern/utils/index.js +5 -0
- package/dist/js/modern/utils/meta.js +4 -0
- package/dist/js/modern/utils/storage.js +48 -0
- package/dist/js/modern/utils/validate.js +49 -0
- package/dist/js/node/api.js +66 -0
- package/dist/js/node/client/generate-client.js +81 -0
- package/dist/js/node/client/index.js +18 -0
- package/dist/js/node/client/result.js +32 -0
- package/dist/js/node/errors/http.js +34 -0
- package/dist/js/node/index.js +125 -0
- package/dist/js/node/operators/http.js +226 -0
- package/dist/js/node/router/constants.js +29 -0
- package/dist/js/node/router/index.js +345 -0
- package/dist/js/node/router/types.js +5 -0
- package/dist/js/node/router/utils.js +123 -0
- package/dist/js/node/types.js +59 -0
- package/dist/js/node/utils/alias.js +115 -0
- package/dist/js/node/utils/debug.js +11 -0
- package/dist/js/node/utils/index.js +72 -0
- package/dist/js/node/utils/meta.js +14 -0
- package/dist/js/node/utils/storage.js +59 -0
- package/dist/js/node/utils/validate.js +68 -0
- package/dist/types/api.d.ts +3 -0
- package/dist/types/client/generate-client.d.ts +24 -0
- package/dist/types/client/index.d.ts +1 -0
- package/dist/types/client/result.d.ts +15 -0
- package/dist/types/errors/http.d.ts +8 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/operators/http.d.ts +39 -0
- package/dist/types/router/constants.d.ts +17 -0
- package/dist/types/router/index.d.ts +51 -0
- package/dist/types/router/types.d.ts +17 -0
- package/dist/types/router/utils.d.ts +10 -0
- package/dist/types/types.d.ts +58 -0
- package/dist/types/utils/alias.d.ts +7 -0
- package/dist/types/utils/debug.d.ts +1 -0
- package/dist/types/utils/index.d.ts +5 -0
- package/dist/types/utils/meta.d.ts +2 -0
- package/dist/types/utils/storage.d.ts +5 -0
- package/dist/types/utils/validate.d.ts +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { globby } from '@modern-js/utils';
|
|
3
|
+
import { INDEX_SUFFIX } from "./constants";
|
|
4
|
+
export const getFiles = (lambdaDir, rules) => globby.sync(rules, {
|
|
5
|
+
cwd: lambdaDir,
|
|
6
|
+
gitignore: true
|
|
7
|
+
}).map(file => path.resolve(lambdaDir, file));
|
|
8
|
+
export const getPathFromFilename = (baseDir, filename) => {
|
|
9
|
+
const relativeName = filename.substring(baseDir.length);
|
|
10
|
+
const relativePath = relativeName.split('.').slice(0, -1).join('.');
|
|
11
|
+
const nameSplit = relativePath.split(path.sep).map(item => {
|
|
12
|
+
if (item.length > 2) {
|
|
13
|
+
if (item.startsWith('[') && item.endsWith(']')) {
|
|
14
|
+
return `:${item.substring(1, item.length - 1)}`;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return item;
|
|
19
|
+
});
|
|
20
|
+
const name = nameSplit.join('/');
|
|
21
|
+
const finalName = name.endsWith(INDEX_SUFFIX) ? name.substring(0, name.length - INDEX_SUFFIX.length) : name;
|
|
22
|
+
return clearRouteName(finalName);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const clearRouteName = routeName => {
|
|
26
|
+
let finalRouteName = routeName.trim();
|
|
27
|
+
|
|
28
|
+
if (!finalRouteName.startsWith('/')) {
|
|
29
|
+
finalRouteName = `/${finalRouteName}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (finalRouteName.length > 1 && finalRouteName.endsWith('/')) {
|
|
33
|
+
finalRouteName = finalRouteName.substring(0, finalRouteName.length - 1);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return finalRouteName;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const isHandler = input => input && typeof input === 'function';
|
|
40
|
+
|
|
41
|
+
const enableRegister = requireFn => {
|
|
42
|
+
// esbuild-register 做 unRegister 时,不会删除 register 添加的 require.extensions,导致第二次调用时 require.extensions['.ts'] 是 nodejs 默认 loader
|
|
43
|
+
// 所以这里根据第一次调用时,require.extensions 有没有,来判断是否需要使用 esbuild-register
|
|
44
|
+
let existTsLoader = false;
|
|
45
|
+
let firstCall = true;
|
|
46
|
+
return modulePath => {
|
|
47
|
+
if (firstCall) {
|
|
48
|
+
// eslint-disable-next-line node/no-deprecated-api
|
|
49
|
+
existTsLoader = Boolean(require.extensions['.ts']);
|
|
50
|
+
firstCall = false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!existTsLoader) {
|
|
54
|
+
const {
|
|
55
|
+
register
|
|
56
|
+
} = require('esbuild-register/dist/node');
|
|
57
|
+
|
|
58
|
+
const {
|
|
59
|
+
unregister
|
|
60
|
+
} = register({
|
|
61
|
+
extension: ['.ts', '.js']
|
|
62
|
+
});
|
|
63
|
+
const requiredModule = requireFn(modulePath);
|
|
64
|
+
unregister();
|
|
65
|
+
return requiredModule;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const requiredModule = requireFn(modulePath);
|
|
69
|
+
return requiredModule;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const isFunction = input => input && {}.toString.call(input) === '[object Function]';
|
|
74
|
+
|
|
75
|
+
export const requireHandlerModule = enableRegister(modulePath => {
|
|
76
|
+
// 测试环境不走缓存,因为缓存的 h andler 文件,会被 mockAPI 函数进行 mock,升级 jest28,setupFilesAfterEnv 能做异步操作的话,可解此问题
|
|
77
|
+
const originRequire = process.env.NODE_ENV === 'test' ? jest.requireActual : require;
|
|
78
|
+
const module = originRequire(modulePath);
|
|
79
|
+
|
|
80
|
+
if (isFunction(module)) {
|
|
81
|
+
return {
|
|
82
|
+
default: module
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return module;
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const routeValue = routePath => {
|
|
90
|
+
if (routePath.includes(':')) {
|
|
91
|
+
return 11;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return 1;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export const sortRoutes = apiHandlers => {
|
|
98
|
+
return apiHandlers.sort((handlerA, handlerB) => {
|
|
99
|
+
return routeValue(handlerA.routeName) - routeValue(handlerB.routeName);
|
|
100
|
+
});
|
|
101
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export let OperatorType;
|
|
2
|
+
|
|
3
|
+
(function (OperatorType) {
|
|
4
|
+
OperatorType[OperatorType["Trigger"] = 0] = "Trigger";
|
|
5
|
+
OperatorType[OperatorType["Middleware"] = 1] = "Middleware";
|
|
6
|
+
})(OperatorType || (OperatorType = {}));
|
|
7
|
+
|
|
8
|
+
export let TriggerType;
|
|
9
|
+
|
|
10
|
+
(function (TriggerType) {
|
|
11
|
+
TriggerType[TriggerType["Http"] = 0] = "Http";
|
|
12
|
+
})(TriggerType || (TriggerType = {}));
|
|
13
|
+
|
|
14
|
+
export let HttpMetadata;
|
|
15
|
+
|
|
16
|
+
(function (HttpMetadata) {
|
|
17
|
+
HttpMetadata["Method"] = "METHOD";
|
|
18
|
+
HttpMetadata["Data"] = "DATA";
|
|
19
|
+
HttpMetadata["Query"] = "QUERY";
|
|
20
|
+
HttpMetadata["Params"] = "PARAMS";
|
|
21
|
+
HttpMetadata["Headers"] = "HEADERS";
|
|
22
|
+
HttpMetadata["Response"] = "RESPONSE";
|
|
23
|
+
})(HttpMetadata || (HttpMetadata = {}));
|
|
24
|
+
|
|
25
|
+
export let ResponseMetaType;
|
|
26
|
+
|
|
27
|
+
(function (ResponseMetaType) {
|
|
28
|
+
ResponseMetaType[ResponseMetaType["StatusCode"] = 0] = "StatusCode";
|
|
29
|
+
ResponseMetaType[ResponseMetaType["Redirect"] = 1] = "Redirect";
|
|
30
|
+
ResponseMetaType[ResponseMetaType["Headers"] = 2] = "Headers";
|
|
31
|
+
})(ResponseMetaType || (ResponseMetaType = {}));
|
|
32
|
+
|
|
33
|
+
export let HttpMethod;
|
|
34
|
+
|
|
35
|
+
(function (HttpMethod) {
|
|
36
|
+
HttpMethod["Get"] = "GET";
|
|
37
|
+
HttpMethod["Post"] = "POST";
|
|
38
|
+
HttpMethod["Put"] = "PUT";
|
|
39
|
+
HttpMethod["Delete"] = "DELETE";
|
|
40
|
+
HttpMethod["Connect"] = "CONNECT";
|
|
41
|
+
HttpMethod["Trace"] = "TRACE";
|
|
42
|
+
HttpMethod["Patch"] = "PATCH";
|
|
43
|
+
HttpMethod["Option"] = "OPTION";
|
|
44
|
+
HttpMethod["Head"] = "HEAD";
|
|
45
|
+
})(HttpMethod || (HttpMethod = {}));
|
|
46
|
+
|
|
47
|
+
export const httpMethods = Object.values(HttpMethod);
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import * as os from 'os';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import Module from 'module';
|
|
5
|
+
export const getRelativeRuntimePath = (appDirectory, serverRuntimePath) => {
|
|
6
|
+
let relativeRuntimePath = '';
|
|
7
|
+
|
|
8
|
+
if (os.platform() === 'win32') {
|
|
9
|
+
// isRelative function in babel-plugin-resolver plugin can't handle windows relative path correctly, see babel-plugin-resolver's utils.
|
|
10
|
+
relativeRuntimePath = `../${path.relative(appDirectory, serverRuntimePath)}`;
|
|
11
|
+
} else {
|
|
12
|
+
// Look up one level, because the artifacts after build have dist directories
|
|
13
|
+
relativeRuntimePath = path.join('../', path.relative(appDirectory, serverRuntimePath));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
|
|
17
|
+
relativeRuntimePath = `./${path.relative(appDirectory, serverRuntimePath)}`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return relativeRuntimePath;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const sortByLongestPrefix = arr => {
|
|
24
|
+
return arr.concat().sort((a, b) => b.length - a.length);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const createMatchPath = paths => {
|
|
28
|
+
const sortedKeys = sortByLongestPrefix(Object.keys(paths));
|
|
29
|
+
const sortedPaths = {};
|
|
30
|
+
sortedKeys.forEach(key => {
|
|
31
|
+
sortedPaths[key] = paths[key];
|
|
32
|
+
});
|
|
33
|
+
return request => {
|
|
34
|
+
const found = Object.keys(sortedPaths).find(key => {
|
|
35
|
+
return request.startsWith(key);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
if (found) {
|
|
39
|
+
let foundPaths = sortedPaths[found];
|
|
40
|
+
|
|
41
|
+
if (!Array.isArray(foundPaths)) {
|
|
42
|
+
foundPaths = [foundPaths];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
foundPaths = foundPaths.filter(foundPath => path.isAbsolute(foundPath));
|
|
46
|
+
|
|
47
|
+
for (const p of foundPaths) {
|
|
48
|
+
const foundPath = request.replace(found, p);
|
|
49
|
+
|
|
50
|
+
if (fs.existsSync(foundPath)) {
|
|
51
|
+
return foundPath;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return request.replace(found, foundPaths[0]);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return null;
|
|
59
|
+
};
|
|
60
|
+
}; // every path must be a absolute path;
|
|
61
|
+
|
|
62
|
+
export const registerPaths = paths => {
|
|
63
|
+
const originalResolveFilename = Module._resolveFilename; // eslint-disable-next-line node/no-unsupported-features/node-builtins
|
|
64
|
+
|
|
65
|
+
const {
|
|
66
|
+
builtinModules
|
|
67
|
+
} = Module;
|
|
68
|
+
const matchPath = createMatchPath(paths);
|
|
69
|
+
|
|
70
|
+
Module._resolveFilename = function (request, _parent) {
|
|
71
|
+
const isCoreModule = builtinModules.includes(request);
|
|
72
|
+
|
|
73
|
+
if (!isCoreModule) {
|
|
74
|
+
const matched = matchPath(request);
|
|
75
|
+
|
|
76
|
+
if (matched) {
|
|
77
|
+
// eslint-disable-next-line prefer-rest-params
|
|
78
|
+
const modifiedArguments = [matched, ...[].slice.call(arguments, 1)]; // Passes all arguments. Even those that is not specified above.
|
|
79
|
+
|
|
80
|
+
return originalResolveFilename.apply(this, modifiedArguments);
|
|
81
|
+
}
|
|
82
|
+
} // eslint-disable-next-line prefer-rest-params
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
return originalResolveFilename.apply(this, arguments);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
return () => {
|
|
89
|
+
Module._resolveFilename = originalResolveFilename;
|
|
90
|
+
};
|
|
91
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as ah from 'async_hooks';
|
|
2
|
+
|
|
3
|
+
const createStorage = () => {
|
|
4
|
+
let storage;
|
|
5
|
+
|
|
6
|
+
if (typeof ah.AsyncLocalStorage !== 'undefined') {
|
|
7
|
+
storage = new ah.AsyncLocalStorage();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const run = (context, cb) => {
|
|
11
|
+
if (!storage) {
|
|
12
|
+
throw new Error(`Unable to use async_hook, please confirm the node version >= 12.17
|
|
13
|
+
`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
storage.run(context, () => {
|
|
18
|
+
try {
|
|
19
|
+
return resolve(cb());
|
|
20
|
+
} catch (error) {
|
|
21
|
+
return reject(error);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const useContext = () => {
|
|
28
|
+
if (!storage) {
|
|
29
|
+
throw new Error(`Unable to use async_hook, please confirm the node version >= 12.17
|
|
30
|
+
`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const context = storage.getStore();
|
|
34
|
+
|
|
35
|
+
if (!context) {
|
|
36
|
+
throw new Error(`Can't call useContext out of scope, it should be placed in the bff function`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return context;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
run,
|
|
44
|
+
useContext
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export { createStorage };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import util from 'util'; // fork from https://github.com/nodejs/node/blob/master/lib/internal/errors.js
|
|
2
|
+
|
|
3
|
+
export const getTypeErrorMessage = actual => {
|
|
4
|
+
let msg = '';
|
|
5
|
+
|
|
6
|
+
if (actual == null) {
|
|
7
|
+
msg += `. Received ${actual}`;
|
|
8
|
+
} else if (typeof actual === 'function' && actual.name) {
|
|
9
|
+
msg += `. Received function ${actual.name}`;
|
|
10
|
+
} else if (typeof actual === 'object') {
|
|
11
|
+
var _actual$constructor;
|
|
12
|
+
|
|
13
|
+
if ((_actual$constructor = actual.constructor) !== null && _actual$constructor !== void 0 && _actual$constructor.name) {
|
|
14
|
+
msg += `. Received an instance of ${actual.constructor.name}`;
|
|
15
|
+
} else {
|
|
16
|
+
const inspected = util.inspect(actual, {
|
|
17
|
+
depth: -1
|
|
18
|
+
});
|
|
19
|
+
msg += `. Received ${inspected}`;
|
|
20
|
+
}
|
|
21
|
+
} else {
|
|
22
|
+
let inspected = util.inspect(actual, {
|
|
23
|
+
colors: false
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
if (inspected.length > 25) {
|
|
27
|
+
inspected = `${inspected.slice(0, 25)}...`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
msg += `. Received type ${typeof actual} (${inspected})`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return msg;
|
|
34
|
+
}; // eslint-disable-next-line @typescript-eslint/naming-convention
|
|
35
|
+
|
|
36
|
+
export class ERR_INVALID_ARG_TYPE extends Error {
|
|
37
|
+
constructor(funcName, expectedType, actual) {
|
|
38
|
+
const message = `[ERR_INVALID_ARG_TYPE]: The '${funcName}' argument must be of type ${expectedType}${getTypeErrorMessage(actual)}`;
|
|
39
|
+
super(message);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
export const validateFunction = (maybeFunc, name) => {
|
|
44
|
+
if (typeof maybeFunc !== 'function') {
|
|
45
|
+
throw new ERR_INVALID_ARG_TYPE(name, 'function', maybeFunc);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return true;
|
|
49
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Api = Api;
|
|
7
|
+
|
|
8
|
+
require("reflect-metadata");
|
|
9
|
+
|
|
10
|
+
var _koaCompose = _interopRequireDefault(require("koa-compose"));
|
|
11
|
+
|
|
12
|
+
var _utils = require("./utils");
|
|
13
|
+
|
|
14
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
+
|
|
16
|
+
function Api(...args) {
|
|
17
|
+
const handler = args.pop();
|
|
18
|
+
(0, _utils.validateFunction)(handler, 'Apihandler');
|
|
19
|
+
const operators = args;
|
|
20
|
+
const metadataHelper = {
|
|
21
|
+
getMetadata(key) {
|
|
22
|
+
return Reflect.getMetadata(key, runner);
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
setMetadata(key, value) {
|
|
26
|
+
return Reflect.defineMetadata(key, value, runner);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
for (const operator of operators) {
|
|
32
|
+
if (operator.metadata) {
|
|
33
|
+
operator.metadata(metadataHelper);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const validateHandlers = operators.filter(operator => operator.validate).map(operator => operator.validate);
|
|
38
|
+
const pipeHandlers = operators.filter(operator => operator.execute).map(operator => operator.execute);
|
|
39
|
+
|
|
40
|
+
async function runner(inputs) {
|
|
41
|
+
const executeHelper = {
|
|
42
|
+
result: null,
|
|
43
|
+
|
|
44
|
+
get inputs() {
|
|
45
|
+
return inputs;
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
set inputs(val) {
|
|
49
|
+
// eslint-disable-next-line no-param-reassign
|
|
50
|
+
inputs = val;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
};
|
|
54
|
+
const stack = [...validateHandlers, ...pipeHandlers];
|
|
55
|
+
stack.push(async (helper, next) => {
|
|
56
|
+
const res = await handler(helper.inputs);
|
|
57
|
+
helper.result = res;
|
|
58
|
+
return next();
|
|
59
|
+
});
|
|
60
|
+
await (0, _koaCompose.default)(stack)(executeHelper);
|
|
61
|
+
return executeHelper.result;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
runner[_utils.HANDLER_WITH_META] = true;
|
|
65
|
+
return runner;
|
|
66
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.generateClient = exports.DEFAULT_CLIENT_REQUEST_CREATOR = void 0;
|
|
7
|
+
|
|
8
|
+
var path = _interopRequireWildcard(require("path"));
|
|
9
|
+
|
|
10
|
+
var _router = require("../router");
|
|
11
|
+
|
|
12
|
+
var _result = require("./result");
|
|
13
|
+
|
|
14
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
15
|
+
|
|
16
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
17
|
+
|
|
18
|
+
const DEFAULT_CLIENT_REQUEST_CREATOR = '@modern-js/create-request';
|
|
19
|
+
exports.DEFAULT_CLIENT_REQUEST_CREATOR = DEFAULT_CLIENT_REQUEST_CREATOR;
|
|
20
|
+
|
|
21
|
+
const generateClient = async ({
|
|
22
|
+
resourcePath,
|
|
23
|
+
apiDir,
|
|
24
|
+
prefix,
|
|
25
|
+
port,
|
|
26
|
+
target,
|
|
27
|
+
requestCreator,
|
|
28
|
+
fetcher,
|
|
29
|
+
requireResolve: _requireResolve = require.resolve
|
|
30
|
+
}) => {
|
|
31
|
+
if (!requestCreator) {
|
|
32
|
+
// eslint-disable-next-line no-param-reassign
|
|
33
|
+
requestCreator = _requireResolve(`${DEFAULT_CLIENT_REQUEST_CREATOR}${target ? `/${target}` : ''}`).replace(/\\/g, '/');
|
|
34
|
+
} else {
|
|
35
|
+
// 这里约束传入的 requestCreator 包也必须有两个导出 client 和 server,因为目前的机制 client 和 server 要导出不同的 configure 函数;该 api 不对使用者暴露,后续可优化
|
|
36
|
+
let resolvedPath = requestCreator;
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
resolvedPath = path.dirname(_requireResolve(requestCreator));
|
|
40
|
+
} catch (error) {} // eslint-disable-next-line no-param-reassign
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
requestCreator = `${resolvedPath}${target ? `/${target}` : ''}`.replace(/\\/g, '/');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const apiRouter = new _router.ApiRouter({
|
|
47
|
+
apiDir,
|
|
48
|
+
prefix
|
|
49
|
+
});
|
|
50
|
+
const handlerInfos = apiRouter.getSingleModuleHandlers(resourcePath);
|
|
51
|
+
|
|
52
|
+
if (!handlerInfos) {
|
|
53
|
+
return (0, _result.Err)(`generate client error: Cannot require module ${resourcePath}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let handlersCode = '';
|
|
57
|
+
|
|
58
|
+
for (const handlerInfo of handlerInfos) {
|
|
59
|
+
const {
|
|
60
|
+
name,
|
|
61
|
+
httpMethod,
|
|
62
|
+
routePath
|
|
63
|
+
} = handlerInfo;
|
|
64
|
+
let exportStatement = `const ${name} =`;
|
|
65
|
+
|
|
66
|
+
if (name.toLowerCase() === 'default') {
|
|
67
|
+
exportStatement = 'default';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const upperHttpMethod = httpMethod.toUpperCase();
|
|
71
|
+
const routeName = routePath;
|
|
72
|
+
handlersCode += `export ${exportStatement} createRequest('${routeName}', '${upperHttpMethod}', process.env.PORT || ${String(port)}${fetcher ? `, fetch` : ''});
|
|
73
|
+
`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const importCode = `import { createRequest } from '${requestCreator}';
|
|
77
|
+
${fetcher ? `import { fetch } from '${fetcher}';\n` : ''}`;
|
|
78
|
+
return (0, _result.Ok)(`${importCode}\n${handlersCode}`);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
exports.generateClient = generateClient;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
var _generateClient = require("./generate-client");
|
|
8
|
+
|
|
9
|
+
Object.keys(_generateClient).forEach(function (key) {
|
|
10
|
+
if (key === "default" || key === "__esModule") return;
|
|
11
|
+
if (key in exports && exports[key] === _generateClient[key]) return;
|
|
12
|
+
Object.defineProperty(exports, key, {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _generateClient[key];
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Ok = exports.Err = void 0;
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
9
|
+
const Err = value => {
|
|
10
|
+
const err = {
|
|
11
|
+
kind: 'Err',
|
|
12
|
+
value,
|
|
13
|
+
isErr: true,
|
|
14
|
+
isOk: false
|
|
15
|
+
};
|
|
16
|
+
return err;
|
|
17
|
+
}; // eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
exports.Err = Err;
|
|
21
|
+
|
|
22
|
+
const Ok = value => {
|
|
23
|
+
const ok = {
|
|
24
|
+
kind: 'Ok',
|
|
25
|
+
value,
|
|
26
|
+
isErr: false,
|
|
27
|
+
isOk: true
|
|
28
|
+
};
|
|
29
|
+
return ok;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
exports.Ok = Ok;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ValidationError = exports.HttpError = void 0;
|
|
7
|
+
|
|
8
|
+
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; }
|
|
9
|
+
|
|
10
|
+
class HttpError extends Error {
|
|
11
|
+
constructor(status, message) {
|
|
12
|
+
super(message);
|
|
13
|
+
|
|
14
|
+
_defineProperty(this, "status", void 0);
|
|
15
|
+
|
|
16
|
+
this.status = status;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
exports.HttpError = HttpError;
|
|
22
|
+
|
|
23
|
+
class ValidationError extends HttpError {
|
|
24
|
+
constructor(status, message) {
|
|
25
|
+
super(status, message);
|
|
26
|
+
|
|
27
|
+
_defineProperty(this, "code", void 0);
|
|
28
|
+
|
|
29
|
+
this.code = 'VALIDATION_ERROR';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
exports.ValidationError = ValidationError;
|