@bleedingdev/modern-js-plugin-bff 3.9.0-ultramodern.4 → 3.9.0-ultramodern.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/cjs/cli/generator.js +118 -117
  2. package/dist/cjs/cli.js +11 -6
  3. package/dist/cjs/loader.js +9 -65
  4. package/dist/cjs/runtime/create-request/index.js +0 -6
  5. package/dist/cjs/runtime/hono/adapter.js +8 -12
  6. package/dist/cjs/server.js +26 -18
  7. package/dist/cjs/utils/client-generator/files.js +1 -1
  8. package/dist/cjs/utils/client-generator/generate.js +46 -45
  9. package/dist/cjs/utils/client-generator/package-json.js +2 -2
  10. package/dist/cjs/utils/client-generator/write-package.js +18 -1
  11. package/dist/cjs/utils/crossProjectApiPlugin.js +26 -83
  12. package/dist/cjs/utils/pluginGenerator.js +26 -26
  13. package/dist/cjs/utils/runtimeGenerator.js +26 -75
  14. package/dist/esm/cli/generator.mjs +121 -120
  15. package/dist/esm/cli.mjs +11 -6
  16. package/dist/esm/loader.mjs +9 -55
  17. package/dist/esm/runtime/create-request/index.mjs +1 -1
  18. package/dist/esm/runtime/hono/adapter.mjs +8 -12
  19. package/dist/esm/server.mjs +27 -19
  20. package/dist/esm/utils/client-generator/files.mjs +1 -1
  21. package/dist/esm/utils/client-generator/generate.mjs +47 -46
  22. package/dist/esm/utils/client-generator/package-json.mjs +3 -3
  23. package/dist/esm/utils/client-generator/write-package.mjs +18 -1
  24. package/dist/esm/utils/crossProjectApiPlugin.mjs +24 -54
  25. package/dist/esm/utils/pluginGenerator.mjs +23 -25
  26. package/dist/esm/utils/runtimeGenerator.mjs +23 -74
  27. package/dist/esm-node/cli/generator.mjs +121 -120
  28. package/dist/esm-node/cli.mjs +11 -6
  29. package/dist/esm-node/loader.mjs +9 -55
  30. package/dist/esm-node/runtime/create-request/index.mjs +1 -1
  31. package/dist/esm-node/runtime/hono/adapter.mjs +8 -12
  32. package/dist/esm-node/server.mjs +27 -19
  33. package/dist/esm-node/utils/client-generator/files.mjs +1 -1
  34. package/dist/esm-node/utils/client-generator/generate.mjs +47 -46
  35. package/dist/esm-node/utils/client-generator/package-json.mjs +3 -3
  36. package/dist/esm-node/utils/client-generator/write-package.mjs +18 -1
  37. package/dist/esm-node/utils/crossProjectApiPlugin.mjs +24 -54
  38. package/dist/esm-node/utils/pluginGenerator.mjs +23 -28
  39. package/dist/esm-node/utils/runtimeGenerator.mjs +24 -76
  40. package/dist/types/cli/generator.d.ts +2 -2
  41. package/dist/types/loader.d.ts +1 -11
  42. package/dist/types/runtime/create-request/index.d.ts +1 -3
  43. package/dist/types/runtime/hono/adapter.d.ts +9 -2
  44. package/dist/types/server.d.ts +9 -2
  45. package/dist/types/utils/client-generator/generate.d.ts +8 -12
  46. package/dist/types/utils/client-generator/write-package.d.ts +1 -1
  47. package/dist/types/utils/crossProjectApiPlugin.d.ts +18 -12
  48. package/dist/types/utils/pluginGenerator.d.ts +6 -7
  49. package/dist/types/utils/runtimeGenerator.d.ts +6 -3
  50. package/package.json +25 -118
  51. package/dist/cjs/cli/serverGlobalVars.js +0 -113
  52. package/dist/cjs/runtime/data-platform/index.js +0 -62
  53. package/dist/cjs/runtime/effect/edge-dispatcher.js +0 -62
  54. package/dist/cjs/runtime/effect/edge.js +0 -69
  55. package/dist/cjs/runtime/effect/index.js +0 -305
  56. package/dist/cjs/runtime/effect-client/index.js +0 -62
  57. package/dist/cjs/runtime/effect-client/runtime.js +0 -62
  58. package/dist/esm/cli/serverGlobalVars.mjs +0 -72
  59. package/dist/esm/runtime/data-platform/index.mjs +0 -1
  60. package/dist/esm/runtime/effect/edge-dispatcher.mjs +0 -1
  61. package/dist/esm/runtime/effect/edge.mjs +0 -2
  62. package/dist/esm/runtime/effect/index.mjs +0 -16
  63. package/dist/esm/runtime/effect-client/index.mjs +0 -1
  64. package/dist/esm/runtime/effect-client/runtime.mjs +0 -1
  65. package/dist/esm-node/cli/serverGlobalVars.mjs +0 -73
  66. package/dist/esm-node/runtime/data-platform/index.mjs +0 -2
  67. package/dist/esm-node/runtime/effect/edge-dispatcher.mjs +0 -2
  68. package/dist/esm-node/runtime/effect/edge.mjs +0 -3
  69. package/dist/esm-node/runtime/effect/index.mjs +0 -17
  70. package/dist/esm-node/runtime/effect-client/index.mjs +0 -2
  71. package/dist/esm-node/runtime/effect-client/runtime.mjs +0 -2
  72. package/dist/types/cli/serverGlobalVars.d.ts +0 -6
  73. package/dist/types/runtime/data-platform/index.d.ts +0 -1
  74. package/dist/types/runtime/effect/edge-dispatcher.d.ts +0 -1
  75. package/dist/types/runtime/effect/edge.d.ts +0 -2
  76. package/dist/types/runtime/effect/index.d.ts +0 -15
  77. package/dist/types/runtime/effect-client/index.d.ts +0 -1
  78. package/dist/types/runtime/effect-client/runtime.d.ts +0 -1
@@ -48,15 +48,14 @@ const external_files_js_namespaceObject = require("./files.js");
48
48
  const external_package_json_js_namespaceObject = require("./package-json.js");
49
49
  const external_type_facade_js_namespaceObject = require("./type-facade.js");
50
50
  const external_write_package_js_namespaceObject = require("./write-package.js");
51
- async function clientGenerator(draftOptions) {
51
+ async function clientGenerator(draftOptions, integration) {
52
52
  const generatedClientDir = external_path_default().resolve(draftOptions.appDir, draftOptions.relativeDistPath, external_files_js_namespaceObject.CLIENT_DIR);
53
53
  await utils_namespaceObject.fs.remove(generatedClientDir);
54
- const requestId = (0, external_package_json_js_namespaceObject.getPackageName)(draftOptions.appDir) || process.env.npm_package_name;
54
+ const requestId = draftOptions.requestId || (0, external_package_json_js_namespaceObject.getPackageName)(draftOptions.appDir) || process.env.npm_package_name;
55
55
  const lambdaSourceList = draftOptions.existLambda ? await (0, external_files_js_namespaceObject.readDirectoryFiles)(draftOptions.appDir, draftOptions.lambdaDir, draftOptions.relativeDistPath, draftOptions.apiFiles) : [];
56
56
  const generatedSourceList = [
57
57
  ...lambdaSourceList
58
58
  ];
59
- let generatedEffectClient = null;
60
59
  const getClitentCode = async (resourcePath, source)=>{
61
60
  const warning = `The file ${resourcePath} is not allowed to be imported in src directory, only API definition files are allowed.`;
62
61
  if (!draftOptions.existLambda) return void utils_namespaceObject.logger.warn(warning);
@@ -71,6 +70,7 @@ async function clientGenerator(draftOptions) {
71
70
  target: 'bundle',
72
71
  httpMethodDecider: draftOptions.httpMethodDecider,
73
72
  requestCreator: draftOptions.requestCreator,
73
+ clientCodegenPlugin: draftOptions.clientCodegenPlugin,
74
74
  requestId
75
75
  };
76
76
  const { lambdaDir } = draftOptions;
@@ -79,9 +79,9 @@ async function clientGenerator(draftOptions) {
79
79
  return result;
80
80
  };
81
81
  const writeClientTypeFacade = async (source, clientCode)=>{
82
- if (!await utils_namespaceObject.fs.pathExists(external_path_default().resolve(source.relativeTargetDistDir))) throw (0, external_type_facade_js_namespaceObject.createMissingClientDeclarationError)(source.resourcePath, source.relativeTargetDistDir);
83
- const clientTypesFile = source.targetDir.replace(/\.js$/, '.d.ts');
84
- await (0, external_files_js_namespaceObject.writeTargetFile)(external_path_default().resolve(clientTypesFile), (0, external_type_facade_js_namespaceObject.buildClientTypeFacade)(clientTypesFile, source.relativeTargetDistDir, external_type_facade_js_namespaceObject.DEFAULT_EXPORT_RE.test(clientCode), true));
82
+ if (!await utils_namespaceObject.fs.pathExists(external_path_default().resolve(draftOptions.appDir, source.relativeTargetDistDir))) throw (0, external_type_facade_js_namespaceObject.createMissingClientDeclarationError)(source.resourcePath, external_path_default().resolve(draftOptions.appDir, source.relativeTargetDistDir));
83
+ const clientTypesFile = source.absTargetDir.replace(/\.js$/, '.d.ts');
84
+ await (0, external_files_js_namespaceObject.writeTargetFile)(external_path_default().resolve(clientTypesFile), (0, external_type_facade_js_namespaceObject.buildClientTypeFacade)(clientTypesFile, external_path_default().resolve(draftOptions.appDir, source.relativeTargetDistDir), external_type_facade_js_namespaceObject.DEFAULT_EXPORT_RE.test(clientCode), true));
85
85
  };
86
86
  try {
87
87
  for (const source of lambdaSourceList){
@@ -91,50 +91,51 @@ async function clientGenerator(draftOptions) {
91
91
  await writeClientTypeFacade(source, code.value);
92
92
  }
93
93
  }
94
- if ('effect' === draftOptions.bffRuntimeFramework) {
95
- const { generateEffectClient, resolveEffectEntryFile } = await import("@modern-js/plugin-bff-extensions/client-generator");
96
- const effectEntryFile = resolveEffectEntryFile({
97
- appDir: draftOptions.appDir,
98
- apiDir: draftOptions.apiDir,
99
- effectEntry: draftOptions.effectEntry
100
- });
101
- if (effectEntryFile) {
102
- const effectSource = await utils_namespaceObject.fs.readFile(effectEntryFile, 'utf8');
103
- const effectFileDetails = (0, external_files_js_namespaceObject.createFileDetails)({
104
- appDirectory: draftOptions.appDir,
105
- baseDirectory: draftOptions.apiDir,
106
- resourcePath: effectEntryFile,
107
- source: effectSource,
108
- relativeDistPath: draftOptions.relativeDistPath
109
- });
110
- generatedEffectClient = await generateEffectClient({
111
- appDir: draftOptions.appDir,
112
- apiDir: draftOptions.apiDir,
113
- resourcePath: effectEntryFile,
114
- prefix: Array.isArray(draftOptions.prefix) ? draftOptions.prefix[0] : draftOptions.prefix,
115
- port: Number(draftOptions.port),
116
- target: 'bundle',
117
- requestId: draftOptions.requestId,
118
- requestCreator: draftOptions.requestCreator,
119
- httpMethodDecider: draftOptions.httpMethodDecider,
120
- dataPlatformBatch: draftOptions.effectDataPlatformBatch
121
- });
122
- if (generatedEffectClient) {
123
- const targetTypeFile = effectFileDetails.targetDir.replace(/\.js$/, '.d.ts');
124
- await (0, external_files_js_namespaceObject.writeTargetFile)(effectFileDetails.absTargetDir, generatedEffectClient.code);
125
- await (0, external_files_js_namespaceObject.writeTargetFile)(external_path_default().resolve(targetTypeFile), generatedEffectClient.declaration);
126
- generatedSourceList.push(effectFileDetails);
127
- }
128
- }
129
- }
130
94
  utils_namespaceObject.logger.info("Client bundle generate succeed");
131
95
  } catch (error) {
132
- if ((0, external_type_facade_js_namespaceObject.isMissingClientDeclarationError)(error)) throw error;
96
+ if ((0, external_type_facade_js_namespaceObject.isMissingClientDeclarationError)(error) || error instanceof bff_core_namespaceObject.ClientCodegenError) throw error;
133
97
  utils_namespaceObject.logger.error(`Client bundle generate failed: ${error}`);
134
98
  }
99
+ let packageDependencies;
100
+ if (integration) {
101
+ const artifacts = await integration.modifyArtifacts({
102
+ generation: integration.generation,
103
+ additionalArtifacts: []
104
+ });
105
+ if (artifacts.generation !== integration.generation) throw new Error('BFF artifacts must preserve generation identity.');
106
+ const sourcePaths = new Set(generatedSourceList.map((file)=>external_path_default().resolve(file.resourcePath)));
107
+ const exportKeys = new Set(generatedSourceList.map((file)=>file.exportKey));
108
+ const outputPaths = new Set(generatedSourceList.map((file)=>external_path_default().resolve(file.absTargetDir)));
109
+ const additionalFiles = artifacts.additionalArtifacts.map((artifact)=>{
110
+ const relative = artifact.sourcePath;
111
+ const resourcePath = external_path_default().resolve(draftOptions.apiDir, relative);
112
+ if (!relative || external_path_default().isAbsolute(relative) || relative.includes('\\') || external_path_default().relative(draftOptions.apiDir, resourcePath).split(external_path_default().sep).includes('..') || external_path_default().relative(draftOptions.apiDir, resourcePath).split(external_path_default().sep).join('/') !== relative || !/\.[cm]?[jt]sx?$/.test(relative)) throw new Error(`Invalid BFF client artifact source path: ${relative}`);
113
+ const file = (0, external_files_js_namespaceObject.createFileDetails)({
114
+ appDirectory: draftOptions.appDir,
115
+ baseDirectory: draftOptions.apiDir,
116
+ resourcePath,
117
+ source: '',
118
+ relativeDistPath: draftOptions.relativeDistPath
119
+ });
120
+ if (sourcePaths.has(resourcePath) || exportKeys.has(file.exportKey) || outputPaths.has(external_path_default().resolve(file.absTargetDir))) throw new Error(`BFF client artifact collision: ${relative}`);
121
+ sourcePaths.add(resourcePath);
122
+ exportKeys.add(file.exportKey);
123
+ outputPaths.add(external_path_default().resolve(file.absTargetDir));
124
+ return {
125
+ file,
126
+ artifact
127
+ };
128
+ });
129
+ for (const { file, artifact } of additionalFiles){
130
+ await (0, external_files_js_namespaceObject.writeTargetFile)(file.absTargetDir, artifact.code);
131
+ await (0, external_files_js_namespaceObject.writeTargetFile)(file.absTargetDir.replace(/\.js$/, '.d.ts'), artifact.declaration);
132
+ generatedSourceList.push(file);
133
+ }
134
+ packageDependencies = await integration.beforePublish() || void 0;
135
+ }
135
136
  if (generatedSourceList.length > 0) await (0, external_write_package_js_namespaceObject.writeClientModuleBoundary)(draftOptions.appDir, draftOptions.relativeDistPath);
136
- await (0, external_write_package_js_namespaceObject.setPackage)(generatedSourceList, draftOptions.appDir, draftOptions.relativeDistPath);
137
- return generatedEffectClient;
137
+ await (0, external_write_package_js_namespaceObject.setPackage)(generatedSourceList, draftOptions.appDir, draftOptions.relativeDistPath, packageDependencies);
138
+ return null;
138
139
  }
139
140
  const generate = clientGenerator;
140
141
  exports.clientGenerator = __webpack_exports__.clientGenerator;
@@ -90,7 +90,7 @@ function mergePackageJson(packageJson, files, typesVersion, exports1, relativeDi
90
90
  }).map(([key])=>key);
91
91
  if (typeConflicts.length > 0) throw new Error(`[plugin-bff] package.json typesVersions conflict on keys: ${typeConflicts.sort().join(', ')}. Rename these keys or move them outside "${external_files_js_namespaceObject.TYPE_PREFIX}" namespace.`);
92
92
  Object.keys(starTypes).forEach((key)=>{
93
- if (generatedTypeKeys.has(key) || key.startsWith(external_files_js_namespaceObject.TYPE_PREFIX)) delete starTypes[key];
93
+ if (generatedTypeKeys.has(key) || key.startsWith(external_files_js_namespaceObject.TYPE_PREFIX) || key === external_files_js_namespaceObject.RUNTIME_DIR && isManagedTypeEntry(starTypes[key])) delete starTypes[key];
94
94
  });
95
95
  typesVersions['*'] = {
96
96
  ...starTypes,
@@ -107,7 +107,7 @@ function mergePackageJson(packageJson, files, typesVersion, exports1, relativeDi
107
107
  }).map(([key])=>key);
108
108
  if (exportConflicts.length > 0) throw new Error(`[plugin-bff] package.json exports conflict on keys: ${exportConflicts.sort().join(', ')}. Rename these exports or move them outside "${external_files_js_namespaceObject.EXPORT_PREFIX}" namespace.`);
109
109
  Object.keys(packageExports).forEach((key)=>{
110
- if (generatedExportKeys.has(key) || key.startsWith(external_files_js_namespaceObject.EXPORT_PREFIX)) delete packageExports[key];
110
+ if (generatedExportKeys.has(key) || key.startsWith(external_files_js_namespaceObject.EXPORT_PREFIX) || key === `./${external_files_js_namespaceObject.RUNTIME_DIR}` && isManagedExportEntry(packageExports[key])) delete packageExports[key];
111
111
  });
112
112
  Object.assign(packageExports, exports1);
113
113
  }
@@ -52,10 +52,19 @@ async function writeClientModuleBoundary(appDirectory, relativeDistPath) {
52
52
  type: 'module'
53
53
  }, null, 2)}\n`);
54
54
  }
55
- async function setPackage(files, appDirectory, relativeDistPath) {
55
+ async function setPackage(files, appDirectory, relativeDistPath, packageDependencies = {}) {
56
56
  const packagePath = external_path_default().resolve(appDirectory, './package.json');
57
57
  const packageContent = await utils_namespaceObject.fs.readFile(packagePath, 'utf8');
58
58
  const packageJson = JSON.parse(packageContent);
59
+ for (const [name, specifier] of Object.entries(packageDependencies)){
60
+ if (!name || 'string' != typeof specifier || !specifier.trim()) throw new Error(`Invalid BFF SDK dependency: ${name}`);
61
+ const existing = packageJson.dependencies?.[name];
62
+ if (void 0 !== existing && existing !== specifier) throw new Error(`package.json dependency conflict for ${name}: ${existing} versus ${specifier}`);
63
+ }
64
+ if (Object.keys(packageDependencies).length > 0) packageJson.dependencies = {
65
+ ...packageJson.dependencies,
66
+ ...packageDependencies
67
+ };
59
68
  const sortedFiles = [
60
69
  ...files
61
70
  ].sort((a, b)=>a.exportKey.localeCompare(b.exportKey));
@@ -112,6 +121,14 @@ async function setPackage(files, appDirectory, relativeDistPath) {
112
121
  types: (0, external_files_js_namespaceObject.toPosixPath)(`./${relativeDistPath}/${external_files_js_namespaceObject.RUNTIME_DIR}/index.d.ts`)
113
122
  }
114
123
  });
124
+ if (0 === files.length) {
125
+ Reflect.deleteProperty(typesVersions['*'], `${external_files_js_namespaceObject.API_DIR}/*`);
126
+ Reflect.deleteProperty(exports1, `./${external_files_js_namespaceObject.API_DIR}/*`);
127
+ }
128
+ if (!utils_namespaceObject.fs.existsSync(external_path_default().resolve(appDirectory, relativeDistPath, external_files_js_namespaceObject.RUNTIME_DIR, 'index.js'))) {
129
+ Reflect.deleteProperty(typesVersions['*'], external_files_js_namespaceObject.RUNTIME_DIR);
130
+ Reflect.deleteProperty(exports1, `./${external_files_js_namespaceObject.RUNTIME_DIR}`);
131
+ }
115
132
  (0, external_package_json_js_namespaceObject.mergePackageJson)(packageJson, addFiles, typesVersions, exports1, relativeDistPath);
116
133
  await utils_namespaceObject.fs.promises.writeFile(packagePath, `${JSON.stringify(packageJson, null, 2)}\n`);
117
134
  }
@@ -37,107 +37,50 @@ var __webpack_require__ = {};
37
37
  var __webpack_exports__ = {};
38
38
  __webpack_require__.r(__webpack_exports__);
39
39
  __webpack_require__.d(__webpack_exports__, {
40
- API_DIR: ()=>API_DIR,
41
- DIST_DIR: ()=>DIST_DIR,
42
- EFFECT_ENTRY: ()=>EFFECT_ENTRY,
43
- LAMBDA_DIR: ()=>LAMBDA_DIR,
44
- OPERATION_CONTRACTS_JSON: ()=>OPERATION_CONTRACTS_JSON,
45
- PACKAGE_NAME: ()=>PACKAGE_NAME,
46
- PREFIX: ()=>PREFIX,
47
- REQUEST_ID: ()=>REQUEST_ID,
48
- RUNTIME_FRAMEWORK: ()=>RUNTIME_FRAMEWORK,
49
- crossProjectApiPlugin: ()=>crossProjectApiPlugin,
50
- default: ()=>utils_crossProjectApiPlugin
40
+ createCrossProjectApiPlugin: ()=>createCrossProjectApiPlugin,
41
+ default: ()=>crossProjectApiPlugin
51
42
  });
52
43
  const external_path_namespaceObject = require("path");
53
44
  var external_path_default = /*#__PURE__*/ __webpack_require__.n(external_path_namespaceObject);
54
- const PACKAGE_NAME = '{packageName}';
55
- const REQUEST_ID = '{requestId}';
56
- const PREFIX = '{prefix}';
57
- const API_DIR = '{apiDirectory}';
58
- const LAMBDA_DIR = '{lambdaDirectory}';
59
- const DIST_DIR = '{distDirectory}';
60
- const RUNTIME_FRAMEWORK = '{runtimeFramework}';
61
- const EFFECT_ENTRY = '{effectEntry}';
62
- const OPERATION_CONTRACTS_JSON = '{operationContracts}';
63
- const NODE_MODULES = 'node_modules';
64
- const crossProjectApiPlugin = ()=>({
45
+ const createCrossProjectApiPlugin = (options)=>({
65
46
  name: '@modern-js/plugin-independent-bff',
66
47
  post: [
67
48
  '@modern-js/plugin-bff'
68
49
  ],
69
50
  setup: (api)=>{
70
- api.modifyResolvedConfig((resolvedConfig)=>{
71
- const { appDirectory: originAppDirectory } = api.getAppContext();
72
- const sdkPath = external_path_default().join(originAppDirectory, NODE_MODULES, PACKAGE_NAME);
73
- const sdkDistPath = external_path_default().join(sdkPath, DIST_DIR);
74
- const effectEntry = EFFECT_ENTRY ? external_path_default().join(sdkDistPath, EFFECT_ENTRY) : void 0;
75
- const apiDirectory = effectEntry ? external_path_default().dirname(effectEntry) : external_path_default().join(sdkDistPath, API_DIR);
76
- const lambdaDirectory = external_path_default().resolve(sdkDistPath, LAMBDA_DIR);
51
+ api.modifyResolvedConfig(async (resolvedConfig)=>{
52
+ const { appDirectory } = api.getAppContext();
53
+ const sdkDirectory = external_path_default().join(appDirectory, 'node_modules', options.packageName);
54
+ const sdkDistDirectory = external_path_default().join(sdkDirectory, options.relativeDistPath);
55
+ const apiDirectory = external_path_default().join(sdkDistDirectory, options.relativeApiPath);
56
+ const lambdaDirectory = external_path_default().resolve(sdkDistDirectory, options.relativeLambdaPath);
57
+ const configuredPrefix = api.getConfig()?.bff?.prefix;
58
+ if (configuredPrefix) {
59
+ const isSamePrefix = Array.isArray(configuredPrefix) ? 1 === configuredPrefix.length && configuredPrefix[0] === options.prefix : configuredPrefix === options.prefix;
60
+ 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}".`);
61
+ }
77
62
  api.updateAppContext({
78
63
  apiDirectory,
79
- lambdaDirectory,
80
- bffRuntimeFramework: RUNTIME_FRAMEWORK
64
+ lambdaDirectory
81
65
  });
82
- const config = api.getConfig();
83
- const configuredPrefix = config?.bff?.prefix;
84
- if (configuredPrefix) {
85
- const isSamePrefix = Array.isArray(configuredPrefix) ? 1 === configuredPrefix.length && configuredPrefix[0] === PREFIX : configuredPrefix === PREFIX;
86
- 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}".`);
87
- }
88
- const configuredRuntimeFramework = config?.bff?.runtimeFramework;
89
- 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}".`);
90
66
  resolvedConfig.bff ??= {};
91
- resolvedConfig.bff.prefix = PREFIX;
92
- resolvedConfig.bff.runtimeFramework = RUNTIME_FRAMEWORK;
93
- if (EFFECT_ENTRY) resolvedConfig.bff.effect = {
94
- ...resolvedConfig.bff.effect,
95
- entry: effectEntry
96
- };
67
+ resolvedConfig.bff.prefix = options.prefix;
97
68
  resolvedConfig.bff.isCrossProjectServer = true;
98
- resolvedConfig.bff.requestId = resolvedConfig.bff.requestId || config?.bff?.requestId || REQUEST_ID || PACKAGE_NAME || 'default';
99
- const generatedOperationContracts = "{operationContracts}" === OPERATION_CONTRACTS_JSON ? {} : JSON.parse(OPERATION_CONTRACTS_JSON);
100
- resolvedConfig.bff.crossProjectPolicy = {
101
- ...resolvedConfig.bff.crossProjectPolicy || {},
102
- enabled: resolvedConfig.bff.crossProjectPolicy?.enabled ?? true,
103
- requireEnvelope: resolvedConfig.bff.crossProjectPolicy?.requireEnvelope ?? true,
104
- requireOperationContext: resolvedConfig.bff.crossProjectPolicy?.requireOperationContext ?? true,
105
- requireOperationContextDetails: resolvedConfig.bff.crossProjectPolicy?.requireOperationContextDetails ?? true,
106
- requireOperationSchemaHash: resolvedConfig.bff.crossProjectPolicy?.requireOperationSchemaHash ?? true,
107
- requireOperationVersion: resolvedConfig.bff.crossProjectPolicy?.requireOperationVersion ?? true,
108
- allowUnknownOperations: resolvedConfig.bff.crossProjectPolicy?.allowUnknownOperations ?? false,
109
- expectedOperationContracts: {
110
- ...resolvedConfig.bff.crossProjectPolicy?.expectedOperationContracts || {},
111
- ...generatedOperationContracts
112
- }
113
- };
114
- return resolvedConfig;
69
+ return options.modifyResolvedConfig ? options.modifyResolvedConfig(resolvedConfig, {
70
+ sdkDirectory,
71
+ sdkDistDirectory,
72
+ apiDirectory,
73
+ lambdaDirectory,
74
+ api
75
+ }) : resolvedConfig;
115
76
  });
116
77
  }
117
78
  });
118
- const utils_crossProjectApiPlugin = crossProjectApiPlugin;
119
- exports.API_DIR = __webpack_exports__.API_DIR;
120
- exports.DIST_DIR = __webpack_exports__.DIST_DIR;
121
- exports.EFFECT_ENTRY = __webpack_exports__.EFFECT_ENTRY;
122
- exports.LAMBDA_DIR = __webpack_exports__.LAMBDA_DIR;
123
- exports.OPERATION_CONTRACTS_JSON = __webpack_exports__.OPERATION_CONTRACTS_JSON;
124
- exports.PACKAGE_NAME = __webpack_exports__.PACKAGE_NAME;
125
- exports.PREFIX = __webpack_exports__.PREFIX;
126
- exports.REQUEST_ID = __webpack_exports__.REQUEST_ID;
127
- exports.RUNTIME_FRAMEWORK = __webpack_exports__.RUNTIME_FRAMEWORK;
128
- exports.crossProjectApiPlugin = __webpack_exports__.crossProjectApiPlugin;
79
+ const crossProjectApiPlugin = createCrossProjectApiPlugin;
80
+ exports.createCrossProjectApiPlugin = __webpack_exports__.createCrossProjectApiPlugin;
129
81
  exports["default"] = __webpack_exports__["default"];
130
82
  for(var __rspack_i in __webpack_exports__)if (-1 === [
131
- "API_DIR",
132
- "DIST_DIR",
133
- "EFFECT_ENTRY",
134
- "LAMBDA_DIR",
135
- "OPERATION_CONTRACTS_JSON",
136
- "PACKAGE_NAME",
137
- "PREFIX",
138
- "REQUEST_ID",
139
- "RUNTIME_FRAMEWORK",
140
- "crossProjectApiPlugin",
83
+ "createCrossProjectApiPlugin",
141
84
  "default"
142
85
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
143
86
  Object.defineProperty(exports, '__esModule', {
@@ -37,40 +37,40 @@ var __webpack_require__ = {};
37
37
  var __webpack_exports__ = {};
38
38
  __webpack_require__.r(__webpack_exports__);
39
39
  __webpack_require__.d(__webpack_exports__, {
40
- default: ()=>utils_pluginGenerator
40
+ default: ()=>pluginGenerator,
41
+ renderBffPlugin: ()=>renderBffPlugin
41
42
  });
42
43
  const utils_namespaceObject = require("@modern-js/utils");
43
44
  const external_path_namespaceObject = require("path");
44
45
  var external_path_default = /*#__PURE__*/ __webpack_require__.n(external_path_namespaceObject);
45
- const external_crossProjectApiPlugin_js_namespaceObject = require("./crossProjectApiPlugin.js");
46
- function replaceContent(source, packageName, requestId, prefix, relativeDistPath, relativeApiPath, relativeLambdaPath, runtimeFramework, relativeEffectEntry, operationContracts) {
47
- const updatedSource = source.replace(new RegExp(external_crossProjectApiPlugin_js_namespaceObject.PACKAGE_NAME, 'g'), packageName).replace(new RegExp(external_crossProjectApiPlugin_js_namespaceObject.REQUEST_ID, 'g'), requestId).replace(new RegExp(external_crossProjectApiPlugin_js_namespaceObject.PREFIX, 'g'), prefix).replace(new RegExp(external_crossProjectApiPlugin_js_namespaceObject.DIST_DIR, 'g'), (0, utils_namespaceObject.normalizeToPosixPath)(relativeDistPath)).replace(new RegExp(external_crossProjectApiPlugin_js_namespaceObject.API_DIR, 'g'), (0, utils_namespaceObject.normalizeToPosixPath)(relativeApiPath)).replace(new RegExp(external_crossProjectApiPlugin_js_namespaceObject.LAMBDA_DIR, 'g'), (0, utils_namespaceObject.normalizeToPosixPath)(relativeLambdaPath)).replace(new RegExp(external_crossProjectApiPlugin_js_namespaceObject.RUNTIME_FRAMEWORK, 'g'), runtimeFramework).replace(new RegExp(external_crossProjectApiPlugin_js_namespaceObject.EFFECT_ENTRY, 'g'), (0, utils_namespaceObject.normalizeToPosixPath)(relativeEffectEntry)).replace(`'${external_crossProjectApiPlugin_js_namespaceObject.OPERATION_CONTRACTS_JSON}'`, ()=>JSON.stringify(JSON.stringify(operationContracts)));
48
- return updatedSource;
46
+ async function renderBffPlugin(options) {
47
+ const packageJson = await utils_namespaceObject.fs.readJSON(external_path_default().resolve(options.appDirectory, 'package.json'));
48
+ const descriptor = {
49
+ packageName: packageJson.name,
50
+ prefix: options.prefix,
51
+ relativeDistPath: (0, utils_namespaceObject.normalizeToPosixPath)(options.relativeDistPath),
52
+ relativeApiPath: (0, utils_namespaceObject.normalizeToPosixPath)(options.relativeApiPath),
53
+ relativeLambdaPath: (0, utils_namespaceObject.normalizeToPosixPath)(options.relativeLambdaPath)
54
+ };
55
+ return {
56
+ 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`,
57
+ declaration: `import type { AppTools, CliPlugin } from '@modern-js/app-tools';
58
+ export declare const crossProjectApiPlugin: () => CliPlugin<AppTools>;
59
+ `
60
+ };
49
61
  }
50
- async function pluginGenerator({ prefix, appDirectory, requestId, relativeDistPath, relativeApiPath, relativeLambdaPath, runtimeFramework, relativeEffectEntry, operationContracts }) {
51
- try {
52
- const packageContent = await utils_namespaceObject.fs.readFile(external_path_default().resolve(appDirectory, './package.json'), 'utf8');
53
- const packageJson = JSON.parse(packageContent);
54
- const pluginDir = external_path_default().resolve(appDirectory, `./${relativeDistPath}`, 'plugin');
55
- const pluginPath = external_path_default().join(pluginDir, 'index.js');
56
- const pluginTemplate = await utils_namespaceObject.fs.readFile(external_path_default().resolve(__dirname, 'crossProjectApiPlugin.js'), 'utf8');
57
- const updatedPlugin = replaceContent(pluginTemplate, packageJson.name, requestId, prefix, relativeDistPath, relativeApiPath, relativeLambdaPath, runtimeFramework, relativeEffectEntry, operationContracts);
58
- await utils_namespaceObject.fs.ensureFile(pluginPath);
59
- await utils_namespaceObject.fs.writeFile(pluginPath, updatedPlugin);
60
- const typeContent = `import type { AppTools, CliPlugin } from '@modern-js/app-tools';
61
- export declare const crossProjectApiPlugin: () => CliPlugin<AppTools>`;
62
- const pluginTypePath = external_path_default().join(pluginDir, 'index.d.ts');
63
- await utils_namespaceObject.fs.ensureFile(pluginTypePath);
64
- await utils_namespaceObject.fs.writeFile(pluginTypePath, typeContent);
65
- utils_namespaceObject.logger.info('Api plugin generate succeed');
66
- } catch (error) {
67
- utils_namespaceObject.logger.error('Api plugin generate failed:', error);
68
- }
62
+ async function pluginGenerator(options, rendered) {
63
+ const module = rendered ?? await renderBffPlugin(options);
64
+ const directory = external_path_default().resolve(options.appDirectory, options.relativeDistPath, 'plugin');
65
+ await utils_namespaceObject.fs.outputFile(external_path_default().join(directory, 'index.js'), module.code);
66
+ await utils_namespaceObject.fs.outputFile(external_path_default().join(directory, 'index.d.ts'), module.declaration);
67
+ utils_namespaceObject.logger.info('Api plugin generate succeed');
69
68
  }
70
- const utils_pluginGenerator = pluginGenerator;
71
69
  exports["default"] = __webpack_exports__["default"];
70
+ exports.renderBffPlugin = __webpack_exports__.renderBffPlugin;
72
71
  for(var __rspack_i in __webpack_exports__)if (-1 === [
73
- "default"
72
+ "default",
73
+ "renderBffPlugin"
74
74
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
75
75
  Object.defineProperty(exports, '__esModule', {
76
76
  value: true
@@ -37,88 +37,39 @@ var __webpack_require__ = {};
37
37
  var __webpack_exports__ = {};
38
38
  __webpack_require__.r(__webpack_exports__);
39
39
  __webpack_require__.d(__webpack_exports__, {
40
- default: ()=>utils_runtimeGenerator
40
+ default: ()=>runtimeGenerator,
41
+ renderBffRuntime: ()=>renderBffRuntime
41
42
  });
42
- const cross_project_generation_namespaceObject = require("@modern-js/plugin-bff-extensions/cross-project-generation");
43
+ const external_node_url_namespaceObject = require("node:url");
43
44
  const utils_namespaceObject = require("@modern-js/utils");
44
45
  const external_path_namespaceObject = require("path");
45
46
  var external_path_default = /*#__PURE__*/ __webpack_require__.n(external_path_namespaceObject);
46
- const getPackageName = (appDirectory)=>{
47
- try {
48
- const packageJsonPath = external_path_default().resolve(appDirectory, './package.json');
49
- const packageJson = require(packageJsonPath);
50
- return packageJson.name;
51
- } catch (error) {
52
- return;
53
- }
54
- };
55
- async function runtimeGenerator({ runtime, appDirectory, relativeDistPath, packageName }) {
56
- const pluginDir = external_path_default().resolve(appDirectory, `./${relativeDistPath}`, 'runtime');
57
- const requestId = packageName || getPackageName(appDirectory) || process.env.npm_package_name || 'default';
58
- const runtimeImportPath = JSON.stringify(runtime);
59
- const requestIdValue = JSON.stringify(requestId);
60
- const source = `'use strict'; const { configure: _configure } = require(${runtimeImportPath});
61
- const defaultSecureOptions = ${(0, cross_project_generation_namespaceObject.renderProducerRuntimeDefaults)(requestIdValue)};
62
- const initProducerClient = (options) => {
63
- return _configure({
64
- ...defaultSecureOptions,
65
- ...options,
66
- identityBinding: {
67
- ...defaultSecureOptions.identityBinding,
68
- ...(options && options.identityBinding ? options.identityBinding : {}),
69
- },
70
- operationContract: {
71
- ...defaultSecureOptions.operationContract,
72
- ...(options && options.operationContract ? options.operationContract : {}),
73
- },
74
- });
75
- }
76
- const configure = initProducerClient;
77
- Object.defineProperty(exports, '__esModule', { value: true });
78
- exports.initProducerClient = initProducerClient;
79
- exports.configure = configure;
80
- `;
81
- const pluginPath = external_path_default().join(pluginDir, 'index.js');
82
- await utils_namespaceObject.fs.ensureFile(pluginPath);
83
- await utils_namespaceObject.fs.writeFile(pluginPath, source);
84
- const tsSource = `type ProducerRuntimeModule = typeof import(${runtimeImportPath});
85
- type ProducerClientOptions = ProducerRuntimeModule extends {
86
- configure: (options: infer TOptions) => unknown;
87
- }
88
- ? TOptions
89
- : {
90
- request?: typeof fetch;
91
- interceptor?: (request: typeof fetch) => typeof fetch;
92
- allowedHeaders?: string[];
93
- requireEnvelope?: boolean;
94
- allowCrossOriginEnvelope?: boolean;
95
- identityBinding?: {
96
- enabled?: boolean;
97
- strict?: boolean;
98
- protectedHeaders?: string[];
99
- };
100
- operationContract?: {
101
- enabled?: boolean;
102
- strict?: boolean;
103
- requireSchemaHash?: boolean;
104
- requireOperationVersion?: boolean;
105
- };
106
- setDomain?: (ops?: {
107
- target: 'server' | 'browser';
108
- requestId?: string;
109
- }) => string;
110
- requestId?: string;
111
- };
112
- export declare const initProducerClient: (options?: ProducerClientOptions) => ReturnType<ProducerRuntimeModule['configure']>;
113
- export declare const configure: typeof initProducerClient;`;
114
- const pluginTypePath = external_path_default().join(pluginDir, 'index.d.ts');
115
- await utils_namespaceObject.fs.ensureFile(pluginTypePath);
116
- await utils_namespaceObject.fs.writeFile(pluginTypePath, tsSource);
47
+ function renderBffRuntime(options) {
48
+ const packagePath = external_path_default().resolve(options.appDirectory, 'package.json');
49
+ const packageJson = utils_namespaceObject.fs.existsSync(packagePath) ? utils_namespaceObject.fs.readJSONSync(packagePath) : {};
50
+ const requestId = options.packageName || packageJson.name || process.env.npm_package_name || 'default';
51
+ const runtime = JSON.stringify(options.runtime);
52
+ const esmRuntime = JSON.stringify(external_path_default().isAbsolute(options.runtime) ? (0, external_node_url_namespaceObject.pathToFileURL)(options.runtime).href : options.runtime);
53
+ return {
54
+ 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`,
55
+ declaration: `type Runtime = typeof import(${runtime});
56
+ export declare const initProducerClient: (options?: Parameters<Runtime['configure']>[0]) => ReturnType<Runtime['configure']>;
57
+ export declare const configure: typeof initProducerClient;
58
+ `
59
+ };
60
+ }
61
+ async function runtimeGenerator(options, rendered) {
62
+ const directory = external_path_default().resolve(options.appDirectory, options.relativeDistPath, 'runtime');
63
+ if (null === rendered) return void await utils_namespaceObject.fs.remove(directory);
64
+ const module = rendered ?? renderBffRuntime(options);
65
+ await utils_namespaceObject.fs.outputFile(external_path_default().join(directory, 'index.js'), module.code);
66
+ await utils_namespaceObject.fs.outputFile(external_path_default().join(directory, 'index.d.ts'), module.declaration);
117
67
  }
118
- const utils_runtimeGenerator = runtimeGenerator;
119
68
  exports["default"] = __webpack_exports__["default"];
69
+ exports.renderBffRuntime = __webpack_exports__.renderBffRuntime;
120
70
  for(var __rspack_i in __webpack_exports__)if (-1 === [
121
- "default"
71
+ "default",
72
+ "renderBffRuntime"
122
73
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
123
74
  Object.defineProperty(exports, '__esModule', {
124
75
  value: true