@bleedingdev/modern-js-bff-core 3.2.0-ultramodern.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 (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +26 -0
  3. package/dist/cjs/api.js +88 -0
  4. package/dist/cjs/client/generateClient.js +136 -0
  5. package/dist/cjs/client/index.js +58 -0
  6. package/dist/cjs/client/result.js +56 -0
  7. package/dist/cjs/compatible.js +18 -0
  8. package/dist/cjs/contracts/eventContracts.js +68 -0
  9. package/dist/cjs/errors/http.js +50 -0
  10. package/dist/cjs/index.js +229 -0
  11. package/dist/cjs/operators/http.js +220 -0
  12. package/dist/cjs/router/constants.js +68 -0
  13. package/dist/cjs/router/index.js +284 -0
  14. package/dist/cjs/router/types.js +18 -0
  15. package/dist/cjs/router/utils.js +97 -0
  16. package/dist/cjs/security/crossProjectPolicy.js +137 -0
  17. package/dist/cjs/security/operationContracts.js +100 -0
  18. package/dist/cjs/types.js +88 -0
  19. package/dist/cjs/utils/alias.js +108 -0
  20. package/dist/cjs/utils/debug.js +37 -0
  21. package/dist/cjs/utils/index.js +101 -0
  22. package/dist/cjs/utils/meta.js +48 -0
  23. package/dist/cjs/utils/storage.js +64 -0
  24. package/dist/cjs/utils/validate.js +82 -0
  25. package/dist/esm/api.mjs +44 -0
  26. package/dist/esm/client/generateClient.mjs +99 -0
  27. package/dist/esm/client/index.mjs +1 -0
  28. package/dist/esm/client/result.mjs +19 -0
  29. package/dist/esm/compatible.mjs +0 -0
  30. package/dist/esm/contracts/eventContracts.mjs +28 -0
  31. package/dist/esm/errors/http.mjs +13 -0
  32. package/dist/esm/index.mjs +10 -0
  33. package/dist/esm/operators/http.mjs +135 -0
  34. package/dist/esm/router/constants.mjs +19 -0
  35. package/dist/esm/router/index.mjs +192 -0
  36. package/dist/esm/router/types.mjs +0 -0
  37. package/dist/esm/router/utils.mjs +41 -0
  38. package/dist/esm/security/crossProjectPolicy.mjs +94 -0
  39. package/dist/esm/security/operationContracts.mjs +57 -0
  40. package/dist/esm/types.mjs +39 -0
  41. package/dist/esm/utils/alias.mjs +57 -0
  42. package/dist/esm/utils/debug.mjs +3 -0
  43. package/dist/esm/utils/index.mjs +5 -0
  44. package/dist/esm/utils/meta.mjs +5 -0
  45. package/dist/esm/utils/storage.mjs +30 -0
  46. package/dist/esm/utils/validate.mjs +32 -0
  47. package/dist/esm-node/api.mjs +45 -0
  48. package/dist/esm-node/client/generateClient.mjs +101 -0
  49. package/dist/esm-node/client/index.mjs +2 -0
  50. package/dist/esm-node/client/result.mjs +20 -0
  51. package/dist/esm-node/compatible.mjs +1 -0
  52. package/dist/esm-node/contracts/eventContracts.mjs +29 -0
  53. package/dist/esm-node/errors/http.mjs +14 -0
  54. package/dist/esm-node/index.mjs +11 -0
  55. package/dist/esm-node/operators/http.mjs +136 -0
  56. package/dist/esm-node/router/constants.mjs +20 -0
  57. package/dist/esm-node/router/index.mjs +193 -0
  58. package/dist/esm-node/router/types.mjs +1 -0
  59. package/dist/esm-node/router/utils.mjs +42 -0
  60. package/dist/esm-node/security/crossProjectPolicy.mjs +95 -0
  61. package/dist/esm-node/security/operationContracts.mjs +58 -0
  62. package/dist/esm-node/types.mjs +40 -0
  63. package/dist/esm-node/utils/alias.mjs +58 -0
  64. package/dist/esm-node/utils/debug.mjs +4 -0
  65. package/dist/esm-node/utils/index.mjs +6 -0
  66. package/dist/esm-node/utils/meta.mjs +6 -0
  67. package/dist/esm-node/utils/storage.mjs +31 -0
  68. package/dist/esm-node/utils/validate.mjs +33 -0
  69. package/dist/types/api.d.ts +6 -0
  70. package/dist/types/client/generateClient.d.ts +21 -0
  71. package/dist/types/client/index.d.ts +1 -0
  72. package/dist/types/client/result.d.ts +15 -0
  73. package/dist/types/compatible.d.ts +9 -0
  74. package/dist/types/contracts/eventContracts.d.ts +22 -0
  75. package/dist/types/errors/http.d.ts +8 -0
  76. package/dist/types/index.d.ts +11 -0
  77. package/dist/types/operators/http.d.ts +44 -0
  78. package/dist/types/router/constants.d.ts +6 -0
  79. package/dist/types/router/index.d.ts +49 -0
  80. package/dist/types/router/types.d.ts +18 -0
  81. package/dist/types/router/utils.d.ts +10 -0
  82. package/dist/types/security/crossProjectPolicy.d.ts +30 -0
  83. package/dist/types/security/operationContracts.d.ts +28 -0
  84. package/dist/types/types.d.ts +64 -0
  85. package/dist/types/utils/alias.d.ts +7 -0
  86. package/dist/types/utils/debug.d.ts +1 -0
  87. package/dist/types/utils/index.d.ts +5 -0
  88. package/dist/types/utils/meta.d.ts +4 -0
  89. package/dist/types/utils/storage.d.ts +5 -0
  90. package/dist/types/utils/validate.d.ts +5 -0
  91. package/package.json +68 -0
  92. package/rslib.config.mts +4 -0
  93. package/rstest.config.mts +10 -0
@@ -0,0 +1,57 @@
1
+ import fs from "fs";
2
+ import module_0 from "module";
3
+ import * as __rspack_external_os from "os";
4
+ import * as __rspack_external_path from "path";
5
+ const getRelativeRuntimePath = (appDirectory, serverRuntimePath)=>{
6
+ let relativeRuntimePath = '';
7
+ relativeRuntimePath = 'win32' === __rspack_external_os.platform() ? `../${__rspack_external_path.relative(appDirectory, serverRuntimePath)}` : __rspack_external_path.join('../', __rspack_external_path.relative(appDirectory, serverRuntimePath));
8
+ if ('development' === process.env.NODE_ENV || 'test' === process.env.NODE_ENV) relativeRuntimePath = `./${__rspack_external_path.relative(appDirectory, serverRuntimePath)}`;
9
+ return relativeRuntimePath;
10
+ };
11
+ const sortByLongestPrefix = (arr)=>arr.concat().sort((a, b)=>b.length - a.length);
12
+ const createMatchPath = (paths)=>{
13
+ const sortedKeys = sortByLongestPrefix(Object.keys(paths));
14
+ const sortedPaths = {};
15
+ sortedKeys.forEach((key)=>{
16
+ sortedPaths[key] = paths[key];
17
+ });
18
+ return (request)=>{
19
+ const found = Object.keys(sortedPaths).find((key)=>request.startsWith(key));
20
+ if (found) {
21
+ let foundPaths = sortedPaths[found];
22
+ if (!Array.isArray(foundPaths)) foundPaths = [
23
+ foundPaths
24
+ ];
25
+ foundPaths = foundPaths.filter((foundPath)=>__rspack_external_path.isAbsolute(foundPath));
26
+ for (const p of foundPaths){
27
+ const foundPath = request.replace(found, p);
28
+ if (fs.existsSync(foundPath)) return foundPath;
29
+ }
30
+ return request.replace(found, foundPaths[0]);
31
+ }
32
+ return null;
33
+ };
34
+ };
35
+ const registerPaths = (paths)=>{
36
+ const originalResolveFilename = module_0._resolveFilename;
37
+ const { builtinModules } = module_0;
38
+ const matchPath = createMatchPath(paths);
39
+ module_0._resolveFilename = function(request, _parent) {
40
+ const isCoreModule = builtinModules.includes(request);
41
+ if (!isCoreModule) {
42
+ const matched = matchPath(request);
43
+ if (matched) {
44
+ const modifiedArguments = [
45
+ matched,
46
+ ...[].slice.call(arguments, 1)
47
+ ];
48
+ return originalResolveFilename.apply(this, modifiedArguments);
49
+ }
50
+ }
51
+ return originalResolveFilename.apply(this, arguments);
52
+ };
53
+ return ()=>{
54
+ module_0._resolveFilename = originalResolveFilename;
55
+ };
56
+ };
57
+ export { createMatchPath, getRelativeRuntimePath, registerPaths };
@@ -0,0 +1,3 @@
1
+ import { createDebugger } from "@modern-js/utils";
2
+ const debug = createDebugger('bff');
3
+ export { debug };
@@ -0,0 +1,5 @@
1
+ export * from "./alias.mjs";
2
+ export * from "./meta.mjs";
3
+ export * from "./storage.mjs";
4
+ export * from "./validate.mjs";
5
+ export { debug } from "./debug.mjs";
@@ -0,0 +1,5 @@
1
+ const HANDLER_WITH_META = 'HANDLER_WITH_META';
2
+ const INPUT_PARAMS_DECIDER = 'INPUT_PARAMS_DECIDER';
3
+ const isWithMetaHandler = (handler)=>'function' == typeof handler && handler[HANDLER_WITH_META];
4
+ const isInputParamsDeciderHandler = (handler)=>'function' == typeof handler && handler[INPUT_PARAMS_DECIDER];
5
+ export { HANDLER_WITH_META, INPUT_PARAMS_DECIDER, isInputParamsDeciderHandler, isWithMetaHandler };
@@ -0,0 +1,30 @@
1
+ import * as __rspack_external_async_hooks from "async_hooks";
2
+ const createStorage = ()=>{
3
+ let storage;
4
+ if (void 0 !== __rspack_external_async_hooks.AsyncLocalStorage) storage = new __rspack_external_async_hooks.AsyncLocalStorage();
5
+ const run = (context, cb)=>{
6
+ if (!storage) throw new Error(`Unable to use async_hook, please confirm the node version >= 12.17
7
+ `);
8
+ return new Promise((resolve, reject)=>{
9
+ storage.run(context, ()=>{
10
+ try {
11
+ return resolve(cb());
12
+ } catch (error) {
13
+ return reject(error);
14
+ }
15
+ });
16
+ });
17
+ };
18
+ const useContext = ()=>{
19
+ if (!storage) throw new Error(`Unable to use async_hook, please confirm the node version >= 12.17
20
+ `);
21
+ const context = storage.getStore();
22
+ if (!context) throw new Error("Can't call useContext out of scope, it should be placed in the bff function");
23
+ return context;
24
+ };
25
+ return {
26
+ run,
27
+ useContext
28
+ };
29
+ };
30
+ export { createStorage };
@@ -0,0 +1,32 @@
1
+ import util from "util";
2
+ const getTypeErrorMessage = (actual)=>{
3
+ let msg = '';
4
+ if (null == actual) msg += `. Received ${actual}`;
5
+ else if ('function' == typeof actual && actual.name) msg += `. Received function ${actual.name}`;
6
+ else if ('object' == typeof actual) if (actual.constructor?.name) msg += `. Received an instance of ${actual.constructor.name}`;
7
+ else {
8
+ const inspected = util.inspect(actual, {
9
+ depth: -1
10
+ });
11
+ msg += `. Received ${inspected}`;
12
+ }
13
+ else {
14
+ let inspected = util.inspect(actual, {
15
+ colors: false
16
+ });
17
+ if (inspected.length > 25) inspected = `${inspected.slice(0, 25)}...`;
18
+ msg += `. Received type ${typeof actual} (${inspected})`;
19
+ }
20
+ return msg;
21
+ };
22
+ class ERR_INVALID_ARG_TYPE extends Error {
23
+ constructor(funcName, expectedType, actual){
24
+ const message = `[ERR_INVALID_ARG_TYPE]: The '${funcName}' argument must be of type ${expectedType}${getTypeErrorMessage(actual)}`;
25
+ super(message);
26
+ }
27
+ }
28
+ const validateFunction = (maybeFunc, name)=>{
29
+ if ('function' != typeof maybeFunc) throw new ERR_INVALID_ARG_TYPE(name, 'function', maybeFunc);
30
+ return true;
31
+ };
32
+ export { ERR_INVALID_ARG_TYPE, getTypeErrorMessage, validateFunction };
@@ -0,0 +1,45 @@
1
+ import "node:module";
2
+ import "reflect-metadata";
3
+ import koa_compose from "koa-compose";
4
+ import { HANDLER_WITH_META, validateFunction } from "./utils/index.mjs";
5
+ function Api(...args) {
6
+ const handler = args.pop();
7
+ validateFunction(handler, 'Apihandler');
8
+ const operators = args;
9
+ const metadataHelper = {
10
+ getMetadata (key) {
11
+ return Reflect.getMetadata(key, runner);
12
+ },
13
+ setMetadata (key, value) {
14
+ return Reflect.defineMetadata(key, value, runner);
15
+ }
16
+ };
17
+ for (const operator of operators)if (operator.metadata) operator.metadata(metadataHelper);
18
+ const validateHandlers = operators.filter((operator)=>operator.validate).map((operator)=>operator.validate);
19
+ const pipeHandlers = operators.filter((operator)=>operator.execute).map((operator)=>operator.execute);
20
+ async function runner(inputs) {
21
+ const executeHelper = {
22
+ result: null,
23
+ get inputs () {
24
+ return inputs;
25
+ },
26
+ set inputs (val){
27
+ inputs = val;
28
+ }
29
+ };
30
+ const stack = [
31
+ ...validateHandlers,
32
+ ...pipeHandlers
33
+ ];
34
+ stack.push(async (helper, next)=>{
35
+ const res = await handler(helper.inputs);
36
+ helper.result = res;
37
+ return next();
38
+ });
39
+ await koa_compose(stack)(executeHelper);
40
+ return executeHelper.result;
41
+ }
42
+ runner[HANDLER_WITH_META] = true;
43
+ return runner;
44
+ }
45
+ export { Api };
@@ -0,0 +1,101 @@
1
+ import __rslib_shim_module__ from "node:module";
2
+ const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(/*#__PURE__*/ (()=>import.meta.url)());
3
+ import "path";
4
+ import { ApiRouter } from "../router/index.mjs";
5
+ import { createOperationEntries, createOperationSchemaHash } from "../security/operationContracts.mjs";
6
+ import { Err, Ok } from "./result.mjs";
7
+ const INNER_CLIENT_REQUEST_CREATOR = '@modern-js/plugin-bff/client';
8
+ const generateClient = async ({ appDir, resourcePath, apiDir, lambdaDir, prefix, port, target, requestCreator, fetcher, requireResolve = require.resolve, httpMethodDecider, domain, requestId })=>{
9
+ requestCreator = requestCreator || INNER_CLIENT_REQUEST_CREATOR;
10
+ const apiRouter = new ApiRouter({
11
+ appDir,
12
+ apiDir,
13
+ lambdaDir,
14
+ prefix,
15
+ httpMethodDecider
16
+ });
17
+ const handlerInfos = await apiRouter.getSingleModuleHandlers(resourcePath);
18
+ if (!handlerInfos) return Err(`generate client error: Cannot require module ${resourcePath}`);
19
+ const operationEntries = createOperationEntries(handlerInfos);
20
+ const operationVersion = 1;
21
+ const schemaHash = createOperationSchemaHash(operationEntries, requestId || 'default');
22
+ let handlersCode = '';
23
+ for (const handlerInfo of handlerInfos){
24
+ const { name, httpMethod, routePath, action } = handlerInfo;
25
+ let exportStatement = `var ${name} =`;
26
+ if ('default' === name.toLowerCase()) exportStatement = 'default';
27
+ const upperHttpMethod = httpMethod.toUpperCase();
28
+ const serializedRouteName = JSON.stringify(routePath);
29
+ const serializedMethod = JSON.stringify(upperHttpMethod);
30
+ const serializedMethodDecider = JSON.stringify(httpMethodDecider ? httpMethodDecider : 'functionName');
31
+ const serializedOperationContext = JSON.stringify({
32
+ operationId: name,
33
+ routePath,
34
+ method: upperHttpMethod,
35
+ schemaHash,
36
+ operationVersion
37
+ });
38
+ const tailArgs = `, ${fetcher ? 'fetch' : 'undefined'}, ${requestId ? JSON.stringify(requestId) : 'undefined'}, ${serializedOperationContext}`;
39
+ if ('server' === target) handlersCode += `export ${exportStatement} createRequest(${serializedRouteName}, ${serializedMethod}, process.env.PORT || ${String(port)}, ${serializedMethodDecider}${tailArgs});
40
+ `;
41
+ else handlersCode += `export ${exportStatement} createRequest(${serializedRouteName}, ${serializedMethod}, ${String(port)}, ${serializedMethodDecider}${tailArgs});
42
+ `;
43
+ }
44
+ const serializedRequestCreator = JSON.stringify(requestCreator);
45
+ const serializedFetcher = fetcher ? JSON.stringify(fetcher) : void 0;
46
+ const importCode = requestId ? `import * as requestRuntime from ${serializedRequestCreator};
47
+ const { createRequest } = requestRuntime;
48
+ ${serializedFetcher ? `import { fetch } from ${serializedFetcher};\n` : ''}` : `import { createRequest } from ${serializedRequestCreator};
49
+ ${serializedFetcher ? `import { fetch } from ${serializedFetcher};\n` : ''}`;
50
+ const bootstrapCode = requestId ? `export const initProducerClient = (options = {}) => {
51
+ const configure = requestRuntime.configure;
52
+ if (typeof configure !== 'function') {
53
+ console.warn('[modernjs] Compatibility request creator path does not expose configure(); use default @modern-js/create-request or migrate the compatibility path.');
54
+ return undefined;
55
+ }
56
+ const defaultSecureOptions = {
57
+ requestId: ${JSON.stringify(requestId)},
58
+ requireEnvelope: true,
59
+ identityBinding: {
60
+ enabled: true,
61
+ strict: true,
62
+ },
63
+ operationContract: {
64
+ enabled: true,
65
+ strict: true,
66
+ requireSchemaHash: true,
67
+ requireOperationVersion: true,
68
+ },
69
+ };
70
+ return configure({
71
+ ...defaultSecureOptions,
72
+ ...options,
73
+ identityBinding: {
74
+ ...defaultSecureOptions.identityBinding,
75
+ ...(options && options.identityBinding ? options.identityBinding : {}),
76
+ },
77
+ operationContract: {
78
+ ...defaultSecureOptions.operationContract,
79
+ ...(options && options.operationContract ? options.operationContract : {}),
80
+ },
81
+ });
82
+ };
83
+ ` : '';
84
+ const manifestCode = `export const operationVersion = ${String(operationVersion)};
85
+ export const operationSchemaHash = '${schemaHash}';
86
+ export const operationManifest = ${JSON.stringify({
87
+ operationVersion,
88
+ schemaHash,
89
+ operations: operationEntries
90
+ }, null, 2)};
91
+ `;
92
+ const generatedParts = [
93
+ importCode.trimEnd(),
94
+ bootstrapCode.trimEnd(),
95
+ manifestCode.trimEnd(),
96
+ handlersCode.trimEnd()
97
+ ].filter(Boolean);
98
+ return Ok(`${generatedParts.join('\n\n')}
99
+ `);
100
+ };
101
+ export { INNER_CLIENT_REQUEST_CREATOR, generateClient };
@@ -0,0 +1,2 @@
1
+ import "node:module";
2
+ export * from "./generateClient.mjs";
@@ -0,0 +1,20 @@
1
+ import "node:module";
2
+ const Err = (value)=>{
3
+ const err = {
4
+ kind: 'Err',
5
+ value,
6
+ isErr: true,
7
+ isOk: false
8
+ };
9
+ return err;
10
+ };
11
+ const Ok = (value)=>{
12
+ const ok = {
13
+ kind: 'Ok',
14
+ value,
15
+ isErr: false,
16
+ isOk: true
17
+ };
18
+ return ok;
19
+ };
20
+ export { Err, Ok };
@@ -0,0 +1 @@
1
+ import "node:module";
@@ -0,0 +1,29 @@
1
+ import "node:module";
2
+ const defineEventContract = (input)=>{
3
+ const normalizedName = input.name.trim();
4
+ if (!normalizedName) throw new Error('Event contract name must be non-empty');
5
+ if (!Number.isFinite(input.version) || input.version <= 0) throw new Error('Event contract version must be a positive number');
6
+ if (!input.schemaHash || !input.schemaHash.trim()) throw new Error('Event contract schemaHash must be non-empty');
7
+ return {
8
+ name: normalizedName,
9
+ version: Math.floor(input.version),
10
+ schemaHash: input.schemaHash.trim(),
11
+ description: input.description
12
+ };
13
+ };
14
+ const createEventEnvelope = (contract, payload, meta)=>({
15
+ name: contract.name,
16
+ version: contract.version,
17
+ schemaHash: contract.schemaHash,
18
+ timestamp: Date.now(),
19
+ payload,
20
+ ...meta ? {
21
+ meta
22
+ } : {}
23
+ });
24
+ const isEventEnvelope = (value)=>{
25
+ if (!value || 'object' != typeof value || Array.isArray(value)) return false;
26
+ const candidate = value;
27
+ return 'string' == typeof candidate.name && candidate.name.length > 0 && 'number' == typeof candidate.version && candidate.version > 0 && 'string' == typeof candidate.schemaHash && candidate.schemaHash.length > 0 && 'number' == typeof candidate.timestamp && Number.isFinite(candidate.timestamp) && 'payload' in candidate;
28
+ };
29
+ export { createEventEnvelope, defineEventContract, isEventEnvelope };
@@ -0,0 +1,14 @@
1
+ import "node:module";
2
+ class HttpError extends Error {
3
+ constructor(status, message){
4
+ super(message);
5
+ this.status = status;
6
+ }
7
+ }
8
+ class ValidationError extends HttpError {
9
+ constructor(status, message){
10
+ super(status, message);
11
+ this.code = 'VALIDATION_ERROR';
12
+ }
13
+ }
14
+ export { HttpError, ValidationError };
@@ -0,0 +1,11 @@
1
+ import "node:module";
2
+ export * from "./client/index.mjs";
3
+ export * from "./contracts/eventContracts.mjs";
4
+ export * from "./operators/http.mjs";
5
+ export * from "./router/index.mjs";
6
+ export * from "./security/crossProjectPolicy.mjs";
7
+ export * from "./security/operationContracts.mjs";
8
+ export * from "./types.mjs";
9
+ export { Api } from "./api.mjs";
10
+ export { HttpError, ValidationError } from "./errors/http.mjs";
11
+ export { HANDLER_WITH_META, INPUT_PARAMS_DECIDER, createStorage, getRelativeRuntimePath, isInputParamsDeciderHandler, isWithMetaHandler, registerPaths } from "./utils/index.mjs";
@@ -0,0 +1,136 @@
1
+ import "node:module";
2
+ import { ValidationError } from "../errors/http.mjs";
3
+ import { HttpMetadata, HttpMethod, OperatorType, ResponseMetaType, TriggerType } from "../types.mjs";
4
+ const validateInput = async (schema, input)=>{
5
+ try {
6
+ return await schema.parseAsync(input);
7
+ } catch (error) {
8
+ if ('name' in error && 'ZodError' === error.name) throw new ValidationError(400, error.message);
9
+ throw error;
10
+ }
11
+ };
12
+ const createHttpOperator = (method)=>(urlPath)=>({
13
+ name: method,
14
+ metadata ({ setMetadata }) {
15
+ setMetadata(OperatorType.Trigger, {
16
+ type: TriggerType.Http,
17
+ path: urlPath,
18
+ method
19
+ });
20
+ }
21
+ });
22
+ const Get = createHttpOperator(HttpMethod.Get);
23
+ const Post = createHttpOperator(HttpMethod.Post);
24
+ const Put = createHttpOperator(HttpMethod.Put);
25
+ const Delete = createHttpOperator(HttpMethod.Delete);
26
+ const Connect = createHttpOperator(HttpMethod.Connect);
27
+ const Trace = createHttpOperator(HttpMethod.Trace);
28
+ const Patch = createHttpOperator(HttpMethod.Patch);
29
+ const Options = createHttpOperator(HttpMethod.Options);
30
+ const Head = createHttpOperator(HttpMethod.Head);
31
+ const Data = (schema)=>({
32
+ name: HttpMetadata.Data,
33
+ metadata ({ setMetadata }) {
34
+ setMetadata(HttpMetadata.Data, schema);
35
+ },
36
+ async validate (helper, next) {
37
+ const { inputs: { data } } = helper;
38
+ helper.inputs = {
39
+ ...helper.inputs,
40
+ data: await validateInput(schema, data)
41
+ };
42
+ return next();
43
+ }
44
+ });
45
+ const Query = (schema)=>({
46
+ name: HttpMetadata.Query,
47
+ metadata ({ setMetadata }) {
48
+ setMetadata(HttpMetadata.Query, schema);
49
+ },
50
+ async validate (helper, next) {
51
+ const { inputs: { query } } = helper;
52
+ helper.inputs = {
53
+ ...helper.inputs,
54
+ query: await validateInput(schema, query)
55
+ };
56
+ return next();
57
+ }
58
+ });
59
+ const Params = (schema)=>({
60
+ name: HttpMetadata.Params,
61
+ metadata ({ setMetadata }) {
62
+ setMetadata(HttpMetadata.Params, schema);
63
+ },
64
+ async validate (helper, next) {
65
+ const { inputs: { params } } = helper;
66
+ helper.inputs = {
67
+ ...helper.inputs,
68
+ params: await validateInput(schema, params)
69
+ };
70
+ return next();
71
+ }
72
+ });
73
+ const Headers = (schema)=>({
74
+ name: HttpMetadata.Headers,
75
+ metadata ({ setMetadata }) {
76
+ setMetadata(HttpMetadata.Headers, schema);
77
+ },
78
+ async validate (helper, next) {
79
+ const { inputs: { headers } } = helper;
80
+ helper.inputs = {
81
+ ...helper.inputs,
82
+ headers: await validateInput(schema, headers)
83
+ };
84
+ return next();
85
+ }
86
+ });
87
+ const setResponseMeta = (helper, type, value)=>{
88
+ const responseMetaData = helper.getMetadata(HttpMetadata.Response) || [];
89
+ helper.setMetadata(HttpMetadata.Response, [
90
+ ...responseMetaData,
91
+ {
92
+ type,
93
+ value
94
+ }
95
+ ]);
96
+ };
97
+ const HttpCode = (statusCode)=>({
98
+ name: 'HttpCode',
99
+ metadata (helper) {
100
+ setResponseMeta(helper, ResponseMetaType.StatusCode, statusCode);
101
+ }
102
+ });
103
+ const SetHeaders = (headers)=>({
104
+ name: 'SetHeaders',
105
+ metadata (helper) {
106
+ setResponseMeta(helper, ResponseMetaType.Headers, headers);
107
+ }
108
+ });
109
+ const Redirect = (url)=>({
110
+ name: 'Redirect',
111
+ metadata (helper) {
112
+ setResponseMeta(helper, ResponseMetaType.Redirect, url);
113
+ }
114
+ });
115
+ const Upload = (urlPath, schema)=>({
116
+ name: 'Upload',
117
+ metadata ({ setMetadata }) {
118
+ setMetadata(OperatorType.Trigger, {
119
+ type: TriggerType.Http,
120
+ path: urlPath,
121
+ method: HttpMethod.Post,
122
+ action: 'upload'
123
+ });
124
+ setMetadata(HttpMetadata.Files, schema);
125
+ },
126
+ async validate (helper, next) {
127
+ if (!schema) return next();
128
+ const { inputs: { formData: files } } = helper;
129
+ helper.inputs = {
130
+ ...helper.inputs,
131
+ files: await validateInput(schema, files)
132
+ };
133
+ return next();
134
+ }
135
+ });
136
+ export { Connect, Data, Delete, Get, Head, Headers, HttpCode, Options, Params, Patch, Post, Put, Query, Redirect, SetHeaders, Trace, Upload, createHttpOperator };
@@ -0,0 +1,20 @@
1
+ import "node:module";
2
+ import { HttpMethod } from "../types.mjs";
3
+ const AllHttpMethods = Object.values(HttpMethod);
4
+ const FRAMEWORK_MODE_LAMBDA_DIR = 'lambda';
5
+ const FRAMEWORK_MODE_APP_DIR = 'app';
6
+ const INDEX_SUFFIX = 'index';
7
+ const API_DIR = 'api';
8
+ const API_FILE_RULES = [
9
+ '**/*.[tj]s',
10
+ '!**/_*',
11
+ '!**/_*/**/*.[tj]s',
12
+ '!**/*.test.js',
13
+ '!**/*.test.ts',
14
+ '!**/*.d.ts',
15
+ '!__test__/*.ts',
16
+ '!__tests__/*.ts',
17
+ '!node_modules/**',
18
+ '!bootstrap.jsx'
19
+ ];
20
+ export { API_DIR, API_FILE_RULES, AllHttpMethods, FRAMEWORK_MODE_APP_DIR, FRAMEWORK_MODE_LAMBDA_DIR, INDEX_SUFFIX };