@bleedingdev/modern-js-bff-core 3.9.0-ultramodern.2 → 3.9.0-ultramodern.20
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/client/generateClient.js +67 -138
- package/dist/cjs/index.js +24 -114
- package/dist/cjs/router/index.js +7 -5
- package/dist/cjs/utils/index.js +11 -21
- package/dist/esm/client/generateClient.mjs +65 -139
- package/dist/esm/index.mjs +1 -5
- package/dist/esm/router/index.mjs +7 -5
- package/dist/esm/utils/index.mjs +0 -1
- package/dist/esm-node/client/generateClient.mjs +65 -139
- package/dist/esm-node/index.mjs +1 -5
- package/dist/esm-node/router/index.mjs +7 -5
- package/dist/esm-node/utils/index.mjs +0 -1
- package/dist/types/client/generateClient.d.ts +24 -1
- package/dist/types/index.d.ts +1 -5
- package/dist/types/utils/index.d.ts +0 -1
- package/package.json +10 -19
- package/dist/cjs/adapter-kit/index.js +0 -144
- package/dist/cjs/adapter-kit/parity-scenarios/cross-project-denial.js +0 -55
- package/dist/cjs/adapter-kit/parity-scenarios/envelope.js +0 -128
- package/dist/cjs/adapter-kit/parity-scenarios/operation-context.js +0 -152
- package/dist/cjs/adapter-kit/parity-scenarios/schema.js +0 -109
- package/dist/cjs/adapter-kit/parity-scenarios/shared.js +0 -71
- package/dist/cjs/adapter-kit/parity.js +0 -204
- package/dist/cjs/security/crossProjectPolicy.js +0 -309
- package/dist/cjs/security/operationContracts.js +0 -183
- package/dist/cjs/security/resolveCrossProjectPolicy.js +0 -65
- package/dist/cjs/utils/alias.js +0 -112
- package/dist/esm/adapter-kit/index.mjs +0 -79
- package/dist/esm/adapter-kit/parity-scenarios/cross-project-denial.mjs +0 -17
- package/dist/esm/adapter-kit/parity-scenarios/envelope.mjs +0 -90
- package/dist/esm/adapter-kit/parity-scenarios/operation-context.mjs +0 -111
- package/dist/esm/adapter-kit/parity-scenarios/schema.mjs +0 -71
- package/dist/esm/adapter-kit/parity-scenarios/shared.mjs +0 -21
- package/dist/esm/adapter-kit/parity.mjs +0 -148
- package/dist/esm/security/crossProjectPolicy.mjs +0 -259
- package/dist/esm/security/operationContracts.mjs +0 -127
- package/dist/esm/security/resolveCrossProjectPolicy.mjs +0 -27
- package/dist/esm/utils/alias.mjs +0 -57
- package/dist/esm-node/adapter-kit/index.mjs +0 -80
- package/dist/esm-node/adapter-kit/parity-scenarios/cross-project-denial.mjs +0 -18
- package/dist/esm-node/adapter-kit/parity-scenarios/envelope.mjs +0 -91
- package/dist/esm-node/adapter-kit/parity-scenarios/operation-context.mjs +0 -112
- package/dist/esm-node/adapter-kit/parity-scenarios/schema.mjs +0 -72
- package/dist/esm-node/adapter-kit/parity-scenarios/shared.mjs +0 -22
- package/dist/esm-node/adapter-kit/parity.mjs +0 -149
- package/dist/esm-node/security/crossProjectPolicy.mjs +0 -260
- package/dist/esm-node/security/operationContracts.mjs +0 -130
- package/dist/esm-node/security/resolveCrossProjectPolicy.mjs +0 -28
- package/dist/esm-node/utils/alias.mjs +0 -58
- package/dist/types/adapter-kit/index.d.ts +0 -90
- package/dist/types/adapter-kit/parity-scenarios/cross-project-denial.d.ts +0 -2
- package/dist/types/adapter-kit/parity-scenarios/envelope.d.ts +0 -2
- package/dist/types/adapter-kit/parity-scenarios/operation-context.d.ts +0 -3
- package/dist/types/adapter-kit/parity-scenarios/schema.d.ts +0 -2
- package/dist/types/adapter-kit/parity-scenarios/shared.d.ts +0 -32
- package/dist/types/adapter-kit/parity.d.ts +0 -43
- package/dist/types/security/crossProjectPolicy.d.ts +0 -110
- package/dist/types/security/operationContracts.d.ts +0 -84
- package/dist/types/security/resolveCrossProjectPolicy.d.ts +0 -39
- package/dist/types/utils/alias.d.ts +0 -7
|
@@ -1,22 +1,18 @@
|
|
|
1
|
+
import { pathToFileURL } from "node:url";
|
|
1
2
|
import { ApiRouter } from "../router/index.mjs";
|
|
2
|
-
import { buildOperationContractMap, createOperationSchemaHash, deriveOperationVersion } from "../security/operationContracts.mjs";
|
|
3
3
|
import { Err, Ok } from "./result.mjs";
|
|
4
4
|
import * as __rspack_external_path from "path";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
version: packageJson.version
|
|
12
|
-
};
|
|
13
|
-
} catch (error) {
|
|
14
|
-
return {};
|
|
5
|
+
class ClientCodegenError extends Error {
|
|
6
|
+
constructor(plugin, cause){
|
|
7
|
+
super(`BFF client code-generation plugin failed: ${plugin}`, {
|
|
8
|
+
cause
|
|
9
|
+
});
|
|
10
|
+
this.name = 'ClientCodegenError';
|
|
15
11
|
}
|
|
16
|
-
}
|
|
12
|
+
}
|
|
17
13
|
const INNER_CLIENT_REQUEST_CREATOR = '@modern-js/plugin-bff/client';
|
|
18
|
-
const generateClient = async (
|
|
19
|
-
|
|
14
|
+
const generateClient = async (options)=>{
|
|
15
|
+
const { appDir, resourcePath, apiDir, lambdaDir, prefix, port, target, fetcher, requireResolve = require.resolve, httpMethodDecider, domain, requestId, clientCodegenPlugin } = options;
|
|
20
16
|
const apiRouter = new ApiRouter({
|
|
21
17
|
appDir,
|
|
22
18
|
apiDir,
|
|
@@ -26,131 +22,61 @@ const generateClient = async ({ appDir, resourcePath, apiDir, lambdaDir, prefix,
|
|
|
26
22
|
});
|
|
27
23
|
const handlerInfos = await apiRouter.getSingleModuleHandlers(resourcePath);
|
|
28
24
|
if (!handlerInfos) return Err(`generate client error: Cannot require module ${resourcePath}`);
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
});
|
|
50
|
-
const schemaHash = createOperationSchemaHash(operationEntries, normalizedRequestId);
|
|
51
|
-
let hasUploadHandler = false;
|
|
52
|
-
let handlersCode = '';
|
|
53
|
-
for (const handlerInfo of handlerInfos){
|
|
54
|
-
const { name, httpMethod, routePath, action } = handlerInfo;
|
|
55
|
-
let exportStatement = `var ${name} =`;
|
|
56
|
-
if ('default' === name.toLowerCase()) exportStatement = 'default';
|
|
57
|
-
const upperHttpMethod = httpMethod.toUpperCase();
|
|
58
|
-
const operationSchemaHash = operationContracts[`${upperHttpMethod}:${routePath}`]?.schemaHash ?? '';
|
|
59
|
-
const operationContext = {
|
|
60
|
-
operationId: name,
|
|
61
|
-
routePath,
|
|
62
|
-
method: upperHttpMethod,
|
|
63
|
-
schemaHash: operationSchemaHash,
|
|
64
|
-
operationVersion
|
|
65
|
-
};
|
|
66
|
-
if ('upload' === action) {
|
|
67
|
-
hasUploadHandler = true;
|
|
68
|
-
const uploadOptions = {
|
|
69
|
-
path: routePath,
|
|
70
|
-
...domain ? {
|
|
71
|
-
domain
|
|
72
|
-
} : {},
|
|
73
|
-
...requestId ? {
|
|
74
|
-
requestId
|
|
75
|
-
} : {},
|
|
76
|
-
...requestId ? {
|
|
77
|
-
operationContext
|
|
78
|
-
} : {}
|
|
25
|
+
const draft = {
|
|
26
|
+
requestCreator: options.requestCreator || INNER_CLIENT_REQUEST_CREATOR,
|
|
27
|
+
imports: fetcher ? [
|
|
28
|
+
`import { fetch } from ${JSON.stringify(fetcher)};`
|
|
29
|
+
] : [],
|
|
30
|
+
statements: [],
|
|
31
|
+
handlers: handlerInfos.map((handlerInfo)=>{
|
|
32
|
+
const optionProperties = [
|
|
33
|
+
`path: ${JSON.stringify(handlerInfo.routePath)}`
|
|
34
|
+
];
|
|
35
|
+
if ('upload' !== handlerInfo.action) {
|
|
36
|
+
const portExpression = 'server' === target ? `process.env.PORT || ${String(port)}` : String(port);
|
|
37
|
+
optionProperties.push(`method: ${JSON.stringify(handlerInfo.httpMethod.toUpperCase())}`, `port: ${portExpression}`, `httpMethodDecider: ${JSON.stringify(httpMethodDecider || 'functionName')}`);
|
|
38
|
+
}
|
|
39
|
+
if (domain) optionProperties.push(`domain: ${JSON.stringify(domain)}`);
|
|
40
|
+
if (fetcher && 'upload' !== handlerInfo.action) optionProperties.push('fetch');
|
|
41
|
+
if (requestId) optionProperties.push(`requestId: ${JSON.stringify(requestId)}`);
|
|
42
|
+
return {
|
|
43
|
+
handlerInfo,
|
|
44
|
+
optionProperties
|
|
79
45
|
};
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
46
|
+
})
|
|
47
|
+
};
|
|
48
|
+
if (clientCodegenPlugin) try {
|
|
49
|
+
const specifier = clientCodegenPlugin.startsWith('.') ? __rspack_external_path.resolve(appDir, clientCodegenPlugin) : clientCodegenPlugin;
|
|
50
|
+
const resolved = requireResolve(specifier, {
|
|
51
|
+
paths: [
|
|
52
|
+
appDir
|
|
53
|
+
]
|
|
54
|
+
});
|
|
55
|
+
const extension = await import(pathToFileURL(resolved).href);
|
|
56
|
+
const modifyClient = extension.modifyClient ?? extension.default?.modifyClient;
|
|
57
|
+
if ('function' != typeof modifyClient) throw new TypeError('The module must export a modifyClient function.');
|
|
58
|
+
await modifyClient(draft, {
|
|
59
|
+
options,
|
|
60
|
+
handlerInfos
|
|
61
|
+
});
|
|
62
|
+
} catch (cause) {
|
|
63
|
+
throw new ClientCodegenError(clientCodegenPlugin, cause);
|
|
97
64
|
}
|
|
98
|
-
const
|
|
99
|
-
const
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
return
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
identityBinding: {
|
|
115
|
-
enabled: true,
|
|
116
|
-
strict: true,
|
|
117
|
-
},
|
|
118
|
-
operationContract: {
|
|
119
|
-
enabled: true,
|
|
120
|
-
strict: true,
|
|
121
|
-
requireSchemaHash: true,
|
|
122
|
-
requireOperationVersion: true,
|
|
123
|
-
},
|
|
124
|
-
};
|
|
125
|
-
return configure({
|
|
126
|
-
...defaultSecureOptions,
|
|
127
|
-
...options,
|
|
128
|
-
identityBinding: {
|
|
129
|
-
...defaultSecureOptions.identityBinding,
|
|
130
|
-
...(options && options.identityBinding ? options.identityBinding : {}),
|
|
131
|
-
},
|
|
132
|
-
operationContract: {
|
|
133
|
-
...defaultSecureOptions.operationContract,
|
|
134
|
-
...(options && options.operationContract ? options.operationContract : {}),
|
|
135
|
-
},
|
|
136
|
-
});
|
|
137
|
-
};
|
|
138
|
-
` : '';
|
|
139
|
-
const manifestCode = `export const operationVersion = ${String(operationVersion)};
|
|
140
|
-
export const operationSchemaHash = '${schemaHash}';
|
|
141
|
-
export const operationManifest = ${JSON.stringify({
|
|
142
|
-
operationVersion,
|
|
143
|
-
schemaHash,
|
|
144
|
-
operations: operationEntries
|
|
145
|
-
}, null, 2)};
|
|
146
|
-
`;
|
|
147
|
-
const generatedParts = [
|
|
148
|
-
importCode.trimEnd(),
|
|
149
|
-
bootstrapCode.trimEnd(),
|
|
150
|
-
manifestCode.trimEnd(),
|
|
151
|
-
handlersCode.trimEnd()
|
|
152
|
-
].filter(Boolean);
|
|
153
|
-
return Ok(`${generatedParts.join('\n\n')}
|
|
154
|
-
`);
|
|
65
|
+
const hasUploadHandler = handlerInfos.some((info)=>'upload' === info.action);
|
|
66
|
+
const requestImports = `createRequest${hasUploadHandler ? ', createUploader' : ''}`;
|
|
67
|
+
const importCode = [
|
|
68
|
+
`import { ${requestImports} } from ${JSON.stringify(draft.requestCreator)};`,
|
|
69
|
+
...draft.imports
|
|
70
|
+
].join('\n');
|
|
71
|
+
const handlersCode = draft.handlers.map(({ handlerInfo, optionProperties })=>{
|
|
72
|
+
const exportStatement = 'default' === handlerInfo.name.toLowerCase() ? 'default' : `var ${handlerInfo.name} =`;
|
|
73
|
+
const creator = 'upload' === handlerInfo.action ? 'createUploader' : 'createRequest';
|
|
74
|
+
return `export ${exportStatement} ${creator}({ ${optionProperties.join(', ')} });`;
|
|
75
|
+
}).join('\n');
|
|
76
|
+
return Ok(`${[
|
|
77
|
+
importCode,
|
|
78
|
+
...draft.statements,
|
|
79
|
+
handlersCode
|
|
80
|
+
].filter(Boolean).join('\n\n')}\n`);
|
|
155
81
|
};
|
|
156
|
-
export { INNER_CLIENT_REQUEST_CREATOR, generateClient };
|
|
82
|
+
export { ClientCodegenError, INNER_CLIENT_REQUEST_CREATOR, generateClient };
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
export * from "./adapter-kit/index.mjs";
|
|
2
1
|
export * from "./client/index.mjs";
|
|
3
2
|
export * from "./operators/http.mjs";
|
|
4
3
|
export * from "./router/index.mjs";
|
|
5
|
-
export * from "./security/crossProjectPolicy.mjs";
|
|
6
|
-
export * from "./security/operationContracts.mjs";
|
|
7
|
-
export * from "./security/resolveCrossProjectPolicy.mjs";
|
|
8
4
|
export * from "./types.mjs";
|
|
9
5
|
export { Api } from "./api.mjs";
|
|
10
6
|
export { HttpError, ValidationError } from "./errors/http.mjs";
|
|
11
|
-
export { HANDLER_WITH_META, INPUT_PARAMS_DECIDER, createStorage,
|
|
7
|
+
export { HANDLER_WITH_META, INPUT_PARAMS_DECIDER, createStorage, isInputParamsDeciderHandler, isWithMetaHandler } from "./utils/index.mjs";
|
|
@@ -88,10 +88,11 @@ class ApiRouter {
|
|
|
88
88
|
if ('test' !== process.env.NODE_ENV) logger.warn(`Only api handlers are allowd to be exported, please remove the function ${originHandlerName} from exports`);
|
|
89
89
|
return null;
|
|
90
90
|
}
|
|
91
|
+
} else {
|
|
92
|
+
if (!handler) return null;
|
|
93
|
+
if ('function' == typeof handler && handler.length > 0) return HttpMethod.Post;
|
|
94
|
+
return HttpMethod.Get;
|
|
91
95
|
}
|
|
92
|
-
if (!handler) return null;
|
|
93
|
-
if ('function' == typeof handler && handler.length > 0) return HttpMethod.Post;
|
|
94
|
-
return HttpMethod.Get;
|
|
95
96
|
}
|
|
96
97
|
getAction(handler) {
|
|
97
98
|
if (handler) {
|
|
@@ -140,9 +141,10 @@ class ApiRouter {
|
|
|
140
141
|
cause: err
|
|
141
142
|
});
|
|
142
143
|
throw error;
|
|
144
|
+
} else {
|
|
145
|
+
console.error(`Failed to load BFF module '${filename}':`, err);
|
|
146
|
+
return null;
|
|
143
147
|
}
|
|
144
|
-
console.error(`Failed to load BFF module '${filename}':`, err);
|
|
145
|
-
return null;
|
|
146
148
|
}
|
|
147
149
|
}
|
|
148
150
|
getHandlerInfos(moduleInfos) {
|
package/dist/esm/utils/index.mjs
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
import __rslib_shim_module__ from "node:module";
|
|
2
2
|
const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(/*#__PURE__*/ (()=>import.meta.url)());
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
3
4
|
import { ApiRouter } from "../router/index.mjs";
|
|
4
|
-
import { buildOperationContractMap, createOperationSchemaHash, deriveOperationVersion } from "../security/operationContracts.mjs";
|
|
5
5
|
import { Err, Ok } from "./result.mjs";
|
|
6
6
|
import * as __rspack_external_path from "path";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
version: packageJson.version
|
|
14
|
-
};
|
|
15
|
-
} catch (error) {
|
|
16
|
-
return {};
|
|
7
|
+
class ClientCodegenError extends Error {
|
|
8
|
+
constructor(plugin, cause){
|
|
9
|
+
super(`BFF client code-generation plugin failed: ${plugin}`, {
|
|
10
|
+
cause
|
|
11
|
+
});
|
|
12
|
+
this.name = 'ClientCodegenError';
|
|
17
13
|
}
|
|
18
|
-
}
|
|
14
|
+
}
|
|
19
15
|
const INNER_CLIENT_REQUEST_CREATOR = '@modern-js/plugin-bff/client';
|
|
20
|
-
const generateClient = async (
|
|
21
|
-
|
|
16
|
+
const generateClient = async (options)=>{
|
|
17
|
+
const { appDir, resourcePath, apiDir, lambdaDir, prefix, port, target, fetcher, requireResolve = require.resolve, httpMethodDecider, domain, requestId, clientCodegenPlugin } = options;
|
|
22
18
|
const apiRouter = new ApiRouter({
|
|
23
19
|
appDir,
|
|
24
20
|
apiDir,
|
|
@@ -28,131 +24,61 @@ const generateClient = async ({ appDir, resourcePath, apiDir, lambdaDir, prefix,
|
|
|
28
24
|
});
|
|
29
25
|
const handlerInfos = await apiRouter.getSingleModuleHandlers(resourcePath);
|
|
30
26
|
if (!handlerInfos) return Err(`generate client error: Cannot require module ${resourcePath}`);
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
});
|
|
52
|
-
const schemaHash = createOperationSchemaHash(operationEntries, normalizedRequestId);
|
|
53
|
-
let hasUploadHandler = false;
|
|
54
|
-
let handlersCode = '';
|
|
55
|
-
for (const handlerInfo of handlerInfos){
|
|
56
|
-
const { name, httpMethod, routePath, action } = handlerInfo;
|
|
57
|
-
let exportStatement = `var ${name} =`;
|
|
58
|
-
if ('default' === name.toLowerCase()) exportStatement = 'default';
|
|
59
|
-
const upperHttpMethod = httpMethod.toUpperCase();
|
|
60
|
-
const operationSchemaHash = operationContracts[`${upperHttpMethod}:${routePath}`]?.schemaHash ?? '';
|
|
61
|
-
const operationContext = {
|
|
62
|
-
operationId: name,
|
|
63
|
-
routePath,
|
|
64
|
-
method: upperHttpMethod,
|
|
65
|
-
schemaHash: operationSchemaHash,
|
|
66
|
-
operationVersion
|
|
67
|
-
};
|
|
68
|
-
if ('upload' === action) {
|
|
69
|
-
hasUploadHandler = true;
|
|
70
|
-
const uploadOptions = {
|
|
71
|
-
path: routePath,
|
|
72
|
-
...domain ? {
|
|
73
|
-
domain
|
|
74
|
-
} : {},
|
|
75
|
-
...requestId ? {
|
|
76
|
-
requestId
|
|
77
|
-
} : {},
|
|
78
|
-
...requestId ? {
|
|
79
|
-
operationContext
|
|
80
|
-
} : {}
|
|
27
|
+
const draft = {
|
|
28
|
+
requestCreator: options.requestCreator || INNER_CLIENT_REQUEST_CREATOR,
|
|
29
|
+
imports: fetcher ? [
|
|
30
|
+
`import { fetch } from ${JSON.stringify(fetcher)};`
|
|
31
|
+
] : [],
|
|
32
|
+
statements: [],
|
|
33
|
+
handlers: handlerInfos.map((handlerInfo)=>{
|
|
34
|
+
const optionProperties = [
|
|
35
|
+
`path: ${JSON.stringify(handlerInfo.routePath)}`
|
|
36
|
+
];
|
|
37
|
+
if ('upload' !== handlerInfo.action) {
|
|
38
|
+
const portExpression = 'server' === target ? `process.env.PORT || ${String(port)}` : String(port);
|
|
39
|
+
optionProperties.push(`method: ${JSON.stringify(handlerInfo.httpMethod.toUpperCase())}`, `port: ${portExpression}`, `httpMethodDecider: ${JSON.stringify(httpMethodDecider || 'functionName')}`);
|
|
40
|
+
}
|
|
41
|
+
if (domain) optionProperties.push(`domain: ${JSON.stringify(domain)}`);
|
|
42
|
+
if (fetcher && 'upload' !== handlerInfo.action) optionProperties.push('fetch');
|
|
43
|
+
if (requestId) optionProperties.push(`requestId: ${JSON.stringify(requestId)}`);
|
|
44
|
+
return {
|
|
45
|
+
handlerInfo,
|
|
46
|
+
optionProperties
|
|
81
47
|
};
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
48
|
+
})
|
|
49
|
+
};
|
|
50
|
+
if (clientCodegenPlugin) try {
|
|
51
|
+
const specifier = clientCodegenPlugin.startsWith('.') ? __rspack_external_path.resolve(appDir, clientCodegenPlugin) : clientCodegenPlugin;
|
|
52
|
+
const resolved = requireResolve(specifier, {
|
|
53
|
+
paths: [
|
|
54
|
+
appDir
|
|
55
|
+
]
|
|
56
|
+
});
|
|
57
|
+
const extension = await import(pathToFileURL(resolved).href);
|
|
58
|
+
const modifyClient = extension.modifyClient ?? extension.default?.modifyClient;
|
|
59
|
+
if ('function' != typeof modifyClient) throw new TypeError('The module must export a modifyClient function.');
|
|
60
|
+
await modifyClient(draft, {
|
|
61
|
+
options,
|
|
62
|
+
handlerInfos
|
|
63
|
+
});
|
|
64
|
+
} catch (cause) {
|
|
65
|
+
throw new ClientCodegenError(clientCodegenPlugin, cause);
|
|
99
66
|
}
|
|
100
|
-
const
|
|
101
|
-
const
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
return
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
identityBinding: {
|
|
117
|
-
enabled: true,
|
|
118
|
-
strict: true,
|
|
119
|
-
},
|
|
120
|
-
operationContract: {
|
|
121
|
-
enabled: true,
|
|
122
|
-
strict: true,
|
|
123
|
-
requireSchemaHash: true,
|
|
124
|
-
requireOperationVersion: true,
|
|
125
|
-
},
|
|
126
|
-
};
|
|
127
|
-
return configure({
|
|
128
|
-
...defaultSecureOptions,
|
|
129
|
-
...options,
|
|
130
|
-
identityBinding: {
|
|
131
|
-
...defaultSecureOptions.identityBinding,
|
|
132
|
-
...(options && options.identityBinding ? options.identityBinding : {}),
|
|
133
|
-
},
|
|
134
|
-
operationContract: {
|
|
135
|
-
...defaultSecureOptions.operationContract,
|
|
136
|
-
...(options && options.operationContract ? options.operationContract : {}),
|
|
137
|
-
},
|
|
138
|
-
});
|
|
139
|
-
};
|
|
140
|
-
` : '';
|
|
141
|
-
const manifestCode = `export const operationVersion = ${String(operationVersion)};
|
|
142
|
-
export const operationSchemaHash = '${schemaHash}';
|
|
143
|
-
export const operationManifest = ${JSON.stringify({
|
|
144
|
-
operationVersion,
|
|
145
|
-
schemaHash,
|
|
146
|
-
operations: operationEntries
|
|
147
|
-
}, null, 2)};
|
|
148
|
-
`;
|
|
149
|
-
const generatedParts = [
|
|
150
|
-
importCode.trimEnd(),
|
|
151
|
-
bootstrapCode.trimEnd(),
|
|
152
|
-
manifestCode.trimEnd(),
|
|
153
|
-
handlersCode.trimEnd()
|
|
154
|
-
].filter(Boolean);
|
|
155
|
-
return Ok(`${generatedParts.join('\n\n')}
|
|
156
|
-
`);
|
|
67
|
+
const hasUploadHandler = handlerInfos.some((info)=>'upload' === info.action);
|
|
68
|
+
const requestImports = `createRequest${hasUploadHandler ? ', createUploader' : ''}`;
|
|
69
|
+
const importCode = [
|
|
70
|
+
`import { ${requestImports} } from ${JSON.stringify(draft.requestCreator)};`,
|
|
71
|
+
...draft.imports
|
|
72
|
+
].join('\n');
|
|
73
|
+
const handlersCode = draft.handlers.map(({ handlerInfo, optionProperties })=>{
|
|
74
|
+
const exportStatement = 'default' === handlerInfo.name.toLowerCase() ? 'default' : `var ${handlerInfo.name} =`;
|
|
75
|
+
const creator = 'upload' === handlerInfo.action ? 'createUploader' : 'createRequest';
|
|
76
|
+
return `export ${exportStatement} ${creator}({ ${optionProperties.join(', ')} });`;
|
|
77
|
+
}).join('\n');
|
|
78
|
+
return Ok(`${[
|
|
79
|
+
importCode,
|
|
80
|
+
...draft.statements,
|
|
81
|
+
handlersCode
|
|
82
|
+
].filter(Boolean).join('\n\n')}\n`);
|
|
157
83
|
};
|
|
158
|
-
export { INNER_CLIENT_REQUEST_CREATOR, generateClient };
|
|
84
|
+
export { ClientCodegenError, INNER_CLIENT_REQUEST_CREATOR, generateClient };
|
package/dist/esm-node/index.mjs
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
export * from "./adapter-kit/index.mjs";
|
|
3
2
|
export * from "./client/index.mjs";
|
|
4
3
|
export * from "./operators/http.mjs";
|
|
5
4
|
export * from "./router/index.mjs";
|
|
6
|
-
export * from "./security/crossProjectPolicy.mjs";
|
|
7
|
-
export * from "./security/operationContracts.mjs";
|
|
8
|
-
export * from "./security/resolveCrossProjectPolicy.mjs";
|
|
9
5
|
export * from "./types.mjs";
|
|
10
6
|
export { Api } from "./api.mjs";
|
|
11
7
|
export { HttpError, ValidationError } from "./errors/http.mjs";
|
|
12
|
-
export { HANDLER_WITH_META, INPUT_PARAMS_DECIDER, createStorage,
|
|
8
|
+
export { HANDLER_WITH_META, INPUT_PARAMS_DECIDER, createStorage, isInputParamsDeciderHandler, isWithMetaHandler } from "./utils/index.mjs";
|
|
@@ -89,10 +89,11 @@ class ApiRouter {
|
|
|
89
89
|
if ('test' !== process.env.NODE_ENV) logger.warn(`Only api handlers are allowd to be exported, please remove the function ${originHandlerName} from exports`);
|
|
90
90
|
return null;
|
|
91
91
|
}
|
|
92
|
+
} else {
|
|
93
|
+
if (!handler) return null;
|
|
94
|
+
if ('function' == typeof handler && handler.length > 0) return HttpMethod.Post;
|
|
95
|
+
return HttpMethod.Get;
|
|
92
96
|
}
|
|
93
|
-
if (!handler) return null;
|
|
94
|
-
if ('function' == typeof handler && handler.length > 0) return HttpMethod.Post;
|
|
95
|
-
return HttpMethod.Get;
|
|
96
97
|
}
|
|
97
98
|
getAction(handler) {
|
|
98
99
|
if (handler) {
|
|
@@ -141,9 +142,10 @@ class ApiRouter {
|
|
|
141
142
|
cause: err
|
|
142
143
|
});
|
|
143
144
|
throw error;
|
|
145
|
+
} else {
|
|
146
|
+
console.error(`Failed to load BFF module '${filename}':`, err);
|
|
147
|
+
return null;
|
|
144
148
|
}
|
|
145
|
-
console.error(`Failed to load BFF module '${filename}':`, err);
|
|
146
|
-
return null;
|
|
147
149
|
}
|
|
148
150
|
}
|
|
149
151
|
getHandlerInfos(moduleInfos) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { HttpMethodDecider } from '@modern-js/types';
|
|
2
|
+
import { type APIHandlerInfo } from '../router/index.js';
|
|
2
3
|
import { type Result } from './result.js';
|
|
3
4
|
export type GenClientResult = Result<string>;
|
|
4
5
|
export type GenClientOptions = {
|
|
@@ -16,6 +17,28 @@ export type GenClientOptions = {
|
|
|
16
17
|
httpMethodDecider?: HttpMethodDecider;
|
|
17
18
|
domain?: string;
|
|
18
19
|
requestId?: string;
|
|
20
|
+
/** Node module exporting a modifyClient code-generation transform. */
|
|
21
|
+
clientCodegenPlugin?: string;
|
|
19
22
|
};
|
|
23
|
+
export interface ClientHandlerDraft {
|
|
24
|
+
readonly handlerInfo: APIHandlerInfo;
|
|
25
|
+
/** Source expressions, including native server port and fetch bindings. */
|
|
26
|
+
optionProperties: string[];
|
|
27
|
+
}
|
|
28
|
+
export interface ClientModuleDraft {
|
|
29
|
+
requestCreator: string;
|
|
30
|
+
imports: string[];
|
|
31
|
+
statements: string[];
|
|
32
|
+
readonly handlers: readonly ClientHandlerDraft[];
|
|
33
|
+
}
|
|
34
|
+
export interface ClientCodegenContext {
|
|
35
|
+
readonly options: Readonly<GenClientOptions>;
|
|
36
|
+
readonly handlerInfos: readonly APIHandlerInfo[];
|
|
37
|
+
}
|
|
38
|
+
export type ClientCodegenPlugin = (draft: ClientModuleDraft, context: ClientCodegenContext) => void | Promise<void>;
|
|
39
|
+
/** A failed transform must not be downgraded to best-effort publication. */
|
|
40
|
+
export declare class ClientCodegenError extends Error {
|
|
41
|
+
constructor(plugin: string, cause: unknown);
|
|
42
|
+
}
|
|
20
43
|
export declare const INNER_CLIENT_REQUEST_CREATOR = "@modern-js/plugin-bff/client";
|
|
21
|
-
export declare const generateClient: (
|
|
44
|
+
export declare const generateClient: (options: GenClientOptions) => Promise<GenClientResult>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
export * from './adapter-kit/index.js';
|
|
2
1
|
export { Api } from './api.js';
|
|
3
2
|
export * from './client/index.js';
|
|
4
3
|
export type * from './compatible.js';
|
|
5
4
|
export { HttpError, ValidationError } from './errors/http.js';
|
|
6
5
|
export * from './operators/http.js';
|
|
7
6
|
export * from './router/index.js';
|
|
8
|
-
export * from './security/crossProjectPolicy.js';
|
|
9
|
-
export * from './security/operationContracts.js';
|
|
10
|
-
export * from './security/resolveCrossProjectPolicy.js';
|
|
11
7
|
export * from './types.js';
|
|
12
|
-
export { createStorage,
|
|
8
|
+
export { createStorage, HANDLER_WITH_META, INPUT_PARAMS_DECIDER, isInputParamsDeciderHandler, isWithMetaHandler, } from './utils/index.js';
|