@bleedingdev/modern-js-plugin-bff 3.9.0-ultramodern.3 → 3.9.0-ultramodern.5
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/cli/generator.js +118 -117
- package/dist/cjs/cli.js +11 -6
- package/dist/cjs/loader.js +9 -65
- package/dist/cjs/runtime/create-request/index.js +0 -6
- package/dist/cjs/runtime/hono/adapter.js +8 -12
- package/dist/cjs/server.js +26 -18
- package/dist/cjs/utils/client-generator/files.js +1 -1
- package/dist/cjs/utils/client-generator/generate.js +46 -45
- package/dist/cjs/utils/client-generator/write-package.js +10 -1
- package/dist/cjs/utils/crossProjectApiPlugin.js +26 -83
- package/dist/cjs/utils/pluginGenerator.js +26 -26
- package/dist/cjs/utils/runtimeGenerator.js +25 -75
- package/dist/esm/cli/generator.mjs +121 -120
- package/dist/esm/cli.mjs +11 -6
- package/dist/esm/loader.mjs +9 -55
- package/dist/esm/runtime/create-request/index.mjs +1 -1
- package/dist/esm/runtime/hono/adapter.mjs +8 -12
- package/dist/esm/server.mjs +27 -19
- package/dist/esm/utils/client-generator/files.mjs +1 -1
- package/dist/esm/utils/client-generator/generate.mjs +47 -46
- package/dist/esm/utils/client-generator/write-package.mjs +10 -1
- package/dist/esm/utils/crossProjectApiPlugin.mjs +24 -54
- package/dist/esm/utils/pluginGenerator.mjs +23 -25
- package/dist/esm/utils/runtimeGenerator.mjs +22 -74
- package/dist/esm-node/cli/generator.mjs +121 -120
- package/dist/esm-node/cli.mjs +11 -6
- package/dist/esm-node/loader.mjs +9 -55
- package/dist/esm-node/runtime/create-request/index.mjs +1 -1
- package/dist/esm-node/runtime/hono/adapter.mjs +8 -12
- package/dist/esm-node/server.mjs +27 -19
- package/dist/esm-node/utils/client-generator/files.mjs +1 -1
- package/dist/esm-node/utils/client-generator/generate.mjs +47 -46
- package/dist/esm-node/utils/client-generator/write-package.mjs +10 -1
- package/dist/esm-node/utils/crossProjectApiPlugin.mjs +24 -54
- package/dist/esm-node/utils/pluginGenerator.mjs +23 -28
- package/dist/esm-node/utils/runtimeGenerator.mjs +23 -76
- package/dist/types/cli/generator.d.ts +2 -2
- package/dist/types/loader.d.ts +1 -11
- package/dist/types/runtime/create-request/index.d.ts +1 -3
- package/dist/types/runtime/hono/adapter.d.ts +9 -2
- package/dist/types/server.d.ts +9 -2
- package/dist/types/utils/client-generator/generate.d.ts +8 -12
- package/dist/types/utils/client-generator/write-package.d.ts +1 -1
- package/dist/types/utils/crossProjectApiPlugin.d.ts +18 -12
- package/dist/types/utils/pluginGenerator.d.ts +6 -7
- package/dist/types/utils/runtimeGenerator.d.ts +6 -3
- package/package.json +25 -118
- package/dist/cjs/cli/serverGlobalVars.js +0 -113
- package/dist/cjs/runtime/data-platform/index.js +0 -62
- package/dist/cjs/runtime/effect/edge-dispatcher.js +0 -62
- package/dist/cjs/runtime/effect/edge.js +0 -69
- package/dist/cjs/runtime/effect/index.js +0 -305
- package/dist/cjs/runtime/effect-client/index.js +0 -62
- package/dist/cjs/runtime/effect-client/runtime.js +0 -62
- package/dist/esm/cli/serverGlobalVars.mjs +0 -72
- package/dist/esm/runtime/data-platform/index.mjs +0 -1
- package/dist/esm/runtime/effect/edge-dispatcher.mjs +0 -1
- package/dist/esm/runtime/effect/edge.mjs +0 -2
- package/dist/esm/runtime/effect/index.mjs +0 -16
- package/dist/esm/runtime/effect-client/index.mjs +0 -1
- package/dist/esm/runtime/effect-client/runtime.mjs +0 -1
- package/dist/esm-node/cli/serverGlobalVars.mjs +0 -73
- package/dist/esm-node/runtime/data-platform/index.mjs +0 -2
- package/dist/esm-node/runtime/effect/edge-dispatcher.mjs +0 -2
- package/dist/esm-node/runtime/effect/edge.mjs +0 -3
- package/dist/esm-node/runtime/effect/index.mjs +0 -17
- package/dist/esm-node/runtime/effect-client/index.mjs +0 -2
- package/dist/esm-node/runtime/effect-client/runtime.mjs +0 -2
- package/dist/types/cli/serverGlobalVars.d.ts +0 -6
- package/dist/types/runtime/data-platform/index.d.ts +0 -1
- package/dist/types/runtime/effect/edge-dispatcher.d.ts +0 -1
- package/dist/types/runtime/effect/edge.d.ts +0 -2
- package/dist/types/runtime/effect/index.d.ts +0 -15
- package/dist/types/runtime/effect-client/index.d.ts +0 -1
- package/dist/types/runtime/effect-client/runtime.d.ts +0 -1
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import { generateClient } from "@modern-js/bff-core";
|
|
1
|
+
import { ClientCodegenError, generateClient } from "@modern-js/bff-core";
|
|
2
2
|
import { fs, logger } from "@modern-js/utils";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import { CLIENT_DIR, createFileDetails, readDirectoryFiles, writeTargetFile } from "./files.mjs";
|
|
5
5
|
import { getPackageName } from "./package-json.mjs";
|
|
6
6
|
import { DEFAULT_EXPORT_RE, buildClientTypeFacade, createMissingClientDeclarationError, isMissingClientDeclarationError } from "./type-facade.mjs";
|
|
7
7
|
import { setPackage, writeClientModuleBoundary } from "./write-package.mjs";
|
|
8
|
-
async function clientGenerator(draftOptions) {
|
|
8
|
+
async function clientGenerator(draftOptions, integration) {
|
|
9
9
|
const generatedClientDir = path.resolve(draftOptions.appDir, draftOptions.relativeDistPath, CLIENT_DIR);
|
|
10
10
|
await fs.remove(generatedClientDir);
|
|
11
|
-
const requestId = getPackageName(draftOptions.appDir) || process.env.npm_package_name;
|
|
11
|
+
const requestId = draftOptions.requestId || getPackageName(draftOptions.appDir) || process.env.npm_package_name;
|
|
12
12
|
const lambdaSourceList = draftOptions.existLambda ? await readDirectoryFiles(draftOptions.appDir, draftOptions.lambdaDir, draftOptions.relativeDistPath, draftOptions.apiFiles) : [];
|
|
13
13
|
const generatedSourceList = [
|
|
14
14
|
...lambdaSourceList
|
|
15
15
|
];
|
|
16
|
-
let generatedEffectClient = null;
|
|
17
16
|
const getClitentCode = async (resourcePath, source)=>{
|
|
18
17
|
const warning = `The file ${resourcePath} is not allowed to be imported in src directory, only API definition files are allowed.`;
|
|
19
18
|
if (!draftOptions.existLambda) return void logger.warn(warning);
|
|
@@ -28,6 +27,7 @@ async function clientGenerator(draftOptions) {
|
|
|
28
27
|
target: 'bundle',
|
|
29
28
|
httpMethodDecider: draftOptions.httpMethodDecider,
|
|
30
29
|
requestCreator: draftOptions.requestCreator,
|
|
30
|
+
clientCodegenPlugin: draftOptions.clientCodegenPlugin,
|
|
31
31
|
requestId
|
|
32
32
|
};
|
|
33
33
|
const { lambdaDir } = draftOptions;
|
|
@@ -36,9 +36,9 @@ async function clientGenerator(draftOptions) {
|
|
|
36
36
|
return result;
|
|
37
37
|
};
|
|
38
38
|
const writeClientTypeFacade = async (source, clientCode)=>{
|
|
39
|
-
if (!await fs.pathExists(path.resolve(source.relativeTargetDistDir))) throw createMissingClientDeclarationError(source.resourcePath, source.relativeTargetDistDir);
|
|
40
|
-
const clientTypesFile = source.
|
|
41
|
-
await writeTargetFile(path.resolve(clientTypesFile), buildClientTypeFacade(clientTypesFile, source.relativeTargetDistDir, DEFAULT_EXPORT_RE.test(clientCode), true));
|
|
39
|
+
if (!await fs.pathExists(path.resolve(draftOptions.appDir, source.relativeTargetDistDir))) throw createMissingClientDeclarationError(source.resourcePath, path.resolve(draftOptions.appDir, source.relativeTargetDistDir));
|
|
40
|
+
const clientTypesFile = source.absTargetDir.replace(/\.js$/, '.d.ts');
|
|
41
|
+
await writeTargetFile(path.resolve(clientTypesFile), buildClientTypeFacade(clientTypesFile, path.resolve(draftOptions.appDir, source.relativeTargetDistDir), DEFAULT_EXPORT_RE.test(clientCode), true));
|
|
42
42
|
};
|
|
43
43
|
try {
|
|
44
44
|
for (const source of lambdaSourceList){
|
|
@@ -48,50 +48,51 @@ async function clientGenerator(draftOptions) {
|
|
|
48
48
|
await writeClientTypeFacade(source, code.value);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
if ('effect' === draftOptions.bffRuntimeFramework) {
|
|
52
|
-
const { generateEffectClient, resolveEffectEntryFile } = await import("@modern-js/plugin-bff-extensions/client-generator");
|
|
53
|
-
const effectEntryFile = resolveEffectEntryFile({
|
|
54
|
-
appDir: draftOptions.appDir,
|
|
55
|
-
apiDir: draftOptions.apiDir,
|
|
56
|
-
effectEntry: draftOptions.effectEntry
|
|
57
|
-
});
|
|
58
|
-
if (effectEntryFile) {
|
|
59
|
-
const effectSource = await fs.readFile(effectEntryFile, 'utf8');
|
|
60
|
-
const effectFileDetails = createFileDetails({
|
|
61
|
-
appDirectory: draftOptions.appDir,
|
|
62
|
-
baseDirectory: draftOptions.apiDir,
|
|
63
|
-
resourcePath: effectEntryFile,
|
|
64
|
-
source: effectSource,
|
|
65
|
-
relativeDistPath: draftOptions.relativeDistPath
|
|
66
|
-
});
|
|
67
|
-
generatedEffectClient = await generateEffectClient({
|
|
68
|
-
appDir: draftOptions.appDir,
|
|
69
|
-
apiDir: draftOptions.apiDir,
|
|
70
|
-
resourcePath: effectEntryFile,
|
|
71
|
-
prefix: Array.isArray(draftOptions.prefix) ? draftOptions.prefix[0] : draftOptions.prefix,
|
|
72
|
-
port: Number(draftOptions.port),
|
|
73
|
-
target: 'bundle',
|
|
74
|
-
requestId: draftOptions.requestId,
|
|
75
|
-
requestCreator: draftOptions.requestCreator,
|
|
76
|
-
httpMethodDecider: draftOptions.httpMethodDecider,
|
|
77
|
-
dataPlatformBatch: draftOptions.effectDataPlatformBatch
|
|
78
|
-
});
|
|
79
|
-
if (generatedEffectClient) {
|
|
80
|
-
const targetTypeFile = effectFileDetails.targetDir.replace(/\.js$/, '.d.ts');
|
|
81
|
-
await writeTargetFile(effectFileDetails.absTargetDir, generatedEffectClient.code);
|
|
82
|
-
await writeTargetFile(path.resolve(targetTypeFile), generatedEffectClient.declaration);
|
|
83
|
-
generatedSourceList.push(effectFileDetails);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
51
|
logger.info("Client bundle generate succeed");
|
|
88
52
|
} catch (error) {
|
|
89
|
-
if (isMissingClientDeclarationError(error)) throw error;
|
|
53
|
+
if (isMissingClientDeclarationError(error) || error instanceof ClientCodegenError) throw error;
|
|
90
54
|
logger.error(`Client bundle generate failed: ${error}`);
|
|
91
55
|
}
|
|
56
|
+
let packageDependencies;
|
|
57
|
+
if (integration) {
|
|
58
|
+
const artifacts = await integration.modifyArtifacts({
|
|
59
|
+
generation: integration.generation,
|
|
60
|
+
additionalArtifacts: []
|
|
61
|
+
});
|
|
62
|
+
if (artifacts.generation !== integration.generation) throw new Error('BFF artifacts must preserve generation identity.');
|
|
63
|
+
const sourcePaths = new Set(generatedSourceList.map((file)=>path.resolve(file.resourcePath)));
|
|
64
|
+
const exportKeys = new Set(generatedSourceList.map((file)=>file.exportKey));
|
|
65
|
+
const outputPaths = new Set(generatedSourceList.map((file)=>path.resolve(file.absTargetDir)));
|
|
66
|
+
const additionalFiles = artifacts.additionalArtifacts.map((artifact)=>{
|
|
67
|
+
const relative = artifact.sourcePath;
|
|
68
|
+
const resourcePath = path.resolve(draftOptions.apiDir, relative);
|
|
69
|
+
if (!relative || path.isAbsolute(relative) || relative.includes('\\') || path.relative(draftOptions.apiDir, resourcePath).split(path.sep).includes('..') || path.relative(draftOptions.apiDir, resourcePath).split(path.sep).join('/') !== relative || !/\.[cm]?[jt]sx?$/.test(relative)) throw new Error(`Invalid BFF client artifact source path: ${relative}`);
|
|
70
|
+
const file = createFileDetails({
|
|
71
|
+
appDirectory: draftOptions.appDir,
|
|
72
|
+
baseDirectory: draftOptions.apiDir,
|
|
73
|
+
resourcePath,
|
|
74
|
+
source: '',
|
|
75
|
+
relativeDistPath: draftOptions.relativeDistPath
|
|
76
|
+
});
|
|
77
|
+
if (sourcePaths.has(resourcePath) || exportKeys.has(file.exportKey) || outputPaths.has(path.resolve(file.absTargetDir))) throw new Error(`BFF client artifact collision: ${relative}`);
|
|
78
|
+
sourcePaths.add(resourcePath);
|
|
79
|
+
exportKeys.add(file.exportKey);
|
|
80
|
+
outputPaths.add(path.resolve(file.absTargetDir));
|
|
81
|
+
return {
|
|
82
|
+
file,
|
|
83
|
+
artifact
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
for (const { file, artifact } of additionalFiles){
|
|
87
|
+
await writeTargetFile(file.absTargetDir, artifact.code);
|
|
88
|
+
await writeTargetFile(file.absTargetDir.replace(/\.js$/, '.d.ts'), artifact.declaration);
|
|
89
|
+
generatedSourceList.push(file);
|
|
90
|
+
}
|
|
91
|
+
packageDependencies = await integration.beforePublish() || void 0;
|
|
92
|
+
}
|
|
92
93
|
if (generatedSourceList.length > 0) await writeClientModuleBoundary(draftOptions.appDir, draftOptions.relativeDistPath);
|
|
93
|
-
await setPackage(generatedSourceList, draftOptions.appDir, draftOptions.relativeDistPath);
|
|
94
|
-
return
|
|
94
|
+
await setPackage(generatedSourceList, draftOptions.appDir, draftOptions.relativeDistPath, packageDependencies);
|
|
95
|
+
return null;
|
|
95
96
|
}
|
|
96
97
|
const generate = clientGenerator;
|
|
97
98
|
export default generate;
|
|
@@ -9,10 +9,19 @@ async function writeClientModuleBoundary(appDirectory, relativeDistPath) {
|
|
|
9
9
|
type: 'module'
|
|
10
10
|
}, null, 2)}\n`);
|
|
11
11
|
}
|
|
12
|
-
async function setPackage(files, appDirectory, relativeDistPath) {
|
|
12
|
+
async function setPackage(files, appDirectory, relativeDistPath, packageDependencies = {}) {
|
|
13
13
|
const packagePath = path.resolve(appDirectory, './package.json');
|
|
14
14
|
const packageContent = await fs.readFile(packagePath, 'utf8');
|
|
15
15
|
const packageJson = JSON.parse(packageContent);
|
|
16
|
+
for (const [name, specifier] of Object.entries(packageDependencies)){
|
|
17
|
+
if (!name || 'string' != typeof specifier || !specifier.trim()) throw new Error(`Invalid BFF SDK dependency: ${name}`);
|
|
18
|
+
const existing = packageJson.dependencies?.[name];
|
|
19
|
+
if (void 0 !== existing && existing !== specifier) throw new Error(`package.json dependency conflict for ${name}: ${existing} versus ${specifier}`);
|
|
20
|
+
}
|
|
21
|
+
if (Object.keys(packageDependencies).length > 0) packageJson.dependencies = {
|
|
22
|
+
...packageJson.dependencies,
|
|
23
|
+
...packageDependencies
|
|
24
|
+
};
|
|
16
25
|
const sortedFiles = [
|
|
17
26
|
...files
|
|
18
27
|
].sort((a, b)=>a.exportKey.localeCompare(b.exportKey));
|
|
@@ -1,68 +1,38 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
-
const
|
|
3
|
-
const REQUEST_ID = '{requestId}';
|
|
4
|
-
const PREFIX = '{prefix}';
|
|
5
|
-
const API_DIR = '{apiDirectory}';
|
|
6
|
-
const LAMBDA_DIR = '{lambdaDirectory}';
|
|
7
|
-
const DIST_DIR = '{distDirectory}';
|
|
8
|
-
const RUNTIME_FRAMEWORK = '{runtimeFramework}';
|
|
9
|
-
const EFFECT_ENTRY = '{effectEntry}';
|
|
10
|
-
const OPERATION_CONTRACTS_JSON = '{operationContracts}';
|
|
11
|
-
const NODE_MODULES = 'node_modules';
|
|
12
|
-
const crossProjectApiPlugin = ()=>({
|
|
2
|
+
const createCrossProjectApiPlugin = (options)=>({
|
|
13
3
|
name: '@modern-js/plugin-independent-bff',
|
|
14
4
|
post: [
|
|
15
5
|
'@modern-js/plugin-bff'
|
|
16
6
|
],
|
|
17
7
|
setup: (api)=>{
|
|
18
|
-
api.modifyResolvedConfig((resolvedConfig)=>{
|
|
19
|
-
const { appDirectory
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
8
|
+
api.modifyResolvedConfig(async (resolvedConfig)=>{
|
|
9
|
+
const { appDirectory } = api.getAppContext();
|
|
10
|
+
const sdkDirectory = path.join(appDirectory, 'node_modules', options.packageName);
|
|
11
|
+
const sdkDistDirectory = path.join(sdkDirectory, options.relativeDistPath);
|
|
12
|
+
const apiDirectory = path.join(sdkDistDirectory, options.relativeApiPath);
|
|
13
|
+
const lambdaDirectory = path.resolve(sdkDistDirectory, options.relativeLambdaPath);
|
|
14
|
+
const configuredPrefix = api.getConfig()?.bff?.prefix;
|
|
15
|
+
if (configuredPrefix) {
|
|
16
|
+
const isSamePrefix = Array.isArray(configuredPrefix) ? 1 === configuredPrefix.length && configuredPrefix[0] === options.prefix : configuredPrefix === options.prefix;
|
|
17
|
+
if (!isSamePrefix) throw new Error(`[${options.packageName}] Invalid bff.prefix for cross-project BFF. Detected "${configuredPrefix}", expected "${options.prefix}". Remove bff.prefix from the consumer app, or set it exactly to "${options.prefix}".`);
|
|
18
|
+
}
|
|
25
19
|
api.updateAppContext({
|
|
26
20
|
apiDirectory,
|
|
27
|
-
lambdaDirectory
|
|
28
|
-
bffRuntimeFramework: RUNTIME_FRAMEWORK
|
|
21
|
+
lambdaDirectory
|
|
29
22
|
});
|
|
30
|
-
const config = api.getConfig();
|
|
31
|
-
const configuredPrefix = config?.bff?.prefix;
|
|
32
|
-
if (configuredPrefix) {
|
|
33
|
-
const isSamePrefix = Array.isArray(configuredPrefix) ? 1 === configuredPrefix.length && configuredPrefix[0] === PREFIX : configuredPrefix === PREFIX;
|
|
34
|
-
if (!isSamePrefix) throw new Error(`[${PACKAGE_NAME}] Invalid bff.prefix for cross-project BFF. Detected "${configuredPrefix}", expected "${PREFIX}". Remove bff.prefix from the consumer app, or set it exactly to "${PREFIX}".`);
|
|
35
|
-
}
|
|
36
|
-
const configuredRuntimeFramework = config?.bff?.runtimeFramework;
|
|
37
|
-
if (configuredRuntimeFramework && configuredRuntimeFramework !== RUNTIME_FRAMEWORK) throw new Error(`[${PACKAGE_NAME}] Runtime framework mismatch for cross-project BFF. Detected "${configuredRuntimeFramework}", but producer SDK requires "${RUNTIME_FRAMEWORK}".`);
|
|
38
23
|
resolvedConfig.bff ??= {};
|
|
39
|
-
resolvedConfig.bff.prefix =
|
|
40
|
-
resolvedConfig.bff.runtimeFramework = RUNTIME_FRAMEWORK;
|
|
41
|
-
if (EFFECT_ENTRY) resolvedConfig.bff.effect = {
|
|
42
|
-
...resolvedConfig.bff.effect,
|
|
43
|
-
entry: effectEntry
|
|
44
|
-
};
|
|
24
|
+
resolvedConfig.bff.prefix = options.prefix;
|
|
45
25
|
resolvedConfig.bff.isCrossProjectServer = true;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
requireOperationContextDetails: resolvedConfig.bff.crossProjectPolicy?.requireOperationContextDetails ?? true,
|
|
54
|
-
requireOperationSchemaHash: resolvedConfig.bff.crossProjectPolicy?.requireOperationSchemaHash ?? true,
|
|
55
|
-
requireOperationVersion: resolvedConfig.bff.crossProjectPolicy?.requireOperationVersion ?? true,
|
|
56
|
-
allowUnknownOperations: resolvedConfig.bff.crossProjectPolicy?.allowUnknownOperations ?? false,
|
|
57
|
-
expectedOperationContracts: {
|
|
58
|
-
...resolvedConfig.bff.crossProjectPolicy?.expectedOperationContracts || {},
|
|
59
|
-
...generatedOperationContracts
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
return resolvedConfig;
|
|
26
|
+
return options.modifyResolvedConfig ? options.modifyResolvedConfig(resolvedConfig, {
|
|
27
|
+
sdkDirectory,
|
|
28
|
+
sdkDistDirectory,
|
|
29
|
+
apiDirectory,
|
|
30
|
+
lambdaDirectory,
|
|
31
|
+
api
|
|
32
|
+
}) : resolvedConfig;
|
|
63
33
|
});
|
|
64
34
|
}
|
|
65
35
|
});
|
|
66
|
-
const
|
|
67
|
-
export default
|
|
68
|
-
export {
|
|
36
|
+
const crossProjectApiPlugin = createCrossProjectApiPlugin;
|
|
37
|
+
export default crossProjectApiPlugin;
|
|
38
|
+
export { createCrossProjectApiPlugin };
|
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
import { fs, logger, normalizeToPosixPath } from "@modern-js/utils";
|
|
2
2
|
import path from "path";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
3
|
+
async function renderBffPlugin(options) {
|
|
4
|
+
const packageJson = await fs.readJSON(path.resolve(options.appDirectory, 'package.json'));
|
|
5
|
+
const descriptor = {
|
|
6
|
+
packageName: packageJson.name,
|
|
7
|
+
prefix: options.prefix,
|
|
8
|
+
relativeDistPath: normalizeToPosixPath(options.relativeDistPath),
|
|
9
|
+
relativeApiPath: normalizeToPosixPath(options.relativeApiPath),
|
|
10
|
+
relativeLambdaPath: normalizeToPosixPath(options.relativeLambdaPath)
|
|
11
|
+
};
|
|
12
|
+
return {
|
|
13
|
+
code: 'module' === packageJson.type ? `import { createCrossProjectApiPlugin } from '@modern-js/plugin-bff/cross-project';\nexport const crossProjectApiPlugin = () => createCrossProjectApiPlugin(${JSON.stringify(descriptor)});\n` : `'use strict';\nconst { createCrossProjectApiPlugin } = require('@modern-js/plugin-bff/cross-project');\nexports.crossProjectApiPlugin = () => createCrossProjectApiPlugin(${JSON.stringify(descriptor)});\n`,
|
|
14
|
+
declaration: `import type { AppTools, CliPlugin } from '@modern-js/app-tools';
|
|
15
|
+
export declare const crossProjectApiPlugin: () => CliPlugin<AppTools>;
|
|
16
|
+
`
|
|
17
|
+
};
|
|
7
18
|
}
|
|
8
|
-
async function pluginGenerator(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const pluginTemplate = await fs.readFile(path.resolve(__dirname, 'crossProjectApiPlugin.js'), 'utf8');
|
|
15
|
-
const updatedPlugin = replaceContent(pluginTemplate, packageJson.name, requestId, prefix, relativeDistPath, relativeApiPath, relativeLambdaPath, runtimeFramework, relativeEffectEntry, operationContracts);
|
|
16
|
-
await fs.ensureFile(pluginPath);
|
|
17
|
-
await fs.writeFile(pluginPath, updatedPlugin);
|
|
18
|
-
const typeContent = `import type { AppTools, CliPlugin } from '@modern-js/app-tools';
|
|
19
|
-
export declare const crossProjectApiPlugin: () => CliPlugin<AppTools>`;
|
|
20
|
-
const pluginTypePath = path.join(pluginDir, 'index.d.ts');
|
|
21
|
-
await fs.ensureFile(pluginTypePath);
|
|
22
|
-
await fs.writeFile(pluginTypePath, typeContent);
|
|
23
|
-
logger.info('Api plugin generate succeed');
|
|
24
|
-
} catch (error) {
|
|
25
|
-
logger.error('Api plugin generate failed:', error);
|
|
26
|
-
}
|
|
19
|
+
async function pluginGenerator(options, rendered) {
|
|
20
|
+
const module = rendered ?? await renderBffPlugin(options);
|
|
21
|
+
const directory = path.resolve(options.appDirectory, options.relativeDistPath, 'plugin');
|
|
22
|
+
await fs.outputFile(path.join(directory, 'index.js'), module.code);
|
|
23
|
+
await fs.outputFile(path.join(directory, 'index.d.ts'), module.declaration);
|
|
24
|
+
logger.info('Api plugin generate succeed');
|
|
27
25
|
}
|
|
28
|
-
|
|
29
|
-
export
|
|
26
|
+
export default pluginGenerator;
|
|
27
|
+
export { renderBffPlugin };
|
|
@@ -1,77 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { pathToFileURL } from "node:url";
|
|
2
2
|
import { fs } from "@modern-js/utils";
|
|
3
3
|
import path from "path";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const requestIdValue = JSON.stringify(requestId);
|
|
18
|
-
const source = `'use strict'; const { configure: _configure } = require(${runtimeImportPath});
|
|
19
|
-
const defaultSecureOptions = ${renderProducerRuntimeDefaults(requestIdValue)};
|
|
20
|
-
const initProducerClient = (options) => {
|
|
21
|
-
return _configure({
|
|
22
|
-
...defaultSecureOptions,
|
|
23
|
-
...options,
|
|
24
|
-
identityBinding: {
|
|
25
|
-
...defaultSecureOptions.identityBinding,
|
|
26
|
-
...(options && options.identityBinding ? options.identityBinding : {}),
|
|
27
|
-
},
|
|
28
|
-
operationContract: {
|
|
29
|
-
...defaultSecureOptions.operationContract,
|
|
30
|
-
...(options && options.operationContract ? options.operationContract : {}),
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
const configure = initProducerClient;
|
|
35
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
36
|
-
exports.initProducerClient = initProducerClient;
|
|
37
|
-
exports.configure = configure;
|
|
38
|
-
`;
|
|
39
|
-
const pluginPath = path.join(pluginDir, 'index.js');
|
|
40
|
-
await fs.ensureFile(pluginPath);
|
|
41
|
-
await fs.writeFile(pluginPath, source);
|
|
42
|
-
const tsSource = `type ProducerRuntimeModule = typeof import(${runtimeImportPath});
|
|
43
|
-
type ProducerClientOptions = ProducerRuntimeModule extends {
|
|
44
|
-
configure: (options: infer TOptions) => unknown;
|
|
45
|
-
}
|
|
46
|
-
? TOptions
|
|
47
|
-
: {
|
|
48
|
-
request?: typeof fetch;
|
|
49
|
-
interceptor?: (request: typeof fetch) => typeof fetch;
|
|
50
|
-
allowedHeaders?: string[];
|
|
51
|
-
requireEnvelope?: boolean;
|
|
52
|
-
allowCrossOriginEnvelope?: boolean;
|
|
53
|
-
identityBinding?: {
|
|
54
|
-
enabled?: boolean;
|
|
55
|
-
strict?: boolean;
|
|
56
|
-
protectedHeaders?: string[];
|
|
57
|
-
};
|
|
58
|
-
operationContract?: {
|
|
59
|
-
enabled?: boolean;
|
|
60
|
-
strict?: boolean;
|
|
61
|
-
requireSchemaHash?: boolean;
|
|
62
|
-
requireOperationVersion?: boolean;
|
|
63
|
-
};
|
|
64
|
-
setDomain?: (ops?: {
|
|
65
|
-
target: 'server' | 'browser';
|
|
66
|
-
requestId?: string;
|
|
67
|
-
}) => string;
|
|
68
|
-
requestId?: string;
|
|
69
|
-
};
|
|
70
|
-
export declare const initProducerClient: (options?: ProducerClientOptions) => ReturnType<ProducerRuntimeModule['configure']>;
|
|
71
|
-
export declare const configure: typeof initProducerClient;`;
|
|
72
|
-
const pluginTypePath = path.join(pluginDir, 'index.d.ts');
|
|
73
|
-
await fs.ensureFile(pluginTypePath);
|
|
74
|
-
await fs.writeFile(pluginTypePath, tsSource);
|
|
4
|
+
function renderBffRuntime(options) {
|
|
5
|
+
const packagePath = path.resolve(options.appDirectory, 'package.json');
|
|
6
|
+
const packageJson = fs.existsSync(packagePath) ? fs.readJSONSync(packagePath) : {};
|
|
7
|
+
const requestId = options.packageName || packageJson.name || process.env.npm_package_name || 'default';
|
|
8
|
+
const runtime = JSON.stringify(options.runtime);
|
|
9
|
+
const esmRuntime = JSON.stringify(path.isAbsolute(options.runtime) ? pathToFileURL(options.runtime).href : options.runtime);
|
|
10
|
+
return {
|
|
11
|
+
code: 'module' === packageJson.type ? `import { configure as _configure } from ${esmRuntime};\nexport const initProducerClient = options => _configure({ requestId: ${JSON.stringify(requestId)}, ...options });\nexport const configure = initProducerClient;\n` : `'use strict';\nconst { configure: _configure } = require(${runtime});\nconst initProducerClient = options => _configure({ requestId: ${JSON.stringify(requestId)}, ...options });\nexports.initProducerClient = initProducerClient;\nexports.configure = initProducerClient;\n`,
|
|
12
|
+
declaration: `type Runtime = typeof import(${runtime});
|
|
13
|
+
export declare const initProducerClient: (options?: Parameters<Runtime['configure']>[0]) => ReturnType<Runtime['configure']>;
|
|
14
|
+
export declare const configure: typeof initProducerClient;
|
|
15
|
+
`
|
|
16
|
+
};
|
|
75
17
|
}
|
|
76
|
-
|
|
77
|
-
|
|
18
|
+
async function runtimeGenerator(options, rendered) {
|
|
19
|
+
const module = rendered ?? renderBffRuntime(options);
|
|
20
|
+
const directory = path.resolve(options.appDirectory, options.relativeDistPath, 'runtime');
|
|
21
|
+
await fs.outputFile(path.join(directory, 'index.js'), module.code);
|
|
22
|
+
await fs.outputFile(path.join(directory, 'index.d.ts'), module.declaration);
|
|
23
|
+
}
|
|
24
|
+
export default runtimeGenerator;
|
|
25
|
+
export { renderBffRuntime };
|