@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
@@ -0,0 +1,271 @@
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
+ import path from 'path';
4
+ import { fs, logger } from '@modern-js/utils';
5
+ import 'reflect-metadata';
6
+ import 'esbuild-register';
7
+ import { HttpMethod, httpMethods, OperatorType, TriggerType } from "../types";
8
+ import { APIMode, FRAMEWORK_MODE_LAMBDA_DIR, API_FILE_RULES } from "./constants";
9
+ import { getFiles, getPathFromFilename, requireHandlerModule } from "./utils";
10
+ export * from "./types";
11
+ export * from "./constants";
12
+ export class ApiRouter {
13
+ constructor({
14
+ apiDir: _apiDir,
15
+ lambdaDir: _lambdaDir,
16
+ prefix
17
+ }) {
18
+ _defineProperty(this, "apiDir", void 0);
19
+
20
+ _defineProperty(this, "lambdaDir", void 0);
21
+
22
+ _defineProperty(this, "prefix", void 0);
23
+
24
+ _defineProperty(this, "apiFiles", void 0);
25
+
26
+ _defineProperty(this, "getAPIMode", apiDir => {
27
+ const exist = this.createExistChecker(apiDir);
28
+
29
+ if (exist(FRAMEWORK_MODE_LAMBDA_DIR)) {
30
+ return APIMode.FARMEWORK;
31
+ }
32
+
33
+ return APIMode.FUNCTION;
34
+ });
35
+
36
+ _defineProperty(this, "createExistChecker", base => target => fs.pathExistsSync(path.resolve(base, target)));
37
+
38
+ _defineProperty(this, "getLambdaDir", apiDir => {
39
+ if (this.lambdaDir) {
40
+ return this.lambdaDir;
41
+ }
42
+
43
+ const mode = this.getAPIMode(apiDir);
44
+ const lambdaDir = mode === APIMode.FARMEWORK ? path.join(apiDir, FRAMEWORK_MODE_LAMBDA_DIR) : apiDir;
45
+ return lambdaDir;
46
+ });
47
+
48
+ this.apiFiles = [];
49
+
50
+ if (_apiDir) {
51
+ this.validateAbsolute(_apiDir, 'apiDir');
52
+ }
53
+
54
+ if (_lambdaDir) {
55
+ this.validateAbsolute(_lambdaDir, 'lambdaDir');
56
+ }
57
+
58
+ this.prefix = this.initPrefix(prefix);
59
+ this.apiDir = _apiDir;
60
+ this.lambdaDir = _lambdaDir || this.getLambdaDir(this.apiDir);
61
+ }
62
+ /**
63
+ * 如果用户未传入或传入空串,默认为 /api
64
+ * 如果传入 /,则 prefix 为 /
65
+ */
66
+
67
+
68
+ initPrefix(prefix) {
69
+ if (prefix === '/') {
70
+ return '';
71
+ }
72
+
73
+ return prefix || '/api';
74
+ }
75
+
76
+ validateAbsolute(filename, paramsName) {
77
+ if (!path.isAbsolute(filename)) {
78
+ throw new Error(`The ${paramsName} ${filename} is not a abolute path`);
79
+ }
80
+ }
81
+
82
+ getModuleInfos(filenames) {
83
+ return filenames.map(filename => this.getModuleInfo(filename)).filter(moduleInfo => Boolean(moduleInfo));
84
+ }
85
+
86
+ getModuleInfo(filename) {
87
+ try {
88
+ const module = requireHandlerModule(filename);
89
+ return {
90
+ filename,
91
+ module
92
+ };
93
+ } catch (err) {
94
+ if (process.env.NODE_ENV === 'production') {
95
+ throw err;
96
+ } else {
97
+ console.error(err);
98
+ return null;
99
+ }
100
+ }
101
+ }
102
+
103
+ getHandlerInfos(moduleInfos) {
104
+ let apiHandlers = [];
105
+ moduleInfos.forEach(moduleInfo => {
106
+ const handlerInfos = this.getModuleHandlerInfos(moduleInfo);
107
+
108
+ if (handlerInfos) {
109
+ apiHandlers = apiHandlers.concat(handlerInfos);
110
+ }
111
+ });
112
+ return apiHandlers;
113
+ }
114
+
115
+ getModuleHandlerInfos(moduleInfo) {
116
+ const {
117
+ module,
118
+ filename
119
+ } = moduleInfo;
120
+ return Object.entries(module).filter(([, handler]) => typeof handler === 'function').map(([key]) => {
121
+ const handler = module[key];
122
+ const handlerInfo = this.getHandlerInfo(filename, key, handler);
123
+ return handlerInfo;
124
+ }).filter(handlerInfo => Boolean(handlerInfo));
125
+ }
126
+
127
+ validateValidApifile(filename) {
128
+ if (!this.apiFiles.includes(filename)) {
129
+ throw new Error(`The ${filename} is not a valid api file.`);
130
+ }
131
+ }
132
+
133
+ getRoutePath(prefix, routeName) {
134
+ const finalRouteName = routeName === '/' ? '' : routeName;
135
+
136
+ if (prefix === '' && finalRouteName === '') {
137
+ return '/';
138
+ }
139
+
140
+ return `${prefix}${finalRouteName}`;
141
+ }
142
+
143
+ isApiFile(filename) {
144
+ if (!this.apiFiles.includes(filename)) {
145
+ return false;
146
+ }
147
+
148
+ return true;
149
+ }
150
+
151
+ getSingleModuleHandlers(filename) {
152
+ const moduleInfo = this.getModuleInfo(filename);
153
+
154
+ if (moduleInfo) {
155
+ return this.getModuleHandlerInfos(moduleInfo);
156
+ }
157
+
158
+ return null;
159
+ }
160
+
161
+ getHandlerInfo(filename, originFuncName, handler) {
162
+ const httpMethod = this.getHttpMethod(originFuncName, handler);
163
+ const routeName = this.getRouteName(filename, handler);
164
+
165
+ if (httpMethod && routeName) {
166
+ return {
167
+ handler,
168
+ name: originFuncName,
169
+ httpMethod,
170
+ routeName,
171
+ filename,
172
+ routePath: this.getRoutePath(this.prefix, routeName)
173
+ };
174
+ }
175
+
176
+ return null;
177
+ } // TODO: 性能提升,开发环境,判断下 lambda 目录修改时间
178
+
179
+
180
+ getSafeRoutePath(filename, handler) {
181
+ this.loadApiFiles();
182
+ this.validateValidApifile(filename);
183
+ return this.getRouteName(filename, handler);
184
+ }
185
+
186
+ getRouteName(filename, handler) {
187
+ if (handler) {
188
+ const trigger = Reflect.getMetadata(OperatorType.Trigger, handler);
189
+
190
+ if (trigger && trigger.type === TriggerType.Http) {
191
+ if (!trigger.path) {
192
+ throw new Error(`The http trigger ${trigger.name} needs to specify a path`);
193
+ }
194
+
195
+ return trigger.path;
196
+ }
197
+ }
198
+
199
+ const routePath = getPathFromFilename(this.lambdaDir, filename);
200
+ return routePath;
201
+ }
202
+
203
+ getHttpMethod(originHandlerName, handler) {
204
+ if (handler) {
205
+ const trigger = Reflect.getMetadata(OperatorType.Trigger, handler);
206
+
207
+ if (trigger && httpMethods.includes(trigger.method)) {
208
+ return trigger.method;
209
+ }
210
+ }
211
+
212
+ const upperName = originHandlerName.toUpperCase();
213
+
214
+ switch (upperName) {
215
+ case 'GET':
216
+ return HttpMethod.Get;
217
+
218
+ case 'POST':
219
+ return HttpMethod.Post;
220
+
221
+ case 'PUT':
222
+ return HttpMethod.Put;
223
+
224
+ case 'DELETE':
225
+ case 'DEL':
226
+ return HttpMethod.Delete;
227
+
228
+ case 'CONNECT':
229
+ return HttpMethod.Connect;
230
+
231
+ case 'TRACE':
232
+ return HttpMethod.Trace;
233
+
234
+ case 'PATCH':
235
+ return HttpMethod.Patch;
236
+
237
+ case 'OPTION':
238
+ return HttpMethod.Option;
239
+
240
+ case 'DEFAULT':
241
+ {
242
+ return HttpMethod.Get;
243
+ }
244
+
245
+ default:
246
+ logger.warn(`Only api handlers are allowd to be exported, please remove the function ${originHandlerName} from exports`);
247
+ return null;
248
+ }
249
+ }
250
+
251
+ loadApiFiles() {
252
+ // eslint-disable-next-line no-multi-assign
253
+ const apiFiles = this.apiFiles = getFiles(this.lambdaDir, API_FILE_RULES);
254
+ return apiFiles;
255
+ }
256
+
257
+ getApiFiles() {
258
+ if (this.apiFiles.length > 0) {
259
+ return this.apiFiles;
260
+ }
261
+
262
+ return this.loadApiFiles();
263
+ }
264
+
265
+ getApiHandlers() {
266
+ const filenames = this.getApiFiles();
267
+ const moduleInfos = this.getModuleInfos(filenames);
268
+ return this.getHandlerInfos(moduleInfos);
269
+ }
270
+
271
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,53 @@
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 isFunction = input => input && {}.toString.call(input) === '[object Function]';
42
+
43
+ export const requireHandlerModule = modulePath => {
44
+ const module = require(modulePath);
45
+
46
+ if (isFunction(module)) {
47
+ return {
48
+ default: module
49
+ };
50
+ }
51
+
52
+ return module;
53
+ };
@@ -0,0 +1,42 @@
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["StatusCode"] = "STATUS_CODE";
24
+ HttpMetadata["Redirect"] = "REDIRECT";
25
+ HttpMetadata["ResponseHeaders"] = "RESPONSE_HEADERS";
26
+ })(HttpMetadata || (HttpMetadata = {}));
27
+
28
+ export let HttpMethod;
29
+
30
+ (function (HttpMethod) {
31
+ HttpMethod["Get"] = "GET";
32
+ HttpMethod["Post"] = "POST";
33
+ HttpMethod["Put"] = "PUT";
34
+ HttpMethod["Delete"] = "DELETE";
35
+ HttpMethod["Connect"] = "CONNECT";
36
+ HttpMethod["Trace"] = "TRACE";
37
+ HttpMethod["Patch"] = "PATCH";
38
+ HttpMethod["Option"] = "OPTION";
39
+ HttpMethod["Head"] = "HEAD";
40
+ })(HttpMethod || (HttpMethod = {}));
41
+
42
+ export const httpMethods = Object.values(HttpMethod);
@@ -0,0 +1,61 @@
1
+ import util from 'util';
2
+ export const HANDLER_WITH_META = 'HANDLER_WITH_SCHEMA'; // export const pick = <T extends Record<string, unknown>, K extends keyof T>(
3
+ // obj: T,
4
+ // keys: readonly K[],
5
+ // ) => {
6
+ // Object.entries(obj).filter(([key]) => {
7
+ // return (keys as readonly string[]).includes(key);
8
+ // });
9
+ // };
10
+ // fork from https://github.com/nodejs/node/blob/master/lib/internal/errors.js
11
+
12
+ export const getTypeErrorMessage = actual => {
13
+ let msg = '';
14
+
15
+ if (actual == null) {
16
+ msg += `. Received ${actual}`;
17
+ } else if (typeof actual === 'function' && actual.name) {
18
+ msg += `. Received function ${actual.name}`;
19
+ } else if (typeof actual === 'object') {
20
+ var _actual$constructor;
21
+
22
+ if ((_actual$constructor = actual.constructor) !== null && _actual$constructor !== void 0 && _actual$constructor.name) {
23
+ msg += `. Received an instance of ${actual.constructor.name}`;
24
+ } else {
25
+ const inspected = util.inspect(actual, {
26
+ depth: -1
27
+ });
28
+ msg += `. Received ${inspected}`;
29
+ }
30
+ } else {
31
+ let inspected = util.inspect(actual, {
32
+ colors: false
33
+ });
34
+
35
+ if (inspected.length > 25) {
36
+ inspected = `${inspected.slice(0, 25)}...`;
37
+ }
38
+
39
+ msg += `. Received type ${typeof actual} (${inspected})`;
40
+ }
41
+
42
+ return msg;
43
+ }; // eslint-disable-next-line @typescript-eslint/naming-convention
44
+
45
+ export class ERR_INVALID_ARG_TYPE extends Error {
46
+ constructor(funcName, expectedType, actual) {
47
+ const message = `[ERR_INVALID_ARG_TYPE]: The '${funcName}' argument must be of type ${expectedType}${getTypeErrorMessage(actual)}`;
48
+ super(message);
49
+ }
50
+
51
+ }
52
+ export const validateFunction = (maybeFunc, name) => {
53
+ if (typeof maybeFunc !== 'function') {
54
+ throw new ERR_INVALID_ARG_TYPE(name, 'function', maybeFunc);
55
+ }
56
+
57
+ return true;
58
+ };
59
+ export const isWithMetaHandler = handler => {
60
+ return typeof handler === 'function' && handler[HANDLER_WITH_META];
61
+ };
@@ -0,0 +1,71 @@
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
+
39
+ async function runner(inputs) {
40
+ // 错误组合传给用户哪些信息?
41
+ // 取出来所有的 schema,然后做校验
42
+ // 包裹中间件,怎么根据不同框架去包裹?
43
+ // 需要满足的需求,可以关闭某一样 schema 的校验
44
+ // 可以关闭某一个字段的校验
45
+ // 可以设置校验函数以替换 zod ?类型怎么搞?
46
+ // 全局可配置校验函数
47
+ // middleware 多框架实现要支持在路由上配,但这样 middleware 就要在校验之前先执行了
48
+ // 简易模式适配怎么处理?
49
+ // 不同框架适配,响应怎么处理?都传入 co ntext 给这个函数?
50
+ // 如何不依赖 zod 库?支持用户自定义 schema 库? Query,Data 实现可以统一代码,类型好像无解,除非这些函数是创建出来的,保证只有 http 中依赖 zod 吧
51
+ const executeHelper = {
52
+ result: null,
53
+
54
+ get inputs() {
55
+ return inputs;
56
+ }
57
+
58
+ };
59
+ const stack = [...validateHandlers];
60
+ stack.push(async (helper, next) => {
61
+ const res = await handler(inputs);
62
+ helper.result = res;
63
+ return next();
64
+ });
65
+ await (0, _koaCompose.default)(stack)(executeHelper);
66
+ return executeHelper.result;
67
+ }
68
+
69
+ runner[_utils.HANDLER_WITH_META] = true;
70
+ return runner;
71
+ }
@@ -0,0 +1,82 @@
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
+ lambdaDir: apiDir
50
+ });
51
+ const handlerInfos = apiRouter.getSingleModuleHandlers(resourcePath);
52
+
53
+ if (!handlerInfos) {
54
+ return (0, _result.Err)(`Cannot require module ${resourcePath}`);
55
+ }
56
+
57
+ let handlersCode = '';
58
+
59
+ for (const handlerInfo of handlerInfos) {
60
+ const {
61
+ name,
62
+ httpMethod,
63
+ routePath
64
+ } = handlerInfo;
65
+ let exportStatement = `const ${name} =`;
66
+
67
+ if (name.toLowerCase() === 'default') {
68
+ exportStatement = 'default';
69
+ }
70
+
71
+ const upperHttpMethod = httpMethod.toUpperCase();
72
+ const routeName = routePath;
73
+ handlersCode += `export ${exportStatement} createRequest('${routeName}', '${upperHttpMethod}', process.env.PORT || ${String(port)}${fetcher ? `, fetch` : ''});
74
+ `;
75
+ }
76
+
77
+ const importCode = `import { createRequest } from '${requestCreator}';
78
+ ${fetcher ? `import { fetch } from '${fetcher}';\n` : ''}`;
79
+ return (0, _result.Ok)(`${importCode}\n${handlersCode}`);
80
+ };
81
+
82
+ 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,25 @@
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
+
25
+ exports.ValidationError = ValidationError;