@bleedingdev/modern-js-plugin-bff-build-extensions 3.9.0-ultramodern.8 → 3.9.3-ultramodern.1

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.
@@ -33,7 +33,6 @@ __webpack_require__.d(__webpack_exports__, {
33
33
  });
34
34
  const bff_core_namespaceObject = require("@modern-js/bff-core");
35
35
  const node_namespaceObject = require("@modern-js/server-runtime-extensions/bff-policy/node");
36
- const utils_namespaceObject = require("@modern-js/utils");
37
36
  const BFF_REQUEST_RUNTIME = '@modern-js/runtime-extensions/request-policy';
38
37
  function registerBffClientArtifacts(api, metadata) {
39
38
  api.modifyBffClientArtifacts(async (context)=>{
@@ -68,11 +67,15 @@ function registerBffClientArtifacts(api, metadata) {
68
67
  httpMethodDecider: generation.httpMethodDecider,
69
68
  isBuild: true
70
69
  });
71
- const packageJson = await utils_namespaceObject.fs.readJSON(utils_namespaceObject.upath.join(generation.appDirectory, 'package.json'));
72
70
  const operationContracts = generation.existLambda ? (0, node_namespaceObject.buildOperationContractMap)({
73
71
  handlers: await router.getApiHandlers(),
74
- requestId: generation.requestId,
75
- operationVersion: (0, node_namespaceObject.deriveOperationVersion)(packageJson.version)
72
+ ...(0, node_namespaceObject.resolveOperationProducer)({
73
+ directories: [
74
+ generation.apiDirectory,
75
+ generation.appDirectory
76
+ ],
77
+ requestId: generation.requestId || 'default'
78
+ })
76
79
  }) : {};
77
80
  metadata.set(generation, {
78
81
  runtimeFramework: 'hono',
@@ -40,6 +40,18 @@ function registerBffCompilation(api) {
40
40
  const globals = serialized.get(context);
41
41
  if (!globals) throw new Error('BFF compilation completed without its before hook.');
42
42
  serialized.delete(context);
43
+ const appContext = api.getAppContext();
44
+ const resolveIdentity = appContext.resolveBffRuntimeBuildIdentity;
45
+ if (true !== appContext.apiOnly && void 0 !== resolveIdentity) {
46
+ if (appContext.appDirectory !== context.appDirectory) throw new Error('BFF runtime build identity provider does not belong to this application.');
47
+ if ('function' != typeof resolveIdentity) throw new Error('BFF runtime build identity provider is invalid.');
48
+ const identity = await resolveIdentity(context);
49
+ if (null === identity || 'object' != typeof identity || !Object.isFrozen(identity)) throw new Error('BFF runtime build identity must be immutable.');
50
+ const { buildMarker, sourceRevision } = identity;
51
+ if ('string' != typeof buildMarker || !/^[0-9a-f]{64}$/u.test(buildMarker) || 'string' != typeof sourceRevision || 0 === sourceRevision.trim().length) throw new Error('BFF runtime build identity is not finalized.');
52
+ globals.ULTRAMODERN_BUILD_MARKER = JSON.stringify(buildMarker);
53
+ globals.ULTRAMODERN_SOURCE_REVISION = JSON.stringify(sourceRevision);
54
+ }
43
55
  await (0, external_server_global_vars_js_namespaceObject.transformServerGlobalVars)([
44
56
  ...context.outputDirectories
45
57
  ], globals);
@@ -1,14 +1,5 @@
1
1
  "use strict";
2
2
  var __webpack_require__ = {};
3
- (()=>{
4
- __webpack_require__.n = (module)=>{
5
- var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
- __webpack_require__.d(getter, {
7
- a: getter
8
- });
9
- return getter;
10
- };
11
- })();
12
3
  (()=>{
13
4
  __webpack_require__.d = (exports1, getters, values)=>{
14
5
  var define = (defs, kind)=>{
@@ -39,19 +30,18 @@ __webpack_require__.r(__webpack_exports__);
39
30
  __webpack_require__.d(__webpack_exports__, {
40
31
  modifyClient: ()=>modifyClient
41
32
  });
42
- const external_node_path_namespaceObject = require("node:path");
43
- var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
44
33
  const node_namespaceObject = require("@modern-js/server-runtime-extensions/bff-policy/node");
45
34
  const REQUEST_RUNTIME = '@modern-js/runtime-extensions/request-policy';
46
35
  const modifyClient = (draft, context)=>{
47
36
  const { appDir, requestId } = context.options;
48
37
  draft.requestCreator = context.options.requestCreator || REQUEST_RUNTIME;
49
- let version;
50
- try {
51
- version = require(external_node_path_default().resolve(appDir, 'package.json')).version;
52
- } catch {}
53
- const operationVersion = (0, node_namespaceObject.deriveOperationVersion)(version);
54
- const normalizedRequestId = requestId || 'default';
38
+ const { operationVersion, requestId: normalizedRequestId } = (0, node_namespaceObject.resolveOperationProducer)({
39
+ directories: [
40
+ context.options.apiDir,
41
+ appDir
42
+ ],
43
+ requestId: requestId || 'default'
44
+ });
55
45
  const operationContracts = (0, node_namespaceObject.buildOperationContractMap)({
56
46
  handlers: [
57
47
  ...context.handlerInfos
package/dist/cjs/index.js CHANGED
@@ -37,6 +37,7 @@ const utils_namespaceObject = require("@modern-js/utils");
37
37
  const external_client_artifacts_js_namespaceObject = require("./client-artifacts.js");
38
38
  const external_compile_js_namespaceObject = require("./compile.js");
39
39
  const external_generated_entries_js_namespaceObject = require("./generated-entries.js");
40
+ const external_self_module_js_namespaceObject = require("./self-module.js");
40
41
  const bffPlugin = ()=>({
41
42
  name: '@modern-js/plugin-bff-build-extensions',
42
43
  usePlugins: [
@@ -57,7 +58,7 @@ const bffPlugin = ()=>({
57
58
  bff: {
58
59
  requestCreator: external_client_artifacts_js_namespaceObject.BFF_REQUEST_RUNTIME,
59
60
  runtimeCreateRequest: external_client_artifacts_js_namespaceObject.BFF_REQUEST_RUNTIME,
60
- clientCodegenPlugin: require.resolve('@modern-js/plugin-bff-build-extensions/hono-client-codegen')
61
+ clientCodegenPlugin: (0, external_self_module_js_namespaceObject.resolveSelfModule)('hono-client-codegen')
61
62
  }
62
63
  }));
63
64
  const runtimeFramework = api.getConfig()?.bff?.runtimeFramework;
@@ -69,19 +70,26 @@ const bffPlugin = ()=>({
69
70
  const nativePlugins = plugins.filter((plugin)=>'@modern-js/plugin-bff/server-plugin' === plugin.name);
70
71
  if (1 !== nativePlugins.length) throw new Error('Expected exactly one native BFF server plugin.');
71
72
  const native = nativePlugins[0];
72
- const runtimeAdapters = native.options?.runtimeAdapters ?? {};
73
- const effect = '@modern-js/plugin-bff-extensions/effect-adapter';
74
73
  const honoRouteBinder = '@modern-js/plugin-bff-extensions/hono/node';
75
74
  if (native.options?.honoRouteBinder !== void 0 && native.options.honoRouteBinder !== honoRouteBinder) throw new Error('The Hono BFF route binder is already configured.');
76
- if (void 0 !== runtimeAdapters.effect && runtimeAdapters.effect !== effect) throw new Error('The Effect BFF runtime adapter is already configured.');
75
+ if ('hono' !== runtimeFramework) {
76
+ plugins.splice(plugins.indexOf(native), 1, {
77
+ name: '@modern-js/plugin-bff-extensions/effect-server'
78
+ });
79
+ return {
80
+ plugins
81
+ };
82
+ }
77
83
  native.options = {
78
84
  ...native.options,
79
- honoRouteBinder,
80
- runtimeAdapters: {
81
- ...runtimeAdapters,
82
- effect
83
- }
85
+ honoRouteBinder
84
86
  };
87
+ native.includeEntries = [
88
+ ...new Set([
89
+ ...native.includeEntries ?? [],
90
+ honoRouteBinder
91
+ ])
92
+ ];
85
93
  return {
86
94
  plugins
87
95
  };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.r = (exports1)=>{
5
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
6
+ value: 'Module'
7
+ });
8
+ Object.defineProperty(exports1, '__esModule', {
9
+ value: true
10
+ });
11
+ };
12
+ })();
13
+ var __webpack_exports__ = {};
14
+ __webpack_require__.r(__webpack_exports__);
15
+ for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
16
+ Object.defineProperty(exports, '__esModule', {
17
+ value: true
18
+ });
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ const __rslib_import_meta_url__ = /*#__PURE__*/ function() {
3
+ return "u" < typeof document ? new (require('url'.replace('', ''))).URL('file:' + __filename).href : document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href;
4
+ }();
5
+ var __webpack_require__ = {};
6
+ (()=>{
7
+ __webpack_require__.d = (exports1, getters, values)=>{
8
+ var define = (defs, kind)=>{
9
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
10
+ enumerable: true,
11
+ [kind]: defs[key]
12
+ });
13
+ };
14
+ define(getters, "get");
15
+ define(values, "value");
16
+ };
17
+ })();
18
+ (()=>{
19
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
20
+ })();
21
+ (()=>{
22
+ __webpack_require__.r = (exports1)=>{
23
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
24
+ value: 'Module'
25
+ });
26
+ Object.defineProperty(exports1, '__esModule', {
27
+ value: true
28
+ });
29
+ };
30
+ })();
31
+ var __webpack_exports__ = {};
32
+ __webpack_require__.r(__webpack_exports__);
33
+ __webpack_require__.d(__webpack_exports__, {
34
+ resolveSelfModule: ()=>resolveSelfModule
35
+ });
36
+ const external_node_module_namespaceObject = require("node:module");
37
+ const selfRequire = (0, external_node_module_namespaceObject.createRequire)(__rslib_import_meta_url__);
38
+ const resolveSelfModule = (name)=>{
39
+ for (const extension of [
40
+ '.js',
41
+ '.mjs',
42
+ '.cjs',
43
+ '.ts'
44
+ ])try {
45
+ return selfRequire.resolve(`./${name}${extension}`);
46
+ } catch {}
47
+ return selfRequire.resolve(`@modern-js/plugin-bff-build-extensions/${name}`);
48
+ };
49
+ exports.resolveSelfModule = __webpack_exports__.resolveSelfModule;
50
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
51
+ "resolveSelfModule"
52
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
53
+ Object.defineProperty(exports, '__esModule', {
54
+ value: true
55
+ });
@@ -32,7 +32,6 @@ __webpack_require__.d(__webpack_exports__, {
32
32
  transformServerGlobalVars: ()=>transformServerGlobalVars
33
33
  });
34
34
  const utils_namespaceObject = require("@modern-js/utils");
35
- const core_namespaceObject = require("@swc/core");
36
35
  const RELEASE_IDENTITY_GLOBAL_NAMES = [
37
36
  'ULTRAMODERN_BUILD_MARKER',
38
37
  'ULTRAMODERN_SOURCE_REVISION',
@@ -77,7 +76,9 @@ const transformServerGlobalVars = (outputDirectories, globalVars)=>Promise.resol
77
76
  const sourceMapFilename = `${filename}.map`;
78
77
  return utils_namespaceObject.fs.pathExists(sourceMapFilename).then((sourceMapExists)=>{
79
78
  const inputSourceMapPromise = sourceMapExists ? utils_namespaceObject.fs.readFile(sourceMapFilename, 'utf8') : Promise.resolve(void 0);
80
- return inputSourceMapPromise.then((inputSourceMap)=>(0, core_namespaceObject.transform)(`${releaseIdentityBanner}${source}`, {
79
+ return inputSourceMapPromise.then(async (inputSourceMap)=>{
80
+ const { transform } = await import("@swc/core");
81
+ return transform(`${releaseIdentityBanner}${source}`, {
81
82
  filename,
82
83
  inputSourceMap,
83
84
  sourceMaps: sourceMapExists,
@@ -97,7 +98,8 @@ const transformServerGlobalVars = (outputDirectories, globalVars)=>Promise.resol
97
98
  }
98
99
  }).then((result)=>utils_namespaceObject.fs.writeFile(filename, result.code).then(()=>{
99
100
  if (sourceMapExists && void 0 !== result.map && result.map.length > 0) return utils_namespaceObject.fs.writeFile(sourceMapFilename, result.map);
100
- })));
101
+ }));
102
+ });
101
103
  });
102
104
  }))));
103
105
  }).then(()=>void 0);
@@ -1,6 +1,5 @@
1
1
  import { ApiRouter } from "@modern-js/bff-core";
2
- import { buildOperationContractMap, deriveOperationVersion } from "@modern-js/server-runtime-extensions/bff-policy/node";
3
- import { fs, upath } from "@modern-js/utils";
2
+ import { buildOperationContractMap, resolveOperationProducer } from "@modern-js/server-runtime-extensions/bff-policy/node";
4
3
  const BFF_REQUEST_RUNTIME = '@modern-js/runtime-extensions/request-policy';
5
4
  function registerBffClientArtifacts(api, metadata) {
6
5
  api.modifyBffClientArtifacts(async (context)=>{
@@ -35,11 +34,15 @@ function registerBffClientArtifacts(api, metadata) {
35
34
  httpMethodDecider: generation.httpMethodDecider,
36
35
  isBuild: true
37
36
  });
38
- const packageJson = await fs.readJSON(upath.join(generation.appDirectory, 'package.json'));
39
37
  const operationContracts = generation.existLambda ? buildOperationContractMap({
40
38
  handlers: await router.getApiHandlers(),
41
- requestId: generation.requestId,
42
- operationVersion: deriveOperationVersion(packageJson.version)
39
+ ...resolveOperationProducer({
40
+ directories: [
41
+ generation.apiDirectory,
42
+ generation.appDirectory
43
+ ],
44
+ requestId: generation.requestId || 'default'
45
+ })
43
46
  }) : {};
44
47
  metadata.set(generation, {
45
48
  runtimeFramework: 'hono',
@@ -8,6 +8,18 @@ function registerBffCompilation(api) {
8
8
  const globals = serialized.get(context);
9
9
  if (!globals) throw new Error('BFF compilation completed without its before hook.');
10
10
  serialized.delete(context);
11
+ const appContext = api.getAppContext();
12
+ const resolveIdentity = appContext.resolveBffRuntimeBuildIdentity;
13
+ if (true !== appContext.apiOnly && void 0 !== resolveIdentity) {
14
+ if (appContext.appDirectory !== context.appDirectory) throw new Error('BFF runtime build identity provider does not belong to this application.');
15
+ if ('function' != typeof resolveIdentity) throw new Error('BFF runtime build identity provider is invalid.');
16
+ const identity = await resolveIdentity(context);
17
+ if (null === identity || 'object' != typeof identity || !Object.isFrozen(identity)) throw new Error('BFF runtime build identity must be immutable.');
18
+ const { buildMarker, sourceRevision } = identity;
19
+ if ('string' != typeof buildMarker || !/^[0-9a-f]{64}$/u.test(buildMarker) || 'string' != typeof sourceRevision || 0 === sourceRevision.trim().length) throw new Error('BFF runtime build identity is not finalized.');
20
+ globals.ULTRAMODERN_BUILD_MARKER = JSON.stringify(buildMarker);
21
+ globals.ULTRAMODERN_SOURCE_REVISION = JSON.stringify(sourceRevision);
22
+ }
11
23
  await transformServerGlobalVars([
12
24
  ...context.outputDirectories
13
25
  ], globals);
@@ -1,15 +1,15 @@
1
- import node_path from "node:path";
2
- import { buildOperationContractMap, createOperationSchemaHash, deriveOperationVersion } from "@modern-js/server-runtime-extensions/bff-policy/node";
1
+ import { buildOperationContractMap, createOperationSchemaHash, resolveOperationProducer } from "@modern-js/server-runtime-extensions/bff-policy/node";
3
2
  const REQUEST_RUNTIME = '@modern-js/runtime-extensions/request-policy';
4
3
  const modifyClient = (draft, context)=>{
5
4
  const { appDir, requestId } = context.options;
6
5
  draft.requestCreator = context.options.requestCreator || REQUEST_RUNTIME;
7
- let version;
8
- try {
9
- version = require(node_path.resolve(appDir, 'package.json')).version;
10
- } catch {}
11
- const operationVersion = deriveOperationVersion(version);
12
- const normalizedRequestId = requestId || 'default';
6
+ const { operationVersion, requestId: normalizedRequestId } = resolveOperationProducer({
7
+ directories: [
8
+ context.options.apiDir,
9
+ appDir
10
+ ],
11
+ requestId: requestId || 'default'
12
+ });
13
13
  const operationContracts = buildOperationContractMap({
14
14
  handlers: [
15
15
  ...context.handlerInfos
@@ -4,6 +4,7 @@ import { fs, upath } from "@modern-js/utils";
4
4
  import { BFF_REQUEST_RUNTIME, registerBffClientArtifacts } from "./client-artifacts.mjs";
5
5
  import { registerBffCompilation } from "./compile.mjs";
6
6
  import { registerBffGeneratedEntries } from "./generated-entries.mjs";
7
+ import { resolveSelfModule } from "./self-module.mjs";
7
8
  const src_bffPlugin = ()=>({
8
9
  name: '@modern-js/plugin-bff-build-extensions',
9
10
  usePlugins: [
@@ -24,7 +25,7 @@ const src_bffPlugin = ()=>({
24
25
  bff: {
25
26
  requestCreator: BFF_REQUEST_RUNTIME,
26
27
  runtimeCreateRequest: BFF_REQUEST_RUNTIME,
27
- clientCodegenPlugin: require.resolve('@modern-js/plugin-bff-build-extensions/hono-client-codegen')
28
+ clientCodegenPlugin: resolveSelfModule('hono-client-codegen')
28
29
  }
29
30
  }));
30
31
  const runtimeFramework = api.getConfig()?.bff?.runtimeFramework;
@@ -36,19 +37,26 @@ const src_bffPlugin = ()=>({
36
37
  const nativePlugins = plugins.filter((plugin)=>'@modern-js/plugin-bff/server-plugin' === plugin.name);
37
38
  if (1 !== nativePlugins.length) throw new Error('Expected exactly one native BFF server plugin.');
38
39
  const native = nativePlugins[0];
39
- const runtimeAdapters = native.options?.runtimeAdapters ?? {};
40
- const effect = '@modern-js/plugin-bff-extensions/effect-adapter';
41
40
  const honoRouteBinder = '@modern-js/plugin-bff-extensions/hono/node';
42
41
  if (native.options?.honoRouteBinder !== void 0 && native.options.honoRouteBinder !== honoRouteBinder) throw new Error('The Hono BFF route binder is already configured.');
43
- if (void 0 !== runtimeAdapters.effect && runtimeAdapters.effect !== effect) throw new Error('The Effect BFF runtime adapter is already configured.');
42
+ if ('hono' !== runtimeFramework) {
43
+ plugins.splice(plugins.indexOf(native), 1, {
44
+ name: '@modern-js/plugin-bff-extensions/effect-server'
45
+ });
46
+ return {
47
+ plugins
48
+ };
49
+ }
44
50
  native.options = {
45
51
  ...native.options,
46
- honoRouteBinder,
47
- runtimeAdapters: {
48
- ...runtimeAdapters,
49
- effect
50
- }
52
+ honoRouteBinder
51
53
  };
54
+ native.includeEntries = [
55
+ ...new Set([
56
+ ...native.includeEntries ?? [],
57
+ honoRouteBinder
58
+ ])
59
+ ];
52
60
  return {
53
61
  plugins
54
62
  };
File without changes
@@ -0,0 +1,14 @@
1
+ import { createRequire } from "node:module";
2
+ const selfRequire = createRequire(import.meta.url);
3
+ const resolveSelfModule = (name)=>{
4
+ for (const extension of [
5
+ '.js',
6
+ '.mjs',
7
+ '.cjs',
8
+ '.ts'
9
+ ])try {
10
+ return selfRequire.resolve(`./${name}${extension}`);
11
+ } catch {}
12
+ return selfRequire.resolve(`@modern-js/plugin-bff-build-extensions/${name}`);
13
+ };
14
+ export { resolveSelfModule };
@@ -1,5 +1,4 @@
1
1
  import { applyOptionsChain, fs, upath } from "@modern-js/utils";
2
- import { transform } from "@swc/core";
3
2
  const RELEASE_IDENTITY_GLOBAL_NAMES = [
4
3
  'ULTRAMODERN_BUILD_MARKER',
5
4
  'ULTRAMODERN_SOURCE_REVISION',
@@ -44,7 +43,9 @@ const transformServerGlobalVars = (outputDirectories, globalVars)=>Promise.resol
44
43
  const sourceMapFilename = `${filename}.map`;
45
44
  return fs.pathExists(sourceMapFilename).then((sourceMapExists)=>{
46
45
  const inputSourceMapPromise = sourceMapExists ? fs.readFile(sourceMapFilename, 'utf8') : Promise.resolve(void 0);
47
- return inputSourceMapPromise.then((inputSourceMap)=>transform(`${releaseIdentityBanner}${source}`, {
46
+ return inputSourceMapPromise.then(async (inputSourceMap)=>{
47
+ const { transform } = await import("@swc/core");
48
+ return transform(`${releaseIdentityBanner}${source}`, {
48
49
  filename,
49
50
  inputSourceMap,
50
51
  sourceMaps: sourceMapExists,
@@ -64,7 +65,8 @@ const transformServerGlobalVars = (outputDirectories, globalVars)=>Promise.resol
64
65
  }
65
66
  }).then((result)=>fs.writeFile(filename, result.code).then(()=>{
66
67
  if (sourceMapExists && void 0 !== result.map && result.map.length > 0) return fs.writeFile(sourceMapFilename, result.map);
67
- })));
68
+ }));
69
+ });
68
70
  });
69
71
  }))));
70
72
  }).then(()=>void 0);
@@ -1,7 +1,6 @@
1
1
  import "node:module";
2
2
  import { ApiRouter } from "@modern-js/bff-core";
3
- import { buildOperationContractMap, deriveOperationVersion } from "@modern-js/server-runtime-extensions/bff-policy/node";
4
- import { fs, upath } from "@modern-js/utils";
3
+ import { buildOperationContractMap, resolveOperationProducer } from "@modern-js/server-runtime-extensions/bff-policy/node";
5
4
  const BFF_REQUEST_RUNTIME = '@modern-js/runtime-extensions/request-policy';
6
5
  function registerBffClientArtifacts(api, metadata) {
7
6
  api.modifyBffClientArtifacts(async (context)=>{
@@ -36,11 +35,15 @@ function registerBffClientArtifacts(api, metadata) {
36
35
  httpMethodDecider: generation.httpMethodDecider,
37
36
  isBuild: true
38
37
  });
39
- const packageJson = await fs.readJSON(upath.join(generation.appDirectory, 'package.json'));
40
38
  const operationContracts = generation.existLambda ? buildOperationContractMap({
41
39
  handlers: await router.getApiHandlers(),
42
- requestId: generation.requestId,
43
- operationVersion: deriveOperationVersion(packageJson.version)
40
+ ...resolveOperationProducer({
41
+ directories: [
42
+ generation.apiDirectory,
43
+ generation.appDirectory
44
+ ],
45
+ requestId: generation.requestId || 'default'
46
+ })
44
47
  }) : {};
45
48
  metadata.set(generation, {
46
49
  runtimeFramework: 'hono',
@@ -9,6 +9,18 @@ function registerBffCompilation(api) {
9
9
  const globals = serialized.get(context);
10
10
  if (!globals) throw new Error('BFF compilation completed without its before hook.');
11
11
  serialized.delete(context);
12
+ const appContext = api.getAppContext();
13
+ const resolveIdentity = appContext.resolveBffRuntimeBuildIdentity;
14
+ if (true !== appContext.apiOnly && void 0 !== resolveIdentity) {
15
+ if (appContext.appDirectory !== context.appDirectory) throw new Error('BFF runtime build identity provider does not belong to this application.');
16
+ if ('function' != typeof resolveIdentity) throw new Error('BFF runtime build identity provider is invalid.');
17
+ const identity = await resolveIdentity(context);
18
+ if (null === identity || 'object' != typeof identity || !Object.isFrozen(identity)) throw new Error('BFF runtime build identity must be immutable.');
19
+ const { buildMarker, sourceRevision } = identity;
20
+ if ('string' != typeof buildMarker || !/^[0-9a-f]{64}$/u.test(buildMarker) || 'string' != typeof sourceRevision || 0 === sourceRevision.trim().length) throw new Error('BFF runtime build identity is not finalized.');
21
+ globals.ULTRAMODERN_BUILD_MARKER = JSON.stringify(buildMarker);
22
+ globals.ULTRAMODERN_SOURCE_REVISION = JSON.stringify(sourceRevision);
23
+ }
12
24
  await transformServerGlobalVars([
13
25
  ...context.outputDirectories
14
26
  ], globals);
@@ -1,17 +1,16 @@
1
- import __rslib_shim_module__ from "node:module";
2
- const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(/*#__PURE__*/ (()=>import.meta.url)());
3
- import node_path from "node:path";
4
- import { buildOperationContractMap, createOperationSchemaHash, deriveOperationVersion } from "@modern-js/server-runtime-extensions/bff-policy/node";
1
+ import "node:module";
2
+ import { buildOperationContractMap, createOperationSchemaHash, resolveOperationProducer } from "@modern-js/server-runtime-extensions/bff-policy/node";
5
3
  const REQUEST_RUNTIME = '@modern-js/runtime-extensions/request-policy';
6
4
  const modifyClient = (draft, context)=>{
7
5
  const { appDir, requestId } = context.options;
8
6
  draft.requestCreator = context.options.requestCreator || REQUEST_RUNTIME;
9
- let version;
10
- try {
11
- version = require(node_path.resolve(appDir, 'package.json')).version;
12
- } catch {}
13
- const operationVersion = deriveOperationVersion(version);
14
- const normalizedRequestId = requestId || 'default';
7
+ const { operationVersion, requestId: normalizedRequestId } = resolveOperationProducer({
8
+ directories: [
9
+ context.options.apiDir,
10
+ appDir
11
+ ],
12
+ requestId: requestId || 'default'
13
+ });
15
14
  const operationContracts = buildOperationContractMap({
16
15
  handlers: [
17
16
  ...context.handlerInfos
@@ -6,6 +6,7 @@ import { fs, upath } from "@modern-js/utils";
6
6
  import { BFF_REQUEST_RUNTIME, registerBffClientArtifacts } from "./client-artifacts.mjs";
7
7
  import { registerBffCompilation } from "./compile.mjs";
8
8
  import { registerBffGeneratedEntries } from "./generated-entries.mjs";
9
+ import { resolveSelfModule } from "./self-module.mjs";
9
10
  const src_bffPlugin = ()=>({
10
11
  name: '@modern-js/plugin-bff-build-extensions',
11
12
  usePlugins: [
@@ -26,7 +27,7 @@ const src_bffPlugin = ()=>({
26
27
  bff: {
27
28
  requestCreator: BFF_REQUEST_RUNTIME,
28
29
  runtimeCreateRequest: BFF_REQUEST_RUNTIME,
29
- clientCodegenPlugin: require.resolve('@modern-js/plugin-bff-build-extensions/hono-client-codegen')
30
+ clientCodegenPlugin: resolveSelfModule('hono-client-codegen')
30
31
  }
31
32
  }));
32
33
  const runtimeFramework = api.getConfig()?.bff?.runtimeFramework;
@@ -38,19 +39,26 @@ const src_bffPlugin = ()=>({
38
39
  const nativePlugins = plugins.filter((plugin)=>'@modern-js/plugin-bff/server-plugin' === plugin.name);
39
40
  if (1 !== nativePlugins.length) throw new Error('Expected exactly one native BFF server plugin.');
40
41
  const native = nativePlugins[0];
41
- const runtimeAdapters = native.options?.runtimeAdapters ?? {};
42
- const effect = '@modern-js/plugin-bff-extensions/effect-adapter';
43
42
  const honoRouteBinder = '@modern-js/plugin-bff-extensions/hono/node';
44
43
  if (native.options?.honoRouteBinder !== void 0 && native.options.honoRouteBinder !== honoRouteBinder) throw new Error('The Hono BFF route binder is already configured.');
45
- if (void 0 !== runtimeAdapters.effect && runtimeAdapters.effect !== effect) throw new Error('The Effect BFF runtime adapter is already configured.');
44
+ if ('hono' !== runtimeFramework) {
45
+ plugins.splice(plugins.indexOf(native), 1, {
46
+ name: '@modern-js/plugin-bff-extensions/effect-server'
47
+ });
48
+ return {
49
+ plugins
50
+ };
51
+ }
46
52
  native.options = {
47
53
  ...native.options,
48
- honoRouteBinder,
49
- runtimeAdapters: {
50
- ...runtimeAdapters,
51
- effect
52
- }
54
+ honoRouteBinder
53
55
  };
56
+ native.includeEntries = [
57
+ ...new Set([
58
+ ...native.includeEntries ?? [],
59
+ honoRouteBinder
60
+ ])
61
+ ];
54
62
  return {
55
63
  plugins
56
64
  };
@@ -0,0 +1 @@
1
+ import "node:module";
@@ -0,0 +1,15 @@
1
+ import "node:module";
2
+ import { createRequire } from "node:module";
3
+ const selfRequire = createRequire(import.meta.url);
4
+ const resolveSelfModule = (name)=>{
5
+ for (const extension of [
6
+ '.js',
7
+ '.mjs',
8
+ '.cjs',
9
+ '.ts'
10
+ ])try {
11
+ return selfRequire.resolve(`./${name}${extension}`);
12
+ } catch {}
13
+ return selfRequire.resolve(`@modern-js/plugin-bff-build-extensions/${name}`);
14
+ };
15
+ export { resolveSelfModule };
@@ -1,6 +1,5 @@
1
1
  import "node:module";
2
2
  import { applyOptionsChain, fs, upath } from "@modern-js/utils";
3
- import { transform } from "@swc/core";
4
3
  const RELEASE_IDENTITY_GLOBAL_NAMES = [
5
4
  'ULTRAMODERN_BUILD_MARKER',
6
5
  'ULTRAMODERN_SOURCE_REVISION',
@@ -45,7 +44,9 @@ const transformServerGlobalVars = (outputDirectories, globalVars)=>Promise.resol
45
44
  const sourceMapFilename = `${filename}.map`;
46
45
  return fs.pathExists(sourceMapFilename).then((sourceMapExists)=>{
47
46
  const inputSourceMapPromise = sourceMapExists ? fs.readFile(sourceMapFilename, 'utf8') : Promise.resolve(void 0);
48
- return inputSourceMapPromise.then((inputSourceMap)=>transform(`${releaseIdentityBanner}${source}`, {
47
+ return inputSourceMapPromise.then(async (inputSourceMap)=>{
48
+ const { transform } = await import("@swc/core");
49
+ return transform(`${releaseIdentityBanner}${source}`, {
49
50
  filename,
50
51
  inputSourceMap,
51
52
  sourceMaps: sourceMapExists,
@@ -65,7 +66,8 @@ const transformServerGlobalVars = (outputDirectories, globalVars)=>Promise.resol
65
66
  }
66
67
  }).then((result)=>fs.writeFile(filename, result.code).then(()=>{
67
68
  if (sourceMapExists && void 0 !== result.map && result.map.length > 0) return fs.writeFile(sourceMapFilename, result.map);
68
- })));
69
+ }));
70
+ });
69
71
  });
70
72
  }))));
71
73
  }).then(()=>void 0);
@@ -1,4 +1,5 @@
1
1
  import '@modern-js/server-runtime-extensions/server-config';
2
2
  import type { AppTools, CliPlugin } from '@modern-js/app-tools';
3
+ export type { BffRuntimeBuildIdentity, BffRuntimeBuildIdentityProvider, WithBffRuntimeBuildIdentity, } from './runtime-build-identity.js';
3
4
  export declare const bffPlugin: () => CliPlugin<AppTools>;
4
5
  export default bffPlugin;
@@ -0,0 +1,17 @@
1
+ import type { BffCompilation } from '@modern-js/app-tools';
2
+ import type { CLIPluginExtends } from '@modern-js/plugin/cli';
3
+ export interface BffRuntimeBuildIdentity {
4
+ readonly buildMarker: string;
5
+ readonly sourceRevision: string;
6
+ }
7
+ export type BffRuntimeBuildIdentityProvider = (compilation: BffCompilation) => Promise<BffRuntimeBuildIdentity>;
8
+ export type WithBffRuntimeBuildIdentity<Extends extends CLIPluginExtends> = Extends & {
9
+ extendContext: Extends['extendContext'] & {
10
+ resolveBffRuntimeBuildIdentity?: BffRuntimeBuildIdentityProvider;
11
+ };
12
+ };
13
+ declare module '@modern-js/app-tools' {
14
+ interface AppToolsExtendContext {
15
+ resolveBffRuntimeBuildIdentity?: BffRuntimeBuildIdentityProvider;
16
+ }
17
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Resolve a file this package ships alongside the calling module.
3
+ *
4
+ * Resolving it by this package's own public name (`@modern-js/plugin-bff-build-extensions/<name>`)
5
+ * only works where the package can see itself in a `node_modules` directory —
6
+ * under pnpm's isolated layout it is anchored in its own `.pnpm` directory and
7
+ * the lookup fails for a consumer, surfacing as an opaque `require.resolve`
8
+ * error in the middle of a build. A sibling lookup works in every layout:
9
+ * source (`src/*.ts`), CommonJS (`dist/cjs/*.js`) and ESM (`dist/esm-node/*.mjs`)
10
+ * all place these files next to each other.
11
+ */
12
+ export declare const resolveSelfModule: (name: string) => string;
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
- "homepage": "https://github.com/BleedingDev/ultramodern.js#readme",
2
+ "homepage": "https://github.com/ultramodernjs/ultramodern.js#readme",
3
3
  "bugs": {
4
- "url": "https://github.com/BleedingDev/ultramodern.js/issues"
4
+ "url": "https://github.com/ultramodernjs/ultramodern.js/issues"
5
5
  },
6
6
  "license": "MIT",
7
- "version": "3.9.0-ultramodern.8",
7
+ "version": "3.9.3-ultramodern.1",
8
8
  "files": [
9
9
  "dist",
10
10
  "src"
11
11
  ],
12
12
  "engines": {
13
- "node": ">=26.7.0"
13
+ "node": ">=26.10.0"
14
14
  },
15
15
  "sideEffects": false,
16
16
  "publishConfig": {
@@ -20,7 +20,7 @@
20
20
  "description": "Fork-owned BFF build lifecycle, instrumentation, and producer SDK composition.",
21
21
  "repository": {
22
22
  "type": "git",
23
- "url": "git+https://github.com/BleedingDev/ultramodern.js.git",
23
+ "url": "git+https://github.com/ultramodernjs/ultramodern.js.git",
24
24
  "directory": "packages/cli/plugin-bff-build-extensions"
25
25
  },
26
26
  "main": "./dist/cjs/index.js",
@@ -65,19 +65,19 @@
65
65
  }
66
66
  },
67
67
  "dependencies": {
68
- "@modern-js/bff-core": "npm:@bleedingdev/modern-js-bff-core@3.9.0-ultramodern.8",
69
- "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.0-ultramodern.8",
70
- "@modern-js/plugin-bff": "npm:@bleedingdev/modern-js-plugin-bff@3.9.0-ultramodern.8",
71
- "@modern-js/plugin-bff-extensions": "npm:@bleedingdev/modern-js-plugin-bff-extensions@3.9.0-ultramodern.8",
72
- "@modern-js/runtime-extensions": "npm:@bleedingdev/modern-js-runtime-extensions@3.9.0-ultramodern.8",
73
- "@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.0-ultramodern.8",
74
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.8",
75
- "@swc/core": "1.16.2"
68
+ "@modern-js/bff-core": "npm:@bleedingdev/modern-js-bff-core@3.9.3-ultramodern.1",
69
+ "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.3-ultramodern.1",
70
+ "@modern-js/plugin-bff": "npm:@bleedingdev/modern-js-plugin-bff@3.9.3-ultramodern.1",
71
+ "@modern-js/plugin-bff-extensions": "npm:@bleedingdev/modern-js-plugin-bff-extensions@3.9.3-ultramodern.1",
72
+ "@modern-js/runtime-extensions": "npm:@bleedingdev/modern-js-runtime-extensions@3.9.3-ultramodern.1",
73
+ "@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.3-ultramodern.1",
74
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.3-ultramodern.1",
75
+ "@swc/core": "1.16.13"
76
76
  },
77
77
  "peerDependencies": {
78
- "@effect/opentelemetry": "4.0.0-rc.112",
79
- "@modern-js/app-tools": "3.9.0-ultramodern.8",
80
- "effect": "4.0.0-rc.112"
78
+ "@effect/opentelemetry": "4.0.0",
79
+ "@modern-js/app-tools": "3.9.3-ultramodern.1",
80
+ "effect": "4.0.0"
81
81
  },
82
82
  "peerDependenciesMeta": {
83
83
  "@effect/opentelemetry": {
@@ -88,25 +88,28 @@
88
88
  }
89
89
  },
90
90
  "devDependencies": {
91
- "@effect/opentelemetry": "4.0.0-rc.112",
92
- "@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.9.0-ultramodern.8",
93
- "@modern-js/bff-effect": "npm:@bleedingdev/modern-js-bff-effect@3.9.0-ultramodern.8",
94
- "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.0-ultramodern.8",
95
- "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.0-ultramodern.8",
96
- "@modern-js/tsconfig": "npm:@bleedingdev/modern-js-tsconfig@3.9.0-ultramodern.8",
97
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.8",
98
- "@rsbuild/core": "2.2.3",
99
- "@rslib/core": "1.0.0",
91
+ "@effect/opentelemetry": "4.0.0",
92
+ "@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.9.3-ultramodern.1",
93
+ "@modern-js/bff-effect": "npm:@bleedingdev/modern-js-bff-effect@3.9.3-ultramodern.1",
94
+ "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.3-ultramodern.1",
95
+ "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.3-ultramodern.1",
96
+ "@modern-js/tsconfig": "npm:@bleedingdev/modern-js-tsconfig@3.9.3-ultramodern.1",
97
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.3-ultramodern.1",
98
+ "@rsbuild/core": "2.2.11",
99
+ "@rslib/core": "1.0.3",
100
100
  "@scripts/rstest-config": "2.66.0",
101
- "@types/node": "^26.4.1",
102
- "@typescript/native-preview": "7.0.0-dev.20260707.2",
103
- "effect": "4.0.0-rc.112",
101
+ "@types/node": "^26.6.3",
102
+ "effect": "4.0.0",
104
103
  "esbuild": "^0.28.2",
105
- "zod": "^4.5.4"
104
+ "typescript": "7.0.2",
105
+ "zod": "^4.6.5"
106
106
  },
107
107
  "scripts": {
108
108
  "dev": "rslib build --watch",
109
109
  "build": "rslib build",
110
110
  "test": "rstest"
111
+ },
112
+ "ultramodern": {
113
+ "sourceName": "@modern-js/plugin-bff-build-extensions"
111
114
  }
112
115
  }
@@ -7,10 +7,9 @@ import { ApiRouter } from '@modern-js/bff-core';
7
7
  import type { CLIPluginAPI } from '@modern-js/plugin';
8
8
  import {
9
9
  buildOperationContractMap,
10
- deriveOperationVersion,
11
10
  type OperationContractMap,
11
+ resolveOperationProducer,
12
12
  } from '@modern-js/server-runtime-extensions/bff-policy/node';
13
- import { fs, upath as path } from '@modern-js/utils';
14
13
 
15
14
  export const BFF_REQUEST_RUNTIME =
16
15
  '@modern-js/runtime-extensions/request-policy';
@@ -66,14 +65,13 @@ export function registerBffClientArtifacts(
66
65
  httpMethodDecider: generation.httpMethodDecider,
67
66
  isBuild: true,
68
67
  });
69
- const packageJson = await fs.readJSON(
70
- path.join(generation.appDirectory, 'package.json'),
71
- );
72
68
  const operationContracts = generation.existLambda
73
69
  ? buildOperationContractMap({
74
70
  handlers: await router.getApiHandlers(),
75
- requestId: generation.requestId,
76
- operationVersion: deriveOperationVersion(packageJson.version),
71
+ ...resolveOperationProducer({
72
+ directories: [generation.apiDirectory, generation.appDirectory],
73
+ requestId: generation.requestId || 'default',
74
+ }),
77
75
  })
78
76
  : {};
79
77
  metadata.set(generation, {
package/src/compile.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { AppTools, BffCompilation } from '@modern-js/app-tools';
2
2
  import type { CLIPluginAPI } from '@modern-js/plugin';
3
+ import type { BffRuntimeBuildIdentity } from './runtime-build-identity';
3
4
  import {
4
5
  serializeServerGlobalVars,
5
6
  transformServerGlobalVars,
@@ -21,6 +22,37 @@ export function registerBffCompilation(api: CLIPluginAPI<AppTools>) {
21
22
  if (!globals)
22
23
  throw new Error('BFF compilation completed without its before hook.');
23
24
  serialized.delete(context);
25
+ const appContext = api.getAppContext();
26
+ const resolveIdentity = appContext.resolveBffRuntimeBuildIdentity;
27
+ if (appContext.apiOnly !== true && resolveIdentity !== undefined) {
28
+ if (appContext.appDirectory !== context.appDirectory) {
29
+ throw new Error(
30
+ 'BFF runtime build identity provider does not belong to this application.',
31
+ );
32
+ }
33
+ if (typeof resolveIdentity !== 'function') {
34
+ throw new Error('BFF runtime build identity provider is invalid.');
35
+ }
36
+ const identity: BffRuntimeBuildIdentity = await resolveIdentity(context);
37
+ if (
38
+ identity === null ||
39
+ typeof identity !== 'object' ||
40
+ !Object.isFrozen(identity)
41
+ ) {
42
+ throw new Error('BFF runtime build identity must be immutable.');
43
+ }
44
+ const { buildMarker, sourceRevision } = identity;
45
+ if (
46
+ typeof buildMarker !== 'string' ||
47
+ !/^[0-9a-f]{64}$/u.test(buildMarker) ||
48
+ typeof sourceRevision !== 'string' ||
49
+ sourceRevision.trim().length === 0
50
+ ) {
51
+ throw new Error('BFF runtime build identity is not finalized.');
52
+ }
53
+ globals.ULTRAMODERN_BUILD_MARKER = JSON.stringify(buildMarker);
54
+ globals.ULTRAMODERN_SOURCE_REVISION = JSON.stringify(sourceRevision);
55
+ }
24
56
  await transformServerGlobalVars([...context.outputDirectories], globals);
25
57
  if (api.getAppContext().bffRuntimeFramework !== 'effect') return;
26
58
  // Hosted APIs use the producer's compiled entry; it is not emitted by this app.
@@ -1,9 +1,8 @@
1
- import path from 'node:path';
2
1
  import type { ClientCodegenPlugin } from '@modern-js/bff-core';
3
2
  import {
4
3
  buildOperationContractMap,
5
4
  createOperationSchemaHash,
6
- deriveOperationVersion,
5
+ resolveOperationProducer,
7
6
  } from '@modern-js/server-runtime-extensions/bff-policy/node';
8
7
 
9
8
  const REQUEST_RUNTIME = '@modern-js/runtime-extensions/request-policy';
@@ -11,14 +10,11 @@ const REQUEST_RUNTIME = '@modern-js/runtime-extensions/request-policy';
11
10
  export const modifyClient: ClientCodegenPlugin = (draft, context) => {
12
11
  const { appDir, requestId } = context.options;
13
12
  draft.requestCreator = context.options.requestCreator || REQUEST_RUNTIME;
14
- let version: string | undefined;
15
- try {
16
- version = require(path.resolve(appDir, 'package.json')).version;
17
- } catch {
18
- // Missing or invalid package metadata uses the established version fallback.
19
- }
20
- const operationVersion = deriveOperationVersion(version);
21
- const normalizedRequestId = requestId || 'default';
13
+ const { operationVersion, requestId: normalizedRequestId } =
14
+ resolveOperationProducer({
15
+ directories: [context.options.apiDir, appDir],
16
+ requestId: requestId || 'default',
17
+ });
22
18
  const operationContracts = buildOperationContractMap({
23
19
  handlers: [...context.handlerInfos],
24
20
  requestId: normalizedRequestId,
package/src/index.ts CHANGED
@@ -9,6 +9,13 @@ import {
9
9
  } from './client-artifacts';
10
10
  import { registerBffCompilation } from './compile';
11
11
  import { registerBffGeneratedEntries } from './generated-entries';
12
+ import { resolveSelfModule } from './self-module';
13
+
14
+ export type {
15
+ BffRuntimeBuildIdentity,
16
+ BffRuntimeBuildIdentityProvider,
17
+ WithBffRuntimeBuildIdentity,
18
+ } from './runtime-build-identity';
12
19
 
13
20
  export const bffPlugin = (): CliPlugin<AppTools> => ({
14
21
  name: '@modern-js/plugin-bff-build-extensions',
@@ -29,9 +36,7 @@ export const bffPlugin = (): CliPlugin<AppTools> => ({
29
36
  bff: {
30
37
  requestCreator: BFF_REQUEST_RUNTIME,
31
38
  runtimeCreateRequest: BFF_REQUEST_RUNTIME,
32
- clientCodegenPlugin: require.resolve(
33
- '@modern-js/plugin-bff-build-extensions/hono-client-codegen',
34
- ),
39
+ clientCodegenPlugin: resolveSelfModule('hono-client-codegen'),
35
40
  },
36
41
  }));
37
42
  const runtimeFramework = api.getConfig()?.bff?.runtimeFramework;
@@ -51,8 +56,6 @@ export const bffPlugin = (): CliPlugin<AppTools> => ({
51
56
  throw new Error('Expected exactly one native BFF server plugin.');
52
57
  }
53
58
  const native = nativePlugins[0]!;
54
- const runtimeAdapters = native.options?.runtimeAdapters ?? {};
55
- const effect = '@modern-js/plugin-bff-extensions/effect-adapter';
56
59
  const honoRouteBinder = '@modern-js/plugin-bff-extensions/hono/node';
57
60
  if (
58
61
  native.options?.honoRouteBinder !== undefined &&
@@ -60,19 +63,19 @@ export const bffPlugin = (): CliPlugin<AppTools> => ({
60
63
  ) {
61
64
  throw new Error('The Hono BFF route binder is already configured.');
62
65
  }
63
- if (
64
- runtimeAdapters.effect !== undefined &&
65
- runtimeAdapters.effect !== effect
66
- ) {
67
- throw new Error(
68
- 'The Effect BFF runtime adapter is already configured.',
69
- );
66
+ if (runtimeFramework !== 'hono') {
67
+ plugins.splice(plugins.indexOf(native), 1, {
68
+ name: '@modern-js/plugin-bff-extensions/effect-server',
69
+ });
70
+ return { plugins };
70
71
  }
71
72
  native.options = {
72
73
  ...native.options,
73
74
  honoRouteBinder,
74
- runtimeAdapters: { ...runtimeAdapters, effect },
75
75
  };
76
+ native.includeEntries = [
77
+ ...new Set([...(native.includeEntries ?? []), honoRouteBinder]),
78
+ ];
76
79
  return { plugins };
77
80
  });
78
81
  const metadata = new WeakMap<BffGeneration, BffGenerationMetadata>();
@@ -0,0 +1,24 @@
1
+ import type { BffCompilation } from '@modern-js/app-tools';
2
+ import type { CLIPluginExtends } from '@modern-js/plugin/cli';
3
+
4
+ export interface BffRuntimeBuildIdentity {
5
+ readonly buildMarker: string;
6
+ readonly sourceRevision: string;
7
+ }
8
+
9
+ export type BffRuntimeBuildIdentityProvider = (
10
+ compilation: BffCompilation,
11
+ ) => Promise<BffRuntimeBuildIdentity>;
12
+
13
+ export type WithBffRuntimeBuildIdentity<Extends extends CLIPluginExtends> =
14
+ Extends & {
15
+ extendContext: Extends['extendContext'] & {
16
+ resolveBffRuntimeBuildIdentity?: BffRuntimeBuildIdentityProvider;
17
+ };
18
+ };
19
+
20
+ declare module '@modern-js/app-tools' {
21
+ interface AppToolsExtendContext {
22
+ resolveBffRuntimeBuildIdentity?: BffRuntimeBuildIdentityProvider;
23
+ }
24
+ }
@@ -0,0 +1,26 @@
1
+ import { createRequire } from 'node:module';
2
+
3
+ const selfRequire = createRequire(import.meta.url);
4
+
5
+ /**
6
+ * Resolve a file this package ships alongside the calling module.
7
+ *
8
+ * Resolving it by this package's own public name (`@modern-js/plugin-bff-build-extensions/<name>`)
9
+ * only works where the package can see itself in a `node_modules` directory —
10
+ * under pnpm's isolated layout it is anchored in its own `.pnpm` directory and
11
+ * the lookup fails for a consumer, surfacing as an opaque `require.resolve`
12
+ * error in the middle of a build. A sibling lookup works in every layout:
13
+ * source (`src/*.ts`), CommonJS (`dist/cjs/*.js`) and ESM (`dist/esm-node/*.mjs`)
14
+ * all place these files next to each other.
15
+ */
16
+ export const resolveSelfModule = (name: string): string => {
17
+ for (const extension of ['.js', '.mjs', '.cjs', '.ts']) {
18
+ try {
19
+ return selfRequire.resolve(`./${name}${extension}`);
20
+ } catch {
21
+ // Try the next extension this package may have been built with.
22
+ }
23
+ }
24
+ // A layout that hoists this package still resolves the public specifier.
25
+ return selfRequire.resolve(`@modern-js/plugin-bff-build-extensions/${name}`);
26
+ };
@@ -1,7 +1,6 @@
1
1
  import type { AppTools } from '@modern-js/app-tools';
2
2
  import type { RsbuildTarget } from '@modern-js/builder';
3
3
  import { applyOptionsChain, fs, upath as path } from '@modern-js/utils';
4
- import { transform } from '@swc/core';
5
4
 
6
5
  type SerializedGlobalVars = Record<string, string>;
7
6
  type ServerGlobalVarsOptions = NonNullable<
@@ -103,8 +102,9 @@ export const transformServerGlobalVars = (
103
102
  ? fs.readFile(sourceMapFilename, 'utf8')
104
103
  : Promise.resolve(undefined);
105
104
 
106
- return inputSourceMapPromise.then(inputSourceMap =>
107
- transform(`${releaseIdentityBanner}${source}`, {
105
+ return inputSourceMapPromise.then(async inputSourceMap => {
106
+ const { transform } = await import('@swc/core');
107
+ return transform(`${releaseIdentityBanner}${source}`, {
108
108
  filename,
109
109
  inputSourceMap,
110
110
  sourceMaps: sourceMapExists,
@@ -133,8 +133,8 @@ export const transformServerGlobalVars = (
133
133
  }
134
134
  return undefined;
135
135
  }),
136
- ),
137
- );
136
+ );
137
+ });
138
138
  });
139
139
  }),
140
140
  ),