@bleedingdev/modern-js-plugin-bff 3.5.0-ultramodern.97 → 3.5.0-ultramodern.99
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/cjs/runtime/effect/endpoint-contracts.js +6 -1
- package/dist/cjs/runtime/hono/adapter.js +32 -79
- package/dist/cjs/server.js +19 -30
- package/dist/cjs/utils/client-generator/write-package.js +1 -1
- package/dist/esm/runtime/effect/endpoint-contracts.mjs +6 -1
- package/dist/esm/runtime/hono/adapter.mjs +33 -80
- package/dist/esm/server.mjs +18 -29
- package/dist/esm/utils/client-generator/write-package.mjs +1 -1
- package/dist/esm-node/runtime/effect/endpoint-contracts.mjs +6 -1
- package/dist/esm-node/runtime/hono/adapter.mjs +33 -80
- package/dist/esm-node/server.mjs +18 -29
- package/dist/esm-node/utils/client-generator/write-package.mjs +1 -1
- package/dist/types/runtime/effect/endpoint-contracts.d.ts +6 -0
- package/dist/types/runtime/effect/handler/definition.d.ts +1 -1
- package/dist/types/runtime/effect/handler/http.d.ts +1 -1
- package/dist/types/runtime/effect/handler/openapi.d.ts +1 -1
- package/dist/types/runtime/effect/handler/types.d.ts +5 -5
- package/dist/types/runtime/effect-client/index.d.ts +1 -1
- package/dist/types/runtime/hono/adapter.d.ts +14 -8
- package/package.json +26 -14
|
@@ -37,6 +37,11 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
37
37
|
});
|
|
38
38
|
const bff_core_namespaceObject = require("@modern-js/bff-core");
|
|
39
39
|
const external_entry_shape_js_namespaceObject = require("./entry-shape.js");
|
|
40
|
+
function resolveEffectEndpointName(endpoint) {
|
|
41
|
+
if ('string' == typeof endpoint.identifier && endpoint.identifier) return endpoint.identifier;
|
|
42
|
+
if ('string' == typeof endpoint.name && endpoint.name) return endpoint.name;
|
|
43
|
+
return '';
|
|
44
|
+
}
|
|
40
45
|
function ensureLeadingSlash(pathname) {
|
|
41
46
|
return pathname.startsWith('/') ? pathname : `/${pathname}`;
|
|
42
47
|
}
|
|
@@ -65,7 +70,7 @@ function collectEffectEndpoints(reflect, api, prefix) {
|
|
|
65
70
|
endpoints.push({
|
|
66
71
|
apiId,
|
|
67
72
|
groupName: String(group.identifier),
|
|
68
|
-
endpointName:
|
|
73
|
+
endpointName: resolveEffectEndpointName(endpoint),
|
|
69
74
|
method: String(endpoint.method).toUpperCase(),
|
|
70
75
|
routePath: getEffectRoutePath(prefix, String(endpoint.path))
|
|
71
76
|
});
|
|
@@ -39,7 +39,6 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
39
39
|
__webpack_require__.d(__webpack_exports__, {
|
|
40
40
|
HonoAdapter: ()=>HonoAdapter
|
|
41
41
|
});
|
|
42
|
-
const server_core_namespaceObject = require("@modern-js/server-core");
|
|
43
42
|
const utils_namespaceObject = require("@modern-js/utils");
|
|
44
43
|
const createHonoRoutes_js_namespaceObject = require("../../utils/createHonoRoutes.js");
|
|
45
44
|
var createHonoRoutes_js_default = /*#__PURE__*/ __webpack_require__.n(createHonoRoutes_js_namespaceObject);
|
|
@@ -50,17 +49,9 @@ const before = [
|
|
|
50
49
|
'custom-server-middleware',
|
|
51
50
|
'render'
|
|
52
51
|
];
|
|
53
|
-
const kParentHonoVars = Symbol.for('modernjs.hono.parentVars');
|
|
54
52
|
class HonoAdapter {
|
|
55
|
-
wrapInArray(handler) {
|
|
56
|
-
if (Array.isArray(handler)) return handler;
|
|
57
|
-
return [
|
|
58
|
-
handler
|
|
59
|
-
];
|
|
60
|
-
}
|
|
61
53
|
constructor(api){
|
|
62
54
|
this.apiMiddleware = [];
|
|
63
|
-
this.apiServer = null;
|
|
64
55
|
this.isHono = true;
|
|
65
56
|
this.prefix = '/api';
|
|
66
57
|
this.setHandlers = async ()=>{
|
|
@@ -71,7 +62,7 @@ class HonoAdapter {
|
|
|
71
62
|
name: 'hono-bff-api',
|
|
72
63
|
path,
|
|
73
64
|
method,
|
|
74
|
-
handler,
|
|
65
|
+
handler: this.withErrorBoundary(handler),
|
|
75
66
|
order: 'post',
|
|
76
67
|
before
|
|
77
68
|
}));
|
|
@@ -92,85 +83,47 @@ class HonoAdapter {
|
|
|
92
83
|
});
|
|
93
84
|
}
|
|
94
85
|
};
|
|
95
|
-
this.
|
|
96
|
-
if (!this.isHono) return;
|
|
97
|
-
this.apiServer = new server_core_namespaceObject.Hono();
|
|
98
|
-
this.apiServer.use('*', server_core_namespaceObject.run);
|
|
99
|
-
this.apiServer.use('*', async (c, next)=>{
|
|
100
|
-
const nodeReq = c.env?.node?.req;
|
|
101
|
-
const parentVars = nodeReq?.[kParentHonoVars];
|
|
102
|
-
if (parentVars && 'object' == typeof parentVars) {
|
|
103
|
-
delete nodeReq[kParentHonoVars];
|
|
104
|
-
for (const [key, value] of Object.entries(parentVars))if (void 0 === c.get(key)) c.set(key, value);
|
|
105
|
-
}
|
|
106
|
-
await next();
|
|
107
|
-
});
|
|
108
|
-
this.apiMiddleware.forEach(({ path = '*', method = 'all', handler })=>{
|
|
109
|
-
const handlers = this.wrapInArray(handler);
|
|
110
|
-
if (0 === handlers.length) return;
|
|
111
|
-
const firstHandler = handlers[0];
|
|
112
|
-
const restHandlers = handlers.slice(1);
|
|
113
|
-
const m = method;
|
|
114
|
-
const server = this.apiServer;
|
|
115
|
-
if (!server) return;
|
|
116
|
-
const register = server[m];
|
|
117
|
-
register.call(server, path, firstHandler, ...restHandlers);
|
|
118
|
-
});
|
|
119
|
-
this.apiServer.onError(async (err, c)=>{
|
|
120
|
-
try {
|
|
121
|
-
const serverConfig = this.api.getServerConfig();
|
|
122
|
-
const onErrorHandler = serverConfig?.onError;
|
|
123
|
-
if (onErrorHandler) {
|
|
124
|
-
const result = await onErrorHandler(err, c);
|
|
125
|
-
if (result instanceof Response) return result;
|
|
126
|
-
} else utils_namespaceObject.logger.error(err);
|
|
127
|
-
} catch (configError) {
|
|
128
|
-
utils_namespaceObject.logger.error(`Error in serverConfig.onError handler: ${configError}`);
|
|
129
|
-
}
|
|
130
|
-
return (0, external_safe_failure_js_namespaceObject.createSafeFailureResponse)(err);
|
|
131
|
-
});
|
|
132
|
-
};
|
|
133
|
-
this.registerMiddleware = async (options)=>{
|
|
134
|
-
const { prefix } = options;
|
|
86
|
+
this.registerMiddleware = async (options = {})=>{
|
|
135
87
|
const { bffRuntimeFramework } = this.api.getServerContext();
|
|
136
88
|
if ('hono' !== bffRuntimeFramework) {
|
|
137
89
|
this.isHono = false;
|
|
138
90
|
return;
|
|
139
91
|
}
|
|
92
|
+
const { prefix } = options;
|
|
140
93
|
this.prefix = prefix || this.prefix;
|
|
141
94
|
const { middlewares: globalMiddlewares } = this.api.getServerContext();
|
|
142
95
|
await this.setHandlers();
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const nodeReq = c.env?.node?.req;
|
|
155
|
-
if (nodeReq) {
|
|
156
|
-
const parentVars = c?.var;
|
|
157
|
-
nodeReq[kParentHonoVars] = parentVars && 'object' == typeof parentVars ? {
|
|
158
|
-
...parentVars
|
|
159
|
-
} : parentVars;
|
|
160
|
-
}
|
|
161
|
-
const response = await this.apiServer.fetch(c.req.raw, c.env);
|
|
162
|
-
if (404 !== response.status) return new Response(response.body, response);
|
|
163
|
-
}
|
|
164
|
-
await next();
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
globalMiddlewares.push(dynamicApiMiddleware);
|
|
96
|
+
globalMiddlewares.push(...this.apiMiddleware);
|
|
97
|
+
};
|
|
98
|
+
this.handleRouteError = async (error, c)=>{
|
|
99
|
+
try {
|
|
100
|
+
const onErrorHandler = this.api.getServerConfig()?.onError;
|
|
101
|
+
if (onErrorHandler) {
|
|
102
|
+
const result = await onErrorHandler(error, c);
|
|
103
|
+
if (result instanceof Response) return result;
|
|
104
|
+
} else utils_namespaceObject.logger.error(error);
|
|
105
|
+
} catch (configError) {
|
|
106
|
+
utils_namespaceObject.logger.error(`Error in serverConfig.onError handler: ${configError}`);
|
|
168
107
|
}
|
|
108
|
+
return (0, external_safe_failure_js_namespaceObject.createSafeFailureResponse)(error);
|
|
169
109
|
};
|
|
170
|
-
this.
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
110
|
+
this.withErrorBoundary = (handler)=>{
|
|
111
|
+
const handlers = Array.isArray(handler) ? handler : [
|
|
112
|
+
handler
|
|
113
|
+
];
|
|
114
|
+
const [firstHandler, ...restHandlers] = handlers;
|
|
115
|
+
if (!firstHandler) return handler;
|
|
116
|
+
const boundary = async (c, next)=>{
|
|
117
|
+
try {
|
|
118
|
+
return await firstHandler(c, next);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
return this.handleRouteError(error, c);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
return Array.isArray(handler) ? [
|
|
124
|
+
boundary,
|
|
125
|
+
...restHandlers
|
|
126
|
+
] : boundary;
|
|
174
127
|
};
|
|
175
128
|
this.api = api;
|
|
176
129
|
}
|
package/dist/cjs/server.js
CHANGED
|
@@ -43,15 +43,17 @@ const bff_core_namespaceObject = require("@modern-js/bff-core");
|
|
|
43
43
|
const utils_namespaceObject = require("@modern-js/utils");
|
|
44
44
|
const external_path_namespaceObject = require("path");
|
|
45
45
|
var external_path_default = /*#__PURE__*/ __webpack_require__.n(external_path_namespaceObject);
|
|
46
|
-
const adapter_js_namespaceObject = require("./runtime/
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
const adapter_js_namespaceObject = require("./runtime/hono/adapter.js");
|
|
47
|
+
const RUNTIME_ADAPTER_LOADERS = {
|
|
48
|
+
hono: async (api)=>[
|
|
49
|
+
new adapter_js_namespaceObject.HonoAdapter(api)
|
|
50
|
+
],
|
|
51
|
+
effect: async (api)=>{
|
|
52
|
+
const { EffectAdapter } = await import("./runtime/effect/adapter.js");
|
|
53
|
+
return [
|
|
54
|
+
new EffectAdapter(api)
|
|
55
|
+
];
|
|
56
|
+
}
|
|
55
57
|
};
|
|
56
58
|
const normalizePrefixList = (prefix)=>{
|
|
57
59
|
if (Array.isArray(prefix)) return prefix.filter(Boolean);
|
|
@@ -64,9 +66,6 @@ function resolveRuntimeFramework(runtimeFramework) {
|
|
|
64
66
|
return 'hono' === runtimeFramework ? 'hono' : 'effect';
|
|
65
67
|
}
|
|
66
68
|
class Storage {
|
|
67
|
-
reset() {
|
|
68
|
-
this.middlewares = [];
|
|
69
|
-
}
|
|
70
69
|
constructor(){
|
|
71
70
|
this.middlewares = [];
|
|
72
71
|
}
|
|
@@ -78,7 +77,6 @@ const server = ()=>({
|
|
|
78
77
|
let apiRouter = null;
|
|
79
78
|
const appContext = api.getServerContext();
|
|
80
79
|
const runtimeFramework = resolveRuntimeFramework(appContext.bffRuntimeFramework);
|
|
81
|
-
const runtimeAdapters = RUNTIME_ADAPTER_FACTORIES[runtimeFramework].map((createAdapter)=>createAdapter(api));
|
|
82
80
|
api.onPrepare(async ()=>{
|
|
83
81
|
const appContext = api.getServerContext();
|
|
84
82
|
const { render } = appContext;
|
|
@@ -124,29 +122,20 @@ const server = ()=>({
|
|
|
124
122
|
]
|
|
125
123
|
});
|
|
126
124
|
}
|
|
125
|
+
const runtimeAdapters = await RUNTIME_ADAPTER_LOADERS[runtimeFramework](api);
|
|
127
126
|
await Promise.all(runtimeAdapters.map((adapter)=>adapter.registerMiddleware({
|
|
128
127
|
prefix,
|
|
129
128
|
enableHandleWeb
|
|
130
129
|
})));
|
|
131
130
|
});
|
|
132
131
|
api.onReset(async ({ event })=>{
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if ('file-change' === event.type) {
|
|
141
|
-
if ('hono' === runtimeFramework && apiRouter) {
|
|
142
|
-
const apiHandlerInfos = await apiRouter.getApiHandlers();
|
|
143
|
-
const appContext = api.getServerContext();
|
|
144
|
-
api.updateServerContext({
|
|
145
|
-
...appContext,
|
|
146
|
-
apiHandlerInfos
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
await Promise.all(runtimeAdapters.map((adapter)=>adapter.onApiHandlersUpdated?.()));
|
|
132
|
+
if ('file-change' === event.type && apiRouter) {
|
|
133
|
+
const appContext = api.getServerContext();
|
|
134
|
+
const apiHandlerInfos = await apiRouter.getApiHandlers();
|
|
135
|
+
api.updateServerContext({
|
|
136
|
+
...appContext,
|
|
137
|
+
apiHandlerInfos
|
|
138
|
+
});
|
|
150
139
|
}
|
|
151
140
|
});
|
|
152
141
|
const prepareApiServer = async (input, next)=>{
|
|
@@ -112,7 +112,7 @@ async function setPackage(files, appDirectory, relativeDistPath) {
|
|
|
112
112
|
}
|
|
113
113
|
});
|
|
114
114
|
(0, external_package_json_js_namespaceObject.mergePackageJson)(packageJson, addFiles, typesVersions, exports1, relativeDistPath);
|
|
115
|
-
await utils_namespaceObject.fs.promises.writeFile(packagePath, JSON.stringify(packageJson, null, 2));
|
|
115
|
+
await utils_namespaceObject.fs.promises.writeFile(packagePath, `${JSON.stringify(packageJson, null, 2)}\n`);
|
|
116
116
|
}
|
|
117
117
|
exports.setPackage = __webpack_exports__.setPackage;
|
|
118
118
|
exports.writeClientModuleBoundary = __webpack_exports__.writeClientModuleBoundary;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { createOperationContractHash } from "@modern-js/bff-core";
|
|
2
2
|
import { classifyEffectBffEntryModule, isValidatorAwareHandlerFactory } from "./entry-shape.mjs";
|
|
3
|
+
function resolveEffectEndpointName(endpoint) {
|
|
4
|
+
if ('string' == typeof endpoint.identifier && endpoint.identifier) return endpoint.identifier;
|
|
5
|
+
if ('string' == typeof endpoint.name && endpoint.name) return endpoint.name;
|
|
6
|
+
return '';
|
|
7
|
+
}
|
|
3
8
|
function ensureLeadingSlash(pathname) {
|
|
4
9
|
return pathname.startsWith('/') ? pathname : `/${pathname}`;
|
|
5
10
|
}
|
|
@@ -28,7 +33,7 @@ function collectEffectEndpoints(reflect, api, prefix) {
|
|
|
28
33
|
endpoints.push({
|
|
29
34
|
apiId,
|
|
30
35
|
groupName: String(group.identifier),
|
|
31
|
-
endpointName:
|
|
36
|
+
endpointName: resolveEffectEndpointName(endpoint),
|
|
32
37
|
method: String(endpoint.method).toUpperCase(),
|
|
33
38
|
routePath: getEffectRoutePath(prefix, String(endpoint.path))
|
|
34
39
|
});
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isProd, logger } from "@modern-js/utils";
|
|
1
|
+
import { logger } from "@modern-js/utils";
|
|
3
2
|
import createHonoRoutes from "../../utils/createHonoRoutes.mjs";
|
|
4
3
|
import { checkCrossProjectPolicyResponse, resolveAdapterCrossProjectPolicy } from "../../utils/crossProjectServerPolicy.mjs";
|
|
5
4
|
import { createSafeFailureResponse } from "../safe-failure.mjs";
|
|
@@ -8,17 +7,9 @@ const before = [
|
|
|
8
7
|
'custom-server-middleware',
|
|
9
8
|
'render'
|
|
10
9
|
];
|
|
11
|
-
const kParentHonoVars = Symbol.for('modernjs.hono.parentVars');
|
|
12
10
|
class HonoAdapter {
|
|
13
|
-
wrapInArray(handler) {
|
|
14
|
-
if (Array.isArray(handler)) return handler;
|
|
15
|
-
return [
|
|
16
|
-
handler
|
|
17
|
-
];
|
|
18
|
-
}
|
|
19
11
|
constructor(api){
|
|
20
12
|
this.apiMiddleware = [];
|
|
21
|
-
this.apiServer = null;
|
|
22
13
|
this.isHono = true;
|
|
23
14
|
this.prefix = '/api';
|
|
24
15
|
this.setHandlers = async ()=>{
|
|
@@ -29,7 +20,7 @@ class HonoAdapter {
|
|
|
29
20
|
name: 'hono-bff-api',
|
|
30
21
|
path,
|
|
31
22
|
method,
|
|
32
|
-
handler,
|
|
23
|
+
handler: this.withErrorBoundary(handler),
|
|
33
24
|
order: 'post',
|
|
34
25
|
before: before
|
|
35
26
|
}));
|
|
@@ -50,85 +41,47 @@ class HonoAdapter {
|
|
|
50
41
|
});
|
|
51
42
|
}
|
|
52
43
|
};
|
|
53
|
-
this.
|
|
54
|
-
if (!this.isHono) return;
|
|
55
|
-
this.apiServer = new Hono();
|
|
56
|
-
this.apiServer.use('*', run);
|
|
57
|
-
this.apiServer.use('*', async (c, next)=>{
|
|
58
|
-
const nodeReq = c.env?.node?.req;
|
|
59
|
-
const parentVars = nodeReq?.[kParentHonoVars];
|
|
60
|
-
if (parentVars && 'object' == typeof parentVars) {
|
|
61
|
-
delete nodeReq[kParentHonoVars];
|
|
62
|
-
for (const [key, value] of Object.entries(parentVars))if (void 0 === c.get(key)) c.set(key, value);
|
|
63
|
-
}
|
|
64
|
-
await next();
|
|
65
|
-
});
|
|
66
|
-
this.apiMiddleware.forEach(({ path = '*', method = 'all', handler })=>{
|
|
67
|
-
const handlers = this.wrapInArray(handler);
|
|
68
|
-
if (0 === handlers.length) return;
|
|
69
|
-
const firstHandler = handlers[0];
|
|
70
|
-
const restHandlers = handlers.slice(1);
|
|
71
|
-
const m = method;
|
|
72
|
-
const server = this.apiServer;
|
|
73
|
-
if (!server) return;
|
|
74
|
-
const register = server[m];
|
|
75
|
-
register.call(server, path, firstHandler, ...restHandlers);
|
|
76
|
-
});
|
|
77
|
-
this.apiServer.onError(async (err, c)=>{
|
|
78
|
-
try {
|
|
79
|
-
const serverConfig = this.api.getServerConfig();
|
|
80
|
-
const onErrorHandler = serverConfig?.onError;
|
|
81
|
-
if (onErrorHandler) {
|
|
82
|
-
const result = await onErrorHandler(err, c);
|
|
83
|
-
if (result instanceof Response) return result;
|
|
84
|
-
} else logger.error(err);
|
|
85
|
-
} catch (configError) {
|
|
86
|
-
logger.error(`Error in serverConfig.onError handler: ${configError}`);
|
|
87
|
-
}
|
|
88
|
-
return createSafeFailureResponse(err);
|
|
89
|
-
});
|
|
90
|
-
};
|
|
91
|
-
this.registerMiddleware = async (options)=>{
|
|
92
|
-
const { prefix } = options;
|
|
44
|
+
this.registerMiddleware = async (options = {})=>{
|
|
93
45
|
const { bffRuntimeFramework } = this.api.getServerContext();
|
|
94
46
|
if ('hono' !== bffRuntimeFramework) {
|
|
95
47
|
this.isHono = false;
|
|
96
48
|
return;
|
|
97
49
|
}
|
|
50
|
+
const { prefix } = options;
|
|
98
51
|
this.prefix = prefix || this.prefix;
|
|
99
52
|
const { middlewares: globalMiddlewares } = this.api.getServerContext();
|
|
100
53
|
await this.setHandlers();
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const nodeReq = c.env?.node?.req;
|
|
113
|
-
if (nodeReq) {
|
|
114
|
-
const parentVars = c?.var;
|
|
115
|
-
nodeReq[kParentHonoVars] = parentVars && 'object' == typeof parentVars ? {
|
|
116
|
-
...parentVars
|
|
117
|
-
} : parentVars;
|
|
118
|
-
}
|
|
119
|
-
const response = await this.apiServer.fetch(c.req.raw, c.env);
|
|
120
|
-
if (404 !== response.status) return new Response(response.body, response);
|
|
121
|
-
}
|
|
122
|
-
await next();
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
globalMiddlewares.push(dynamicApiMiddleware);
|
|
54
|
+
globalMiddlewares.push(...this.apiMiddleware);
|
|
55
|
+
};
|
|
56
|
+
this.handleRouteError = async (error, c)=>{
|
|
57
|
+
try {
|
|
58
|
+
const onErrorHandler = this.api.getServerConfig()?.onError;
|
|
59
|
+
if (onErrorHandler) {
|
|
60
|
+
const result = await onErrorHandler(error, c);
|
|
61
|
+
if (result instanceof Response) return result;
|
|
62
|
+
} else logger.error(error);
|
|
63
|
+
} catch (configError) {
|
|
64
|
+
logger.error(`Error in serverConfig.onError handler: ${configError}`);
|
|
126
65
|
}
|
|
66
|
+
return createSafeFailureResponse(error);
|
|
127
67
|
};
|
|
128
|
-
this.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
68
|
+
this.withErrorBoundary = (handler)=>{
|
|
69
|
+
const handlers = Array.isArray(handler) ? handler : [
|
|
70
|
+
handler
|
|
71
|
+
];
|
|
72
|
+
const [firstHandler, ...restHandlers] = handlers;
|
|
73
|
+
if (!firstHandler) return handler;
|
|
74
|
+
const boundary = async (c, next)=>{
|
|
75
|
+
try {
|
|
76
|
+
return await firstHandler(c, next);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
return this.handleRouteError(error, c);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
return Array.isArray(handler) ? [
|
|
82
|
+
boundary,
|
|
83
|
+
...restHandlers
|
|
84
|
+
] : boundary;
|
|
132
85
|
};
|
|
133
86
|
this.api = api;
|
|
134
87
|
}
|
package/dist/esm/server.mjs
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { ApiRouter } from "@modern-js/bff-core";
|
|
2
2
|
import { API_DIR, isFunction, isWebOnly } from "@modern-js/utils";
|
|
3
3
|
import path from "path";
|
|
4
|
-
import { EffectAdapter } from "./runtime/effect/adapter.mjs";
|
|
5
4
|
import { HonoAdapter } from "./runtime/hono/adapter.mjs";
|
|
6
|
-
const
|
|
7
|
-
hono: [
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
effect:
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
const RUNTIME_ADAPTER_LOADERS = {
|
|
6
|
+
hono: async (api)=>[
|
|
7
|
+
new HonoAdapter(api)
|
|
8
|
+
],
|
|
9
|
+
effect: async (api)=>{
|
|
10
|
+
const { EffectAdapter } = await import("./runtime/effect/adapter.mjs");
|
|
11
|
+
return [
|
|
12
|
+
new EffectAdapter(api)
|
|
13
|
+
];
|
|
14
|
+
}
|
|
13
15
|
};
|
|
14
16
|
const normalizePrefixList = (prefix)=>{
|
|
15
17
|
if (Array.isArray(prefix)) return prefix.filter(Boolean);
|
|
@@ -22,9 +24,6 @@ function resolveRuntimeFramework(runtimeFramework) {
|
|
|
22
24
|
return 'hono' === runtimeFramework ? 'hono' : 'effect';
|
|
23
25
|
}
|
|
24
26
|
class Storage {
|
|
25
|
-
reset() {
|
|
26
|
-
this.middlewares = [];
|
|
27
|
-
}
|
|
28
27
|
constructor(){
|
|
29
28
|
this.middlewares = [];
|
|
30
29
|
}
|
|
@@ -36,7 +35,6 @@ const server = ()=>({
|
|
|
36
35
|
let apiRouter = null;
|
|
37
36
|
const appContext = api.getServerContext();
|
|
38
37
|
const runtimeFramework = resolveRuntimeFramework(appContext.bffRuntimeFramework);
|
|
39
|
-
const runtimeAdapters = RUNTIME_ADAPTER_FACTORIES[runtimeFramework].map((createAdapter)=>createAdapter(api));
|
|
40
38
|
api.onPrepare(async ()=>{
|
|
41
39
|
const appContext = api.getServerContext();
|
|
42
40
|
const { render } = appContext;
|
|
@@ -82,29 +80,20 @@ const server = ()=>({
|
|
|
82
80
|
]
|
|
83
81
|
});
|
|
84
82
|
}
|
|
83
|
+
const runtimeAdapters = await RUNTIME_ADAPTER_LOADERS[runtimeFramework](api);
|
|
85
84
|
await Promise.all(runtimeAdapters.map((adapter)=>adapter.registerMiddleware({
|
|
86
85
|
prefix,
|
|
87
86
|
enableHandleWeb
|
|
88
87
|
})));
|
|
89
88
|
});
|
|
90
89
|
api.onReset(async ({ event })=>{
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if ('file-change' === event.type) {
|
|
99
|
-
if ('hono' === runtimeFramework && apiRouter) {
|
|
100
|
-
const apiHandlerInfos = await apiRouter.getApiHandlers();
|
|
101
|
-
const appContext = api.getServerContext();
|
|
102
|
-
api.updateServerContext({
|
|
103
|
-
...appContext,
|
|
104
|
-
apiHandlerInfos
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
await Promise.all(runtimeAdapters.map((adapter)=>adapter.onApiHandlersUpdated?.()));
|
|
90
|
+
if ('file-change' === event.type && apiRouter) {
|
|
91
|
+
const appContext = api.getServerContext();
|
|
92
|
+
const apiHandlerInfos = await apiRouter.getApiHandlers();
|
|
93
|
+
api.updateServerContext({
|
|
94
|
+
...appContext,
|
|
95
|
+
apiHandlerInfos
|
|
96
|
+
});
|
|
108
97
|
}
|
|
109
98
|
});
|
|
110
99
|
const prepareApiServer = async (input, next)=>{
|
|
@@ -69,6 +69,6 @@ async function setPackage(files, appDirectory, relativeDistPath) {
|
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
71
|
mergePackageJson(packageJson, addFiles, typesVersions, exports, relativeDistPath);
|
|
72
|
-
await fs.promises.writeFile(packagePath, JSON.stringify(packageJson, null, 2));
|
|
72
|
+
await fs.promises.writeFile(packagePath, `${JSON.stringify(packageJson, null, 2)}\n`);
|
|
73
73
|
}
|
|
74
74
|
export { setPackage, writeClientModuleBoundary };
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import { createOperationContractHash } from "@modern-js/bff-core";
|
|
3
3
|
import { classifyEffectBffEntryModule, isValidatorAwareHandlerFactory } from "./entry-shape.mjs";
|
|
4
|
+
function resolveEffectEndpointName(endpoint) {
|
|
5
|
+
if ('string' == typeof endpoint.identifier && endpoint.identifier) return endpoint.identifier;
|
|
6
|
+
if ('string' == typeof endpoint.name && endpoint.name) return endpoint.name;
|
|
7
|
+
return '';
|
|
8
|
+
}
|
|
4
9
|
function ensureLeadingSlash(pathname) {
|
|
5
10
|
return pathname.startsWith('/') ? pathname : `/${pathname}`;
|
|
6
11
|
}
|
|
@@ -29,7 +34,7 @@ function collectEffectEndpoints(reflect, api, prefix) {
|
|
|
29
34
|
endpoints.push({
|
|
30
35
|
apiId,
|
|
31
36
|
groupName: String(group.identifier),
|
|
32
|
-
endpointName:
|
|
37
|
+
endpointName: resolveEffectEndpointName(endpoint),
|
|
33
38
|
method: String(endpoint.method).toUpperCase(),
|
|
34
39
|
routePath: getEffectRoutePath(prefix, String(endpoint.path))
|
|
35
40
|
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
import {
|
|
3
|
-
import { isProd, logger } from "@modern-js/utils";
|
|
2
|
+
import { logger } from "@modern-js/utils";
|
|
4
3
|
import createHonoRoutes from "../../utils/createHonoRoutes.mjs";
|
|
5
4
|
import { checkCrossProjectPolicyResponse, resolveAdapterCrossProjectPolicy } from "../../utils/crossProjectServerPolicy.mjs";
|
|
6
5
|
import { createSafeFailureResponse } from "../safe-failure.mjs";
|
|
@@ -9,17 +8,9 @@ const before = [
|
|
|
9
8
|
'custom-server-middleware',
|
|
10
9
|
'render'
|
|
11
10
|
];
|
|
12
|
-
const kParentHonoVars = Symbol.for('modernjs.hono.parentVars');
|
|
13
11
|
class HonoAdapter {
|
|
14
|
-
wrapInArray(handler) {
|
|
15
|
-
if (Array.isArray(handler)) return handler;
|
|
16
|
-
return [
|
|
17
|
-
handler
|
|
18
|
-
];
|
|
19
|
-
}
|
|
20
12
|
constructor(api){
|
|
21
13
|
this.apiMiddleware = [];
|
|
22
|
-
this.apiServer = null;
|
|
23
14
|
this.isHono = true;
|
|
24
15
|
this.prefix = '/api';
|
|
25
16
|
this.setHandlers = async ()=>{
|
|
@@ -30,7 +21,7 @@ class HonoAdapter {
|
|
|
30
21
|
name: 'hono-bff-api',
|
|
31
22
|
path,
|
|
32
23
|
method,
|
|
33
|
-
handler,
|
|
24
|
+
handler: this.withErrorBoundary(handler),
|
|
34
25
|
order: 'post',
|
|
35
26
|
before: before
|
|
36
27
|
}));
|
|
@@ -51,85 +42,47 @@ class HonoAdapter {
|
|
|
51
42
|
});
|
|
52
43
|
}
|
|
53
44
|
};
|
|
54
|
-
this.
|
|
55
|
-
if (!this.isHono) return;
|
|
56
|
-
this.apiServer = new Hono();
|
|
57
|
-
this.apiServer.use('*', run);
|
|
58
|
-
this.apiServer.use('*', async (c, next)=>{
|
|
59
|
-
const nodeReq = c.env?.node?.req;
|
|
60
|
-
const parentVars = nodeReq?.[kParentHonoVars];
|
|
61
|
-
if (parentVars && 'object' == typeof parentVars) {
|
|
62
|
-
delete nodeReq[kParentHonoVars];
|
|
63
|
-
for (const [key, value] of Object.entries(parentVars))if (void 0 === c.get(key)) c.set(key, value);
|
|
64
|
-
}
|
|
65
|
-
await next();
|
|
66
|
-
});
|
|
67
|
-
this.apiMiddleware.forEach(({ path = '*', method = 'all', handler })=>{
|
|
68
|
-
const handlers = this.wrapInArray(handler);
|
|
69
|
-
if (0 === handlers.length) return;
|
|
70
|
-
const firstHandler = handlers[0];
|
|
71
|
-
const restHandlers = handlers.slice(1);
|
|
72
|
-
const m = method;
|
|
73
|
-
const server = this.apiServer;
|
|
74
|
-
if (!server) return;
|
|
75
|
-
const register = server[m];
|
|
76
|
-
register.call(server, path, firstHandler, ...restHandlers);
|
|
77
|
-
});
|
|
78
|
-
this.apiServer.onError(async (err, c)=>{
|
|
79
|
-
try {
|
|
80
|
-
const serverConfig = this.api.getServerConfig();
|
|
81
|
-
const onErrorHandler = serverConfig?.onError;
|
|
82
|
-
if (onErrorHandler) {
|
|
83
|
-
const result = await onErrorHandler(err, c);
|
|
84
|
-
if (result instanceof Response) return result;
|
|
85
|
-
} else logger.error(err);
|
|
86
|
-
} catch (configError) {
|
|
87
|
-
logger.error(`Error in serverConfig.onError handler: ${configError}`);
|
|
88
|
-
}
|
|
89
|
-
return createSafeFailureResponse(err);
|
|
90
|
-
});
|
|
91
|
-
};
|
|
92
|
-
this.registerMiddleware = async (options)=>{
|
|
93
|
-
const { prefix } = options;
|
|
45
|
+
this.registerMiddleware = async (options = {})=>{
|
|
94
46
|
const { bffRuntimeFramework } = this.api.getServerContext();
|
|
95
47
|
if ('hono' !== bffRuntimeFramework) {
|
|
96
48
|
this.isHono = false;
|
|
97
49
|
return;
|
|
98
50
|
}
|
|
51
|
+
const { prefix } = options;
|
|
99
52
|
this.prefix = prefix || this.prefix;
|
|
100
53
|
const { middlewares: globalMiddlewares } = this.api.getServerContext();
|
|
101
54
|
await this.setHandlers();
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const nodeReq = c.env?.node?.req;
|
|
114
|
-
if (nodeReq) {
|
|
115
|
-
const parentVars = c?.var;
|
|
116
|
-
nodeReq[kParentHonoVars] = parentVars && 'object' == typeof parentVars ? {
|
|
117
|
-
...parentVars
|
|
118
|
-
} : parentVars;
|
|
119
|
-
}
|
|
120
|
-
const response = await this.apiServer.fetch(c.req.raw, c.env);
|
|
121
|
-
if (404 !== response.status) return new Response(response.body, response);
|
|
122
|
-
}
|
|
123
|
-
await next();
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
globalMiddlewares.push(dynamicApiMiddleware);
|
|
55
|
+
globalMiddlewares.push(...this.apiMiddleware);
|
|
56
|
+
};
|
|
57
|
+
this.handleRouteError = async (error, c)=>{
|
|
58
|
+
try {
|
|
59
|
+
const onErrorHandler = this.api.getServerConfig()?.onError;
|
|
60
|
+
if (onErrorHandler) {
|
|
61
|
+
const result = await onErrorHandler(error, c);
|
|
62
|
+
if (result instanceof Response) return result;
|
|
63
|
+
} else logger.error(error);
|
|
64
|
+
} catch (configError) {
|
|
65
|
+
logger.error(`Error in serverConfig.onError handler: ${configError}`);
|
|
127
66
|
}
|
|
67
|
+
return createSafeFailureResponse(error);
|
|
128
68
|
};
|
|
129
|
-
this.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
69
|
+
this.withErrorBoundary = (handler)=>{
|
|
70
|
+
const handlers = Array.isArray(handler) ? handler : [
|
|
71
|
+
handler
|
|
72
|
+
];
|
|
73
|
+
const [firstHandler, ...restHandlers] = handlers;
|
|
74
|
+
if (!firstHandler) return handler;
|
|
75
|
+
const boundary = async (c, next)=>{
|
|
76
|
+
try {
|
|
77
|
+
return await firstHandler(c, next);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
return this.handleRouteError(error, c);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
return Array.isArray(handler) ? [
|
|
83
|
+
boundary,
|
|
84
|
+
...restHandlers
|
|
85
|
+
] : boundary;
|
|
133
86
|
};
|
|
134
87
|
this.api = api;
|
|
135
88
|
}
|
package/dist/esm-node/server.mjs
CHANGED
|
@@ -2,15 +2,17 @@ import "node:module";
|
|
|
2
2
|
import { ApiRouter } from "@modern-js/bff-core";
|
|
3
3
|
import { API_DIR, isFunction, isWebOnly } from "@modern-js/utils";
|
|
4
4
|
import path from "path";
|
|
5
|
-
import { EffectAdapter } from "./runtime/effect/adapter.mjs";
|
|
6
5
|
import { HonoAdapter } from "./runtime/hono/adapter.mjs";
|
|
7
|
-
const
|
|
8
|
-
hono: [
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
effect:
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
const RUNTIME_ADAPTER_LOADERS = {
|
|
7
|
+
hono: async (api)=>[
|
|
8
|
+
new HonoAdapter(api)
|
|
9
|
+
],
|
|
10
|
+
effect: async (api)=>{
|
|
11
|
+
const { EffectAdapter } = await import("./runtime/effect/adapter.mjs");
|
|
12
|
+
return [
|
|
13
|
+
new EffectAdapter(api)
|
|
14
|
+
];
|
|
15
|
+
}
|
|
14
16
|
};
|
|
15
17
|
const normalizePrefixList = (prefix)=>{
|
|
16
18
|
if (Array.isArray(prefix)) return prefix.filter(Boolean);
|
|
@@ -23,9 +25,6 @@ function resolveRuntimeFramework(runtimeFramework) {
|
|
|
23
25
|
return 'hono' === runtimeFramework ? 'hono' : 'effect';
|
|
24
26
|
}
|
|
25
27
|
class Storage {
|
|
26
|
-
reset() {
|
|
27
|
-
this.middlewares = [];
|
|
28
|
-
}
|
|
29
28
|
constructor(){
|
|
30
29
|
this.middlewares = [];
|
|
31
30
|
}
|
|
@@ -37,7 +36,6 @@ const server = ()=>({
|
|
|
37
36
|
let apiRouter = null;
|
|
38
37
|
const appContext = api.getServerContext();
|
|
39
38
|
const runtimeFramework = resolveRuntimeFramework(appContext.bffRuntimeFramework);
|
|
40
|
-
const runtimeAdapters = RUNTIME_ADAPTER_FACTORIES[runtimeFramework].map((createAdapter)=>createAdapter(api));
|
|
41
39
|
api.onPrepare(async ()=>{
|
|
42
40
|
const appContext = api.getServerContext();
|
|
43
41
|
const { render } = appContext;
|
|
@@ -83,29 +81,20 @@ const server = ()=>({
|
|
|
83
81
|
]
|
|
84
82
|
});
|
|
85
83
|
}
|
|
84
|
+
const runtimeAdapters = await RUNTIME_ADAPTER_LOADERS[runtimeFramework](api);
|
|
86
85
|
await Promise.all(runtimeAdapters.map((adapter)=>adapter.registerMiddleware({
|
|
87
86
|
prefix,
|
|
88
87
|
enableHandleWeb
|
|
89
88
|
})));
|
|
90
89
|
});
|
|
91
90
|
api.onReset(async ({ event })=>{
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if ('file-change' === event.type) {
|
|
100
|
-
if ('hono' === runtimeFramework && apiRouter) {
|
|
101
|
-
const apiHandlerInfos = await apiRouter.getApiHandlers();
|
|
102
|
-
const appContext = api.getServerContext();
|
|
103
|
-
api.updateServerContext({
|
|
104
|
-
...appContext,
|
|
105
|
-
apiHandlerInfos
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
await Promise.all(runtimeAdapters.map((adapter)=>adapter.onApiHandlersUpdated?.()));
|
|
91
|
+
if ('file-change' === event.type && apiRouter) {
|
|
92
|
+
const appContext = api.getServerContext();
|
|
93
|
+
const apiHandlerInfos = await apiRouter.getApiHandlers();
|
|
94
|
+
api.updateServerContext({
|
|
95
|
+
...appContext,
|
|
96
|
+
apiHandlerInfos
|
|
97
|
+
});
|
|
109
98
|
}
|
|
110
99
|
});
|
|
111
100
|
const prepareApiServer = async (input, next)=>{
|
|
@@ -70,6 +70,6 @@ async function setPackage(files, appDirectory, relativeDistPath) {
|
|
|
70
70
|
}
|
|
71
71
|
});
|
|
72
72
|
mergePackageJson(packageJson, addFiles, typesVersions, exports, relativeDistPath);
|
|
73
|
-
await fs.promises.writeFile(packagePath, JSON.stringify(packageJson, null, 2));
|
|
73
|
+
await fs.promises.writeFile(packagePath, `${JSON.stringify(packageJson, null, 2)}\n`);
|
|
74
74
|
}
|
|
75
75
|
export { setPackage, writeClientModuleBoundary };
|
|
@@ -25,6 +25,12 @@ type HttpApiGroupLike = {
|
|
|
25
25
|
identifier?: unknown;
|
|
26
26
|
};
|
|
27
27
|
type HttpApiEndpointLike = {
|
|
28
|
+
/**
|
|
29
|
+
* effect 4.0.0-beta.98 renamed the endpoint `name` property to `identifier`,
|
|
30
|
+
* matching `HttpApiGroup`. `name` is kept as a fallback so reflection over an
|
|
31
|
+
* older Effect build does not silently degrade to the class name.
|
|
32
|
+
*/
|
|
33
|
+
identifier?: unknown;
|
|
28
34
|
name?: unknown;
|
|
29
35
|
method?: unknown;
|
|
30
36
|
path?: unknown;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { HttpApi } from 'effect/unstable/httpapi';
|
|
2
2
|
import type { Rpc } from 'effect/unstable/rpc';
|
|
3
3
|
import type { EffectBffRuntime, EffectDataPlatformValidationOptions, EffectRpcBffDefinition, EffectRpcBffHandlerFactory, EffectRpcRuntimeLayer, EffectRuntimeLayer } from './types';
|
|
4
|
-
export declare function defineEffectBff<TApi extends HttpApi.
|
|
4
|
+
export declare function defineEffectBff<TApi extends HttpApi.Constraint, TLayer extends EffectRuntimeLayer, TRpcs extends Rpc.Any = Rpc.Any>(definition: {
|
|
5
5
|
api: TApi;
|
|
6
6
|
layer: TLayer;
|
|
7
7
|
rpc?: EffectRpcBffDefinition<TRpcs>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { HttpApi } from 'effect/unstable/httpapi';
|
|
2
2
|
import type { Rpc } from 'effect/unstable/rpc';
|
|
3
3
|
import type { EffectBffOpenApiConfig, EffectDataPlatformValidationOptions, EffectRequestValidator, EffectRpcBffDefinition, EffectRuntimeLayer } from './types';
|
|
4
|
-
export declare function createHttpApiHandler<TApi extends HttpApi.
|
|
4
|
+
export declare function createHttpApiHandler<TApi extends HttpApi.Constraint = HttpApi.Top, TRpcs extends Rpc.Any = Rpc.Any>(options: {
|
|
5
5
|
api: TApi;
|
|
6
6
|
layer: EffectRuntimeLayer;
|
|
7
7
|
openapi?: EffectBffOpenApiConfig;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { HttpRouter } from 'effect/unstable/http';
|
|
2
2
|
import { type HttpApi } from 'effect/unstable/httpapi';
|
|
3
3
|
import type { EffectBffOpenApiConfig } from './types';
|
|
4
|
-
export declare function createOpenApiLayer(api: HttpApi.
|
|
4
|
+
export declare function createOpenApiLayer(api: HttpApi.Constraint, openapi: EffectBffOpenApiConfig | undefined): import("effect/Layer").Layer<never, never, HttpRouter.HttpRouter> | null;
|
|
@@ -28,9 +28,9 @@ type EffectApiPromiseClient<TClient> = {
|
|
|
28
28
|
[EndpointName in keyof TClient[GroupName]]: TClient[GroupName][EndpointName] extends (...args: infer TArgs) => infer TResult ? TResult extends EffectType.Effect<unknown, unknown, unknown> ? (...args: TArgs) => Promise<Exclude<EffectType.Success<TResult>, readonly [unknown, unknown]>> : never : never;
|
|
29
29
|
};
|
|
30
30
|
};
|
|
31
|
-
export type EffectApiClientFromApi<TApi extends HttpApi.
|
|
32
|
-
export type EffectApiPromiseClientFromApi<TApi extends HttpApi.
|
|
33
|
-
export type EffectBffDefinition<TApi extends HttpApi.
|
|
31
|
+
export type EffectApiClientFromApi<TApi extends HttpApi.Constraint = HttpApi.Top> = TApi extends HttpApi.HttpApi<infer _ApiId, infer Groups> ? HttpApiClient.Client<Extract<Groups, HttpApiGroup.Constraint>, never, never> : never;
|
|
32
|
+
export type EffectApiPromiseClientFromApi<TApi extends HttpApi.Constraint = HttpApi.Top> = EffectApiPromiseClient<EffectApiClientFromApi<TApi>>;
|
|
33
|
+
export type EffectBffDefinition<TApi extends HttpApi.Constraint = HttpApi.Top, TLayer extends EffectRuntimeLayer = EffectRuntimeLayer, TRpcs extends Rpc.Any = Rpc.Any> = {
|
|
34
34
|
api: TApi;
|
|
35
35
|
layer: TLayer;
|
|
36
36
|
rpc?: EffectRpcBffDefinition<TRpcs>;
|
|
@@ -131,13 +131,13 @@ export type EffectDataPlatformValidationOptions = {
|
|
|
131
131
|
* cannot bypass it.
|
|
132
132
|
*/
|
|
133
133
|
export type EffectRequestValidator = (request: Request) => Response | null | undefined;
|
|
134
|
-
export type EffectBffHandlerFactory<TApi extends HttpApi.
|
|
134
|
+
export type EffectBffHandlerFactory<TApi extends HttpApi.Constraint = HttpApi.Top, TLayer extends EffectRuntimeLayer = EffectRuntimeLayer> = (options?: {
|
|
135
135
|
openapi?: EffectBffOpenApiConfig;
|
|
136
136
|
rpc?: Partial<EffectRpcBffHandlerOptions>;
|
|
137
137
|
dataPlatform?: Partial<EffectDataPlatformValidationOptions>;
|
|
138
138
|
validateRequest?: EffectRequestValidator;
|
|
139
139
|
}) => ReturnType<typeof createHttpApiHandler>;
|
|
140
|
-
export type EffectBffRuntime<TApi extends HttpApi.
|
|
140
|
+
export type EffectBffRuntime<TApi extends HttpApi.Constraint = HttpApi.Top, TLayer extends EffectRuntimeLayer = EffectRuntimeLayer> = {
|
|
141
141
|
createHandler: EffectBffHandlerFactory<TApi, TLayer>;
|
|
142
142
|
client: EffectApiPromiseClientFromApi<TApi>;
|
|
143
143
|
};
|
|
@@ -53,6 +53,6 @@ export type EffectRpcClientHandle<Rpcs extends Rpc.Any, Flatten extends boolean
|
|
|
53
53
|
export declare function view<T>(): <const Selection extends EffectViewSelection<T>>(selection: Selection) => Selection;
|
|
54
54
|
export declare function mask<T, const Selection extends EffectViewSelection<T>>(value: T, selection: Selection): EffectViewData<T, Selection>;
|
|
55
55
|
export declare function runEffectView<T, const Selection extends EffectViewSelection<T>>(request: PromiseLike<T>, selection: Selection): Promise<EffectViewData<T, Selection>>;
|
|
56
|
-
export declare function makeEffectHttpApiClient<ApiId extends string, Groups extends HttpApiGroup.
|
|
56
|
+
export declare function makeEffectHttpApiClient<ApiId extends string, Groups extends HttpApiGroup.Constraint>(api: HttpApi.HttpApi<ApiId, Groups>, options?: EffectHttpApiClientOptions): Effect.Effect<HttpApiClient.Client<Groups, never, never>, never, HttpApiGroup.MiddlewareClient<Groups>>;
|
|
57
57
|
export declare function makeEffectRpcClient<Rpcs extends Rpc.Any, const Flatten extends boolean = false>(group: RpcGroup.RpcGroup<Rpcs>, options: EffectRpcClientOptions<Rpcs, Flatten>): Effect.Effect<EffectRpcClientHandle<Rpcs, Flatten>, EffectRpcClientError, never>;
|
|
58
58
|
export declare const runEffectRequest: <A, E>(effect: Effect.Effect<A, E>, options?: Effect.RunOptions | undefined) => Promise<A>;
|
|
@@ -1,22 +1,28 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import { Hono } from '@modern-js/server-core';
|
|
1
|
+
import type { ServerMiddleware, ServerPluginAPI } from '@modern-js/server-core';
|
|
3
2
|
import { type ResolvedCrossProjectPolicy } from '../../utils/crossProjectServerPolicy';
|
|
4
3
|
interface MiddlewareOptions {
|
|
5
|
-
prefix
|
|
4
|
+
prefix?: string;
|
|
6
5
|
enableHandleWeb?: boolean;
|
|
7
6
|
}
|
|
8
7
|
export declare class HonoAdapter {
|
|
9
8
|
apiMiddleware: ServerMiddleware[];
|
|
10
|
-
apiServer: Hono | null;
|
|
11
9
|
api: ServerPluginAPI;
|
|
12
10
|
isHono: boolean;
|
|
13
11
|
prefix: string;
|
|
14
12
|
crossProjectPolicy: ResolvedCrossProjectPolicy | undefined;
|
|
15
13
|
constructor(api: ServerPluginAPI);
|
|
16
14
|
setHandlers: () => Promise<void>;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Register the BFF API routes as ordinary server middlewares.
|
|
17
|
+
*
|
|
18
|
+
* Dev and prod now share this single path: the routes are pushed straight
|
|
19
|
+
* into the server's middleware list. In dev, hot updates are handled by the
|
|
20
|
+
* unified `@modern-js/server` runtime reload (which rebuilds the whole
|
|
21
|
+
* runtime — including this plugin — from scratch), so BFF no longer needs its
|
|
22
|
+
* own swappable Hono sub-app / dynamic dispatch middleware.
|
|
23
|
+
*/
|
|
24
|
+
registerMiddleware: (options?: MiddlewareOptions) => Promise<void>;
|
|
25
|
+
private handleRouteError;
|
|
26
|
+
private withErrorBoundary;
|
|
21
27
|
}
|
|
22
28
|
export {};
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"modern",
|
|
18
18
|
"modern.js"
|
|
19
19
|
],
|
|
20
|
-
"version": "3.5.0-ultramodern.
|
|
20
|
+
"version": "3.5.0-ultramodern.99",
|
|
21
21
|
"types": "./dist/types/cli.d.ts",
|
|
22
22
|
"main": "./dist/cjs/cli.js",
|
|
23
23
|
"exports": {
|
|
@@ -153,13 +153,12 @@
|
|
|
153
153
|
}
|
|
154
154
|
},
|
|
155
155
|
"dependencies": {
|
|
156
|
-
"@
|
|
157
|
-
"@modern-js/
|
|
158
|
-
"@modern-js/
|
|
159
|
-
"@modern-js/
|
|
160
|
-
"@modern-js/server-
|
|
161
|
-
"@modern-js/
|
|
162
|
-
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.5.0-ultramodern.97",
|
|
156
|
+
"@modern-js/bff-core": "npm:@bleedingdev/modern-js-bff-core@3.5.0-ultramodern.99",
|
|
157
|
+
"@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.5.0-ultramodern.99",
|
|
158
|
+
"@modern-js/create-request": "npm:@bleedingdev/modern-js-create-request@3.5.0-ultramodern.99",
|
|
159
|
+
"@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.5.0-ultramodern.99",
|
|
160
|
+
"@modern-js/server-utils": "npm:@bleedingdev/modern-js-server-utils@3.5.0-ultramodern.99",
|
|
161
|
+
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.5.0-ultramodern.99",
|
|
163
162
|
"@module-federation/runtime": "2.8.0",
|
|
164
163
|
"@opentelemetry/api": "1.9.1",
|
|
165
164
|
"@opentelemetry/api-logs": "0.220.0",
|
|
@@ -172,17 +171,29 @@
|
|
|
172
171
|
"@opentelemetry/semantic-conventions": "1.43.0",
|
|
173
172
|
"@swc/core": "1.15.43",
|
|
174
173
|
"@swc/helpers": "^0.5.23",
|
|
175
|
-
"effect": "4.0.0-beta.97",
|
|
176
174
|
"esbuild": "^0.28.1",
|
|
177
175
|
"qs": "^6.15.3",
|
|
178
176
|
"type-is": "^2.1.0"
|
|
179
177
|
},
|
|
178
|
+
"peerDependencies": {
|
|
179
|
+
"@effect/opentelemetry": "4.0.0-beta.102",
|
|
180
|
+
"effect": "4.0.0-beta.102"
|
|
181
|
+
},
|
|
182
|
+
"peerDependenciesMeta": {
|
|
183
|
+
"@effect/opentelemetry": {
|
|
184
|
+
"optional": true
|
|
185
|
+
},
|
|
186
|
+
"effect": {
|
|
187
|
+
"optional": true
|
|
188
|
+
}
|
|
189
|
+
},
|
|
180
190
|
"devDependencies": {
|
|
181
|
-
"@
|
|
182
|
-
"@modern-js/
|
|
183
|
-
"@modern-js/
|
|
184
|
-
"@modern-js/
|
|
185
|
-
"@modern-js/
|
|
191
|
+
"@effect/opentelemetry": "4.0.0-beta.102",
|
|
192
|
+
"@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.5.0-ultramodern.99",
|
|
193
|
+
"@modern-js/bff-runtime": "npm:@bleedingdev/modern-js-bff-runtime@3.5.0-ultramodern.99",
|
|
194
|
+
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.5.0-ultramodern.99",
|
|
195
|
+
"@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.5.0-ultramodern.99",
|
|
196
|
+
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.5.0-ultramodern.99",
|
|
186
197
|
"@rsbuild/core": "2.1.5",
|
|
187
198
|
"@rslib/core": "0.23.2",
|
|
188
199
|
"@scripts/rstest-config": "2.66.0",
|
|
@@ -190,6 +201,7 @@
|
|
|
190
201
|
"@types/qs": "^6.15.1",
|
|
191
202
|
"@types/type-is": "^1.6.7",
|
|
192
203
|
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
204
|
+
"effect": "4.0.0-beta.102",
|
|
193
205
|
"memfs": "^4.64.0",
|
|
194
206
|
"typescript": "^7.0.2",
|
|
195
207
|
"zod": "^4.4.3"
|