@bleedingdev/modern-js-plugin-bff 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.
- package/LICENSE +21 -0
- package/README.md +26 -0
- package/cli.js +1 -0
- package/dist/cjs/cli.js +294 -0
- package/dist/cjs/constants.js +48 -0
- package/dist/cjs/index.js +58 -0
- package/dist/cjs/loader.js +106 -0
- package/dist/cjs/runtime/create-request/index.js +48 -0
- package/dist/cjs/runtime/data-platform/index.js +693 -0
- package/dist/cjs/runtime/effect/adapter.js +311 -0
- package/dist/cjs/runtime/effect/context.js +48 -0
- package/dist/cjs/runtime/effect/index.js +608 -0
- package/dist/cjs/runtime/effect-client/index.js +178 -0
- package/dist/cjs/runtime/hono/adapter.js +168 -0
- package/dist/cjs/runtime/hono/index.js +65 -0
- package/dist/cjs/runtime/hono/operators.js +68 -0
- package/dist/cjs/server.js +179 -0
- package/dist/cjs/utils/clientGenerator.js +342 -0
- package/dist/cjs/utils/createHonoRoutes.js +138 -0
- package/dist/cjs/utils/crossProjectApiPlugin.js +118 -0
- package/dist/cjs/utils/effectClientGenerator.js +673 -0
- package/dist/cjs/utils/pluginGenerator.js +73 -0
- package/dist/cjs/utils/runtimeGenerator.js +133 -0
- package/dist/esm/cli.mjs +245 -0
- package/dist/esm/constants.mjs +11 -0
- package/dist/esm/index.mjs +1 -0
- package/dist/esm/loader.mjs +62 -0
- package/dist/esm/runtime/create-request/index.mjs +1 -0
- package/dist/esm/runtime/data-platform/index.mjs +599 -0
- package/dist/esm/runtime/effect/adapter.mjs +267 -0
- package/dist/esm/runtime/effect/context.mjs +11 -0
- package/dist/esm/runtime/effect/index.mjs +438 -0
- package/dist/esm/runtime/effect-client/index.mjs +90 -0
- package/dist/esm/runtime/hono/adapter.mjs +124 -0
- package/dist/esm/runtime/hono/index.mjs +2 -0
- package/dist/esm/runtime/hono/operators.mjs +31 -0
- package/dist/esm/server.mjs +135 -0
- package/dist/esm/utils/clientGenerator.mjs +293 -0
- package/dist/esm/utils/createHonoRoutes.mjs +92 -0
- package/dist/esm/utils/crossProjectApiPlugin.mjs +54 -0
- package/dist/esm/utils/effectClientGenerator.mjs +623 -0
- package/dist/esm/utils/pluginGenerator.mjs +29 -0
- package/dist/esm/utils/runtimeGenerator.mjs +89 -0
- package/dist/esm-node/cli.mjs +249 -0
- package/dist/esm-node/constants.mjs +12 -0
- package/dist/esm-node/index.mjs +2 -0
- package/dist/esm-node/loader.mjs +64 -0
- package/dist/esm-node/runtime/create-request/index.mjs +2 -0
- package/dist/esm-node/runtime/data-platform/index.mjs +600 -0
- package/dist/esm-node/runtime/effect/adapter.mjs +269 -0
- package/dist/esm-node/runtime/effect/context.mjs +12 -0
- package/dist/esm-node/runtime/effect/index.mjs +439 -0
- package/dist/esm-node/runtime/effect-client/index.mjs +91 -0
- package/dist/esm-node/runtime/hono/adapter.mjs +125 -0
- package/dist/esm-node/runtime/hono/index.mjs +3 -0
- package/dist/esm-node/runtime/hono/operators.mjs +32 -0
- package/dist/esm-node/server.mjs +136 -0
- package/dist/esm-node/utils/clientGenerator.mjs +294 -0
- package/dist/esm-node/utils/createHonoRoutes.mjs +93 -0
- package/dist/esm-node/utils/crossProjectApiPlugin.mjs +55 -0
- package/dist/esm-node/utils/effectClientGenerator.mjs +625 -0
- package/dist/esm-node/utils/pluginGenerator.mjs +33 -0
- package/dist/esm-node/utils/runtimeGenerator.mjs +91 -0
- package/dist/types/cli.d.ts +3 -0
- package/dist/types/constants.d.ts +2 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/loader.d.ts +27 -0
- package/dist/types/runtime/create-request/index.d.ts +2 -0
- package/dist/types/runtime/data-platform/index.d.ts +187 -0
- package/dist/types/runtime/effect/adapter.d.ts +22 -0
- package/dist/types/runtime/effect/context.d.ts +8 -0
- package/dist/types/runtime/effect/index.d.ts +171 -0
- package/dist/types/runtime/effect-client/index.d.ts +47 -0
- package/dist/types/runtime/hono/adapter.d.ts +19 -0
- package/dist/types/runtime/hono/index.d.ts +2 -0
- package/dist/types/runtime/hono/operators.d.ts +10 -0
- package/dist/types/server.d.ts +3 -0
- package/dist/types/utils/clientGenerator.d.ts +37 -0
- package/dist/types/utils/createHonoRoutes.d.ts +10 -0
- package/dist/types/utils/crossProjectApiPlugin.d.ts +9 -0
- package/dist/types/utils/effectClientGenerator.d.ts +27 -0
- package/dist/types/utils/pluginGenerator.d.ts +9 -0
- package/dist/types/utils/runtimeGenerator.d.ts +7 -0
- package/docs/data-platform-architecture.md +61 -0
- package/package.json +172 -0
- package/rslib.config.mts +4 -0
- package/rstest.config.mts +10 -0
- package/server.js +1 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { fs } from "@modern-js/utils";
|
|
2
|
+
import path from "path";
|
|
3
|
+
const getPackageName = (appDirectory)=>{
|
|
4
|
+
try {
|
|
5
|
+
const packageJsonPath = path.resolve(appDirectory, './package.json');
|
|
6
|
+
const packageJson = require(packageJsonPath);
|
|
7
|
+
return packageJson.name;
|
|
8
|
+
} catch (error) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
async function runtimeGenerator({ runtime, appDirectory, relativeDistPath, packageName }) {
|
|
13
|
+
const pluginDir = path.resolve(appDirectory, `./${relativeDistPath}`, 'runtime');
|
|
14
|
+
const requestId = packageName || getPackageName(appDirectory) || process.env.npm_package_name || 'default';
|
|
15
|
+
const runtimeImportPath = JSON.stringify(runtime);
|
|
16
|
+
const requestIdValue = JSON.stringify(requestId);
|
|
17
|
+
const source = `const { configure: _configure } = require(${runtimeImportPath});
|
|
18
|
+
const defaultSecureOptions = {
|
|
19
|
+
requestId: ${requestIdValue},
|
|
20
|
+
requireEnvelope: true,
|
|
21
|
+
identityBinding: {
|
|
22
|
+
enabled: true,
|
|
23
|
+
strict: true,
|
|
24
|
+
},
|
|
25
|
+
operationContract: {
|
|
26
|
+
enabled: true,
|
|
27
|
+
strict: true,
|
|
28
|
+
requireSchemaHash: true,
|
|
29
|
+
requireOperationVersion: true,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
const initProducerClient = (options) => {
|
|
33
|
+
return _configure({
|
|
34
|
+
...defaultSecureOptions,
|
|
35
|
+
...options,
|
|
36
|
+
identityBinding: {
|
|
37
|
+
...defaultSecureOptions.identityBinding,
|
|
38
|
+
...(options && options.identityBinding ? options.identityBinding : {}),
|
|
39
|
+
},
|
|
40
|
+
operationContract: {
|
|
41
|
+
...defaultSecureOptions.operationContract,
|
|
42
|
+
...(options && options.operationContract ? options.operationContract : {}),
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
const configure = initProducerClient;
|
|
47
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
48
|
+
exports.initProducerClient = initProducerClient;
|
|
49
|
+
exports.configure = configure;
|
|
50
|
+
`;
|
|
51
|
+
const pluginPath = path.join(pluginDir, 'index.js');
|
|
52
|
+
await fs.ensureFile(pluginPath);
|
|
53
|
+
await fs.writeFile(pluginPath, source);
|
|
54
|
+
const tsSource = `type ProducerRuntimeModule = typeof import(${runtimeImportPath});
|
|
55
|
+
type ProducerClientOptions = ProducerRuntimeModule extends {
|
|
56
|
+
configure: (options: infer TOptions) => unknown;
|
|
57
|
+
}
|
|
58
|
+
? TOptions
|
|
59
|
+
: {
|
|
60
|
+
request?: typeof fetch;
|
|
61
|
+
interceptor?: (request: typeof fetch) => typeof fetch;
|
|
62
|
+
allowedHeaders?: string[];
|
|
63
|
+
requireEnvelope?: boolean;
|
|
64
|
+
allowCrossOriginEnvelope?: boolean;
|
|
65
|
+
identityBinding?: {
|
|
66
|
+
enabled?: boolean;
|
|
67
|
+
strict?: boolean;
|
|
68
|
+
protectedHeaders?: string[];
|
|
69
|
+
};
|
|
70
|
+
operationContract?: {
|
|
71
|
+
enabled?: boolean;
|
|
72
|
+
strict?: boolean;
|
|
73
|
+
requireSchemaHash?: boolean;
|
|
74
|
+
requireOperationVersion?: boolean;
|
|
75
|
+
};
|
|
76
|
+
setDomain?: (ops?: {
|
|
77
|
+
target: 'server' | 'browser';
|
|
78
|
+
requestId?: string;
|
|
79
|
+
}) => string;
|
|
80
|
+
requestId?: string;
|
|
81
|
+
};
|
|
82
|
+
export declare const initProducerClient: (options: ProducerClientOptions) => void;
|
|
83
|
+
export declare const configure: typeof initProducerClient;`;
|
|
84
|
+
const pluginTypePath = path.join(pluginDir, 'index.d.ts');
|
|
85
|
+
await fs.ensureFile(pluginTypePath);
|
|
86
|
+
await fs.writeFile(pluginTypePath, tsSource);
|
|
87
|
+
}
|
|
88
|
+
const utils_runtimeGenerator = runtimeGenerator;
|
|
89
|
+
export default utils_runtimeGenerator;
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { ApiRouter } from "@modern-js/bff-core";
|
|
3
|
+
import { compile } from "@modern-js/server-utils";
|
|
4
|
+
import { API_DIR, DEFAULT_API_PREFIX, SHARED_DIR, fs, normalizeOutputPath, resolveServerTsconfig } from "@modern-js/utils";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import clientGenerator from "./utils/clientGenerator.mjs";
|
|
7
|
+
import pluginGenerator from "./utils/pluginGenerator.mjs";
|
|
8
|
+
import runtimeGenerator from "./utils/runtimeGenerator.mjs";
|
|
9
|
+
import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
|
|
10
|
+
import { dirname as __rspack_dirname } from "node:path";
|
|
11
|
+
var cli_dirname = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
|
|
12
|
+
const RUNTIME_CREATE_REQUEST = '@modern-js/plugin-bff/client';
|
|
13
|
+
const WATCHABLE_EXTENSIONS = [
|
|
14
|
+
'.ts',
|
|
15
|
+
'.tsx',
|
|
16
|
+
'.js',
|
|
17
|
+
'.jsx',
|
|
18
|
+
'.mts',
|
|
19
|
+
'.cts',
|
|
20
|
+
'.mjs',
|
|
21
|
+
'.cjs',
|
|
22
|
+
'.json'
|
|
23
|
+
];
|
|
24
|
+
const isWatchableBffFile = (filename)=>WATCHABLE_EXTENSIONS.some((ext)=>filename.endsWith(ext));
|
|
25
|
+
const normalizePrefixList = (prefix)=>{
|
|
26
|
+
if (Array.isArray(prefix)) return prefix.filter(Boolean);
|
|
27
|
+
return [
|
|
28
|
+
prefix || DEFAULT_API_PREFIX
|
|
29
|
+
];
|
|
30
|
+
};
|
|
31
|
+
const getPrimaryPrefix = (prefix)=>normalizePrefixList(prefix)[0] || DEFAULT_API_PREFIX;
|
|
32
|
+
const bffPlugin = ()=>({
|
|
33
|
+
name: '@modern-js/plugin-bff',
|
|
34
|
+
setup: (api)=>{
|
|
35
|
+
{
|
|
36
|
+
const appContext = api.getAppContext();
|
|
37
|
+
const userRuntimeFramework = api.getConfig()?.bff?.runtimeFramework;
|
|
38
|
+
api.updateAppContext({
|
|
39
|
+
...appContext,
|
|
40
|
+
bffRuntimeFramework: 'hono' === userRuntimeFramework ? 'hono' : 'effect'
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const compileApi = async ()=>{
|
|
44
|
+
const { appDirectory, distDirectory, apiDirectory, sharedDirectory, moduleType } = api.getAppContext();
|
|
45
|
+
const modernConfig = api.getNormalizedConfig();
|
|
46
|
+
const distDir = path.resolve(distDirectory);
|
|
47
|
+
const apiDir = apiDirectory || path.resolve(appDirectory, API_DIR);
|
|
48
|
+
const sharedDir = sharedDirectory || path.resolve(appDirectory, SHARED_DIR);
|
|
49
|
+
const tsconfigPath = resolveServerTsconfig(appDirectory, modernConfig?.server?.tsconfigPath);
|
|
50
|
+
const sourceDirs = [];
|
|
51
|
+
if (await fs.pathExists(apiDir)) sourceDirs.push(apiDir);
|
|
52
|
+
if (await fs.pathExists(sharedDir)) sourceDirs.push(sharedDir);
|
|
53
|
+
const { alias } = modernConfig.source;
|
|
54
|
+
const { alias: resolveAlias } = modernConfig.resolve;
|
|
55
|
+
if (sourceDirs.length > 0) {
|
|
56
|
+
const combinedAlias = [].concat(alias ?? []).concat(resolveAlias ?? []);
|
|
57
|
+
await compile(appDirectory, {
|
|
58
|
+
alias: combinedAlias
|
|
59
|
+
}, {
|
|
60
|
+
sourceDirs,
|
|
61
|
+
distDir,
|
|
62
|
+
tsconfigPath,
|
|
63
|
+
moduleType,
|
|
64
|
+
throwErrorInsteadOfExit: true
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const generator = async ()=>{
|
|
69
|
+
const { appDirectory, apiDirectory, lambdaDirectory, port, bffRuntimeFramework } = api.getAppContext();
|
|
70
|
+
const modernConfig = api.getNormalizedConfig();
|
|
71
|
+
const relativeDistPath = modernConfig?.output?.distPath?.root || 'dist';
|
|
72
|
+
const { bff } = modernConfig || {};
|
|
73
|
+
const prefix = getPrimaryPrefix(bff?.prefix);
|
|
74
|
+
const httpMethodDecider = bff?.httpMethodDecider;
|
|
75
|
+
const apiRouter = new ApiRouter({
|
|
76
|
+
apiDir: apiDirectory,
|
|
77
|
+
appDir: appDirectory,
|
|
78
|
+
lambdaDir: lambdaDirectory,
|
|
79
|
+
prefix,
|
|
80
|
+
httpMethodDecider,
|
|
81
|
+
isBuild: true
|
|
82
|
+
});
|
|
83
|
+
const lambdaDir = apiRouter.getLambdaDir();
|
|
84
|
+
const existLambda = apiRouter.isExistLambda();
|
|
85
|
+
const runtime = bff?.runtimeCreateRequest || RUNTIME_CREATE_REQUEST;
|
|
86
|
+
const relativeApiPath = path.relative(appDirectory, apiDirectory);
|
|
87
|
+
const relativeLambdaPath = path.relative(appDirectory, lambdaDir);
|
|
88
|
+
await pluginGenerator({
|
|
89
|
+
prefix,
|
|
90
|
+
appDirectory,
|
|
91
|
+
relativeDistPath,
|
|
92
|
+
relativeApiPath,
|
|
93
|
+
relativeLambdaPath,
|
|
94
|
+
runtimeFramework: 'hono' === bffRuntimeFramework ? 'hono' : 'effect'
|
|
95
|
+
});
|
|
96
|
+
await clientGenerator({
|
|
97
|
+
prefix,
|
|
98
|
+
appDir: appDirectory,
|
|
99
|
+
apiDir: apiDirectory,
|
|
100
|
+
lambdaDir,
|
|
101
|
+
existLambda,
|
|
102
|
+
port,
|
|
103
|
+
requestCreator: bff?.requestCreator,
|
|
104
|
+
httpMethodDecider,
|
|
105
|
+
relativeDistPath,
|
|
106
|
+
relativeApiPath,
|
|
107
|
+
bffRuntimeFramework,
|
|
108
|
+
effectEntry: bff?.effect?.entry,
|
|
109
|
+
effectDataPlatformBatch: bff?.effect?.dataPlatform?.batch
|
|
110
|
+
});
|
|
111
|
+
await runtimeGenerator({
|
|
112
|
+
runtime,
|
|
113
|
+
appDirectory,
|
|
114
|
+
relativeDistPath
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
const handleCrossProjectInvocation = async (isBuild = false)=>{
|
|
118
|
+
const { bff } = api.getNormalizedConfig();
|
|
119
|
+
if (bff?.crossProject) {
|
|
120
|
+
if (!isBuild) await compileApi();
|
|
121
|
+
await generator();
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
const isHono = ()=>{
|
|
125
|
+
const { bffRuntimeFramework } = api.getAppContext();
|
|
126
|
+
return 'hono' === bffRuntimeFramework;
|
|
127
|
+
};
|
|
128
|
+
const createCompressConfig = (devServer, prefix)=>{
|
|
129
|
+
if (!devServer || 'object' != typeof devServer || Array.isArray(devServer)) return;
|
|
130
|
+
const { compress } = devServer;
|
|
131
|
+
if (void 0 === compress || true === compress) {
|
|
132
|
+
const prefixes = normalizePrefixList(prefix);
|
|
133
|
+
return {
|
|
134
|
+
filter: (req)=>!prefixes.some((item)=>req.url?.includes(item))
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
if (false === compress) return false;
|
|
138
|
+
return compress;
|
|
139
|
+
};
|
|
140
|
+
api.config(async ()=>{
|
|
141
|
+
const devServer = api.getConfig()?.tools?.devServer;
|
|
142
|
+
const prefix = api.getConfig()?.bff?.prefix || DEFAULT_API_PREFIX;
|
|
143
|
+
const compress = createCompressConfig(devServer, prefix);
|
|
144
|
+
return {
|
|
145
|
+
tools: {
|
|
146
|
+
devServer: {
|
|
147
|
+
compress
|
|
148
|
+
},
|
|
149
|
+
bundlerChain: (chain, { CHAIN_ID, isServer })=>{
|
|
150
|
+
const { port, appDirectory, apiDirectory, lambdaDirectory, bffRuntimeFramework } = api.getAppContext();
|
|
151
|
+
const modernConfig = api.getNormalizedConfig();
|
|
152
|
+
const { bff } = modernConfig || {};
|
|
153
|
+
const prefix = getPrimaryPrefix(bff?.prefix);
|
|
154
|
+
const httpMethodDecider = bff?.httpMethodDecider;
|
|
155
|
+
const apiRouter = new ApiRouter({
|
|
156
|
+
apiDir: apiDirectory,
|
|
157
|
+
appDir: appDirectory,
|
|
158
|
+
lambdaDir: lambdaDirectory,
|
|
159
|
+
prefix,
|
|
160
|
+
httpMethodDecider,
|
|
161
|
+
isBuild: true
|
|
162
|
+
});
|
|
163
|
+
const lambdaDir = apiRouter.getLambdaDir();
|
|
164
|
+
const existLambda = apiRouter.isExistLambda();
|
|
165
|
+
const apiRegexp = new RegExp(normalizeOutputPath(`${apiDirectory}${path.sep}.*(.[tj]s)$`));
|
|
166
|
+
const name = isServer ? 'server' : 'client';
|
|
167
|
+
const sourceExt = 'mjs';
|
|
168
|
+
const loaderPath = path.join(cli_dirname, `loader.${sourceExt}`);
|
|
169
|
+
chain.module.rule(CHAIN_ID.RULE.JS).exclude.add(apiRegexp);
|
|
170
|
+
chain.module.rule('js-bff-api').test(apiRegexp).use('custom-loader').loader(loaderPath.replace(/\\/g, '/')).options({
|
|
171
|
+
prefix,
|
|
172
|
+
appDir: appDirectory,
|
|
173
|
+
apiDir: apiDirectory,
|
|
174
|
+
lambdaDir,
|
|
175
|
+
existLambda,
|
|
176
|
+
port,
|
|
177
|
+
target: name,
|
|
178
|
+
requestCreator: bff?.requestCreator,
|
|
179
|
+
httpMethodDecider,
|
|
180
|
+
bffRuntimeFramework,
|
|
181
|
+
effectEntry: bff?.effect?.entry,
|
|
182
|
+
effectDataPlatformBatch: bff?.effect?.dataPlatform?.batch
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
});
|
|
188
|
+
api.modifyServerRoutes(({ routes })=>{
|
|
189
|
+
const modernConfig = api.getNormalizedConfig();
|
|
190
|
+
const { bff } = modernConfig || {};
|
|
191
|
+
const prefix = bff?.prefix || '/api';
|
|
192
|
+
const prefixList = [];
|
|
193
|
+
if (Array.isArray(prefix)) prefixList.push(...prefix);
|
|
194
|
+
else prefixList.push(prefix);
|
|
195
|
+
const apiServerRoutes = prefixList.map((pre)=>({
|
|
196
|
+
urlPath: pre,
|
|
197
|
+
isApi: true,
|
|
198
|
+
entryPath: '',
|
|
199
|
+
isSPA: false,
|
|
200
|
+
isSSR: false
|
|
201
|
+
}));
|
|
202
|
+
if (!isHono() && bff?.enableHandleWeb) return {
|
|
203
|
+
routes: routes.map((route)=>({
|
|
204
|
+
...route,
|
|
205
|
+
isApi: true
|
|
206
|
+
})).concat(apiServerRoutes)
|
|
207
|
+
};
|
|
208
|
+
return {
|
|
209
|
+
routes: routes.concat(apiServerRoutes)
|
|
210
|
+
};
|
|
211
|
+
});
|
|
212
|
+
api._internalServerPlugins(({ plugins })=>{
|
|
213
|
+
plugins.push({
|
|
214
|
+
name: '@modern-js/plugin-bff/server-plugin'
|
|
215
|
+
});
|
|
216
|
+
return {
|
|
217
|
+
plugins
|
|
218
|
+
};
|
|
219
|
+
});
|
|
220
|
+
api.onBeforeDev(async ()=>{
|
|
221
|
+
await handleCrossProjectInvocation();
|
|
222
|
+
});
|
|
223
|
+
api.onAfterBuild(async ()=>{
|
|
224
|
+
await compileApi();
|
|
225
|
+
await handleCrossProjectInvocation(true);
|
|
226
|
+
});
|
|
227
|
+
api.addWatchFiles(async ()=>{
|
|
228
|
+
const appContext = api.getAppContext();
|
|
229
|
+
const config = api.getNormalizedConfig();
|
|
230
|
+
if (config?.bff?.crossProject) return [
|
|
231
|
+
appContext.apiDirectory,
|
|
232
|
+
appContext.sharedDirectory
|
|
233
|
+
].filter(Boolean);
|
|
234
|
+
return [];
|
|
235
|
+
});
|
|
236
|
+
api.onFileChanged(async (e)=>{
|
|
237
|
+
const { filename, eventType, isPrivate } = e;
|
|
238
|
+
const { appDirectory, apiDirectory, sharedDirectory } = api.getAppContext();
|
|
239
|
+
const relativeApiPath = path.relative(appDirectory, apiDirectory);
|
|
240
|
+
const relativeSharedPath = sharedDirectory ? path.relative(appDirectory, sharedDirectory) : '';
|
|
241
|
+
const isApiFile = filename.startsWith(`${relativeApiPath}/`);
|
|
242
|
+
const isSharedFile = relativeSharedPath ? filename.startsWith(`${relativeSharedPath}/`) : false;
|
|
243
|
+
if (!isPrivate && ('add' === eventType || 'change' === eventType || 'unlink' === eventType) && (isApiFile || isSharedFile) && isWatchableBffFile(filename)) await handleCrossProjectInvocation();
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
const cli = bffPlugin;
|
|
248
|
+
export default cli;
|
|
249
|
+
export { bffPlugin };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
const API_APP_NAME = '_app';
|
|
3
|
+
const BUILD_FILES = [
|
|
4
|
+
'**/*.[tj]sx?',
|
|
5
|
+
'!**/*.test.jsx?',
|
|
6
|
+
'!**/*.test.tsx?',
|
|
7
|
+
'!**/*.spec.jsx?',
|
|
8
|
+
'!**/*.spec.tsx?',
|
|
9
|
+
'!__tests__/*.tsx?',
|
|
10
|
+
'!__tests__/*.jsx?'
|
|
11
|
+
];
|
|
12
|
+
export { API_APP_NAME, BUILD_FILES };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import __rslib_shim_module__ from "node:module";
|
|
2
|
+
const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(/*#__PURE__*/ (()=>import.meta.url)());
|
|
3
|
+
import { generateClient } from "@modern-js/bff-core";
|
|
4
|
+
import { logger } from "@modern-js/utils";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import { generateEffectClientCode, resolveEffectEntryFile } from "./utils/effectClientGenerator.mjs";
|
|
7
|
+
async function loader(source) {
|
|
8
|
+
this.cacheable();
|
|
9
|
+
const { resourcePath } = this;
|
|
10
|
+
delete require.cache[resourcePath];
|
|
11
|
+
const callback = this.async();
|
|
12
|
+
const draftOptions = this.getOptions();
|
|
13
|
+
const effectEntryFile = resolveEffectEntryFile({
|
|
14
|
+
appDir: draftOptions.appDir,
|
|
15
|
+
apiDir: draftOptions.apiDir,
|
|
16
|
+
effectEntry: draftOptions.effectEntry
|
|
17
|
+
});
|
|
18
|
+
if ('effect' === draftOptions.bffRuntimeFramework && effectEntryFile && path.resolve(effectEntryFile) === path.resolve(resourcePath)) {
|
|
19
|
+
const code = await generateEffectClientCode({
|
|
20
|
+
appDir: draftOptions.appDir,
|
|
21
|
+
apiDir: draftOptions.apiDir,
|
|
22
|
+
resourcePath,
|
|
23
|
+
prefix: Array.isArray(draftOptions.prefix) ? draftOptions.prefix[0] : draftOptions.prefix,
|
|
24
|
+
port: Number(draftOptions.port),
|
|
25
|
+
target: draftOptions.target,
|
|
26
|
+
requestCreator: draftOptions.requestCreator,
|
|
27
|
+
httpMethodDecider: draftOptions.httpMethodDecider,
|
|
28
|
+
dataPlatformBatch: draftOptions.effectDataPlatformBatch
|
|
29
|
+
});
|
|
30
|
+
if (code) return void callback(void 0, code);
|
|
31
|
+
callback(void 0, `throw new Error('Failed to generate Effect client for ${resourcePath}')`);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const warning = `The file ${resourcePath} is not allowed to be imported in src directory, only API definition files are allowed.`;
|
|
35
|
+
if (!draftOptions.existLambda) {
|
|
36
|
+
logger.warn(warning);
|
|
37
|
+
callback(null, `throw new Error('${warning}')`);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const options = {
|
|
41
|
+
prefix: Array.isArray(draftOptions.prefix) ? draftOptions.prefix[0] : draftOptions.prefix,
|
|
42
|
+
appDir: draftOptions.appDir,
|
|
43
|
+
apiDir: draftOptions.apiDir,
|
|
44
|
+
lambdaDir: draftOptions.lambdaDir,
|
|
45
|
+
target: draftOptions.target,
|
|
46
|
+
port: Number(draftOptions.port),
|
|
47
|
+
source,
|
|
48
|
+
resourcePath,
|
|
49
|
+
httpMethodDecider: draftOptions.httpMethodDecider
|
|
50
|
+
};
|
|
51
|
+
const { lambdaDir } = draftOptions;
|
|
52
|
+
if (!resourcePath.startsWith(lambdaDir)) {
|
|
53
|
+
logger.warn(warning);
|
|
54
|
+
callback(null, `throw new Error('${warning}')`);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (draftOptions.fetcher) options.fetcher = draftOptions.fetcher;
|
|
58
|
+
if (draftOptions.requestCreator) options.requestCreator = draftOptions.requestCreator;
|
|
59
|
+
options.requireResolve = require.resolve;
|
|
60
|
+
const result = await generateClient(options);
|
|
61
|
+
callback(void 0, result.isOk ? result.value : `throw new Error('${result.value}')`);
|
|
62
|
+
}
|
|
63
|
+
const src_loader = loader;
|
|
64
|
+
export default src_loader;
|