@bleedingdev/modern-js-plugin-bff-extensions 3.9.0-ultramodern.9 → 3.9.3-ultramodern.10

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 (129) hide show
  1. package/README.md +21 -4
  2. package/dist/cjs/backend-federation/edge.js +1 -1
  3. package/dist/cjs/backend-federation/identity.js +23 -22
  4. package/dist/cjs/backend-federation/integrity-plugin.js +112 -0
  5. package/dist/cjs/backend-federation/node-shared.js +85 -0
  6. package/dist/cjs/backend-federation/node.js +6 -1
  7. package/dist/cjs/backend-federation/plugin.js +40 -21
  8. package/dist/cjs/backend-federation/runtime.js +16 -84
  9. package/dist/cjs/backend-federation-manifest/load.js +31 -5
  10. package/dist/cjs/backend-federation-manifest/node.js +3 -1
  11. package/dist/cjs/backend-federation-manifest/remote.js +1 -7
  12. package/dist/cjs/backend-federation-manifest/validation.js +11 -7
  13. package/dist/cjs/cross-project-policy/node.js +8 -28
  14. package/dist/cjs/{effect-adapter → effect-server}/cross-project-policy.js +9 -9
  15. package/dist/cjs/effect-server/entry.js +63 -0
  16. package/dist/cjs/{effect-adapter → effect-server}/error-response.js +4 -4
  17. package/dist/cjs/effect-server/index.js +200 -0
  18. package/dist/cjs/effect-source-loader/built-entry.js +4 -5
  19. package/dist/cjs/effect-source-loader/http-api-runtime.js +4 -4
  20. package/dist/cjs/effect-source-loader/loader.js +10 -2
  21. package/dist/cjs/effect-source-loader/operation-contracts.js +8 -31
  22. package/dist/cjs/effect-source-loader/paths.js +38 -10
  23. package/dist/cjs/server-global-vars/index.js +61 -0
  24. package/dist/esm/backend-federation/edge.mjs +1 -1
  25. package/dist/esm/backend-federation/identity.mjs +18 -23
  26. package/dist/esm/backend-federation/integrity-plugin.mjs +68 -0
  27. package/dist/esm/backend-federation/node-shared.mjs +41 -0
  28. package/dist/esm/backend-federation/node.mjs +4 -2
  29. package/dist/esm/backend-federation/plugin.mjs +37 -18
  30. package/dist/esm/backend-federation/runtime.mjs +16 -84
  31. package/dist/esm/backend-federation-manifest/load.mjs +31 -5
  32. package/dist/esm/backend-federation-manifest/node.mjs +3 -1
  33. package/dist/esm/backend-federation-manifest/remote.mjs +1 -7
  34. package/dist/esm/backend-federation-manifest/validation.mjs +12 -8
  35. package/dist/esm/cross-project-policy/node.mjs +9 -19
  36. package/dist/esm/{effect-adapter → effect-server}/cross-project-policy.mjs +4 -4
  37. package/dist/esm/effect-server/entry.mjs +15 -0
  38. package/dist/esm/{effect-adapter → effect-server}/error-response.mjs +2 -2
  39. package/dist/esm/effect-server/index.mjs +152 -0
  40. package/dist/esm/effect-source-loader/built-entry.mjs +5 -6
  41. package/dist/esm/effect-source-loader/http-api-runtime.mjs +1 -1
  42. package/dist/esm/effect-source-loader/loader.mjs +10 -2
  43. package/dist/esm/effect-source-loader/operation-contracts.mjs +10 -33
  44. package/dist/esm/effect-source-loader/paths.mjs +30 -11
  45. package/dist/esm/server-global-vars/index.mjs +23 -0
  46. package/dist/esm-node/backend-federation/edge.mjs +1 -1
  47. package/dist/esm-node/backend-federation/identity.mjs +18 -23
  48. package/dist/esm-node/backend-federation/integrity-plugin.mjs +69 -0
  49. package/dist/esm-node/backend-federation/node-shared.mjs +42 -0
  50. package/dist/esm-node/backend-federation/node.mjs +4 -2
  51. package/dist/esm-node/backend-federation/plugin.mjs +37 -18
  52. package/dist/esm-node/backend-federation/runtime.mjs +16 -84
  53. package/dist/esm-node/backend-federation-manifest/load.mjs +31 -5
  54. package/dist/esm-node/backend-federation-manifest/node.mjs +3 -1
  55. package/dist/esm-node/backend-federation-manifest/remote.mjs +1 -7
  56. package/dist/esm-node/backend-federation-manifest/validation.mjs +12 -8
  57. package/dist/esm-node/cross-project-policy/node.mjs +9 -19
  58. package/dist/esm-node/{effect-adapter → effect-server}/cross-project-policy.mjs +4 -4
  59. package/dist/esm-node/effect-server/entry.mjs +16 -0
  60. package/dist/esm-node/{effect-adapter → effect-server}/error-response.mjs +2 -2
  61. package/dist/esm-node/effect-server/index.mjs +153 -0
  62. package/dist/esm-node/effect-source-loader/built-entry.mjs +5 -6
  63. package/dist/esm-node/effect-source-loader/http-api-runtime.mjs +1 -1
  64. package/dist/esm-node/effect-source-loader/loader.mjs +10 -2
  65. package/dist/esm-node/effect-source-loader/operation-contracts.mjs +10 -33
  66. package/dist/esm-node/effect-source-loader/paths.mjs +30 -11
  67. package/dist/esm-node/server-global-vars/index.mjs +24 -0
  68. package/dist/types/backend-federation/edge.d.ts +4 -2
  69. package/dist/types/backend-federation/identity.d.ts +3 -6
  70. package/dist/types/backend-federation/integrity-plugin.d.ts +13 -0
  71. package/dist/types/backend-federation/node-shared.d.ts +20 -0
  72. package/dist/types/backend-federation/node.d.ts +3 -0
  73. package/dist/types/backend-federation/plugin.d.ts +4 -0
  74. package/dist/types/backend-federation/types.d.ts +2 -7
  75. package/dist/types/backend-federation-manifest/types.d.ts +2 -1
  76. package/dist/types/cross-project-policy/node.d.ts +2 -2
  77. package/dist/types/effect-server/cross-project-policy.d.ts +5 -0
  78. package/dist/types/{effect-adapter → effect-server}/entry.d.ts +1 -1
  79. package/dist/types/effect-server/error-response.d.ts +2 -0
  80. package/dist/types/effect-server/index.d.ts +4 -0
  81. package/dist/types/effect-source-loader/http-api-runtime.d.ts +2 -0
  82. package/dist/types/effect-source-loader/loader.d.ts +3 -0
  83. package/dist/types/effect-source-loader/operation-contracts.d.ts +2 -0
  84. package/dist/types/effect-source-loader/paths.d.ts +20 -2
  85. package/dist/types/hono/node.d.ts +1 -1
  86. package/dist/types/server-global-vars/index.d.ts +11 -0
  87. package/package.json +47 -33
  88. package/src/backend-federation/edge.ts +7 -4
  89. package/src/backend-federation/identity.ts +39 -47
  90. package/src/backend-federation/integrity-plugin.ts +157 -0
  91. package/src/backend-federation/load.ts +0 -1
  92. package/src/backend-federation/node-shared.ts +76 -0
  93. package/src/backend-federation/node.ts +7 -3
  94. package/src/backend-federation/plugin.ts +73 -25
  95. package/src/backend-federation/runtime.ts +16 -90
  96. package/src/backend-federation/types.ts +2 -11
  97. package/src/backend-federation-manifest/load.ts +76 -27
  98. package/src/backend-federation-manifest/node.ts +3 -2
  99. package/src/backend-federation-manifest/remote.ts +0 -6
  100. package/src/backend-federation-manifest/types.ts +2 -0
  101. package/src/backend-federation-manifest/validation.ts +22 -29
  102. package/src/cross-project-policy/node.ts +7 -38
  103. package/src/{effect-adapter → effect-server}/cross-project-policy.ts +9 -3
  104. package/src/effect-server/entry.ts +18 -0
  105. package/src/{effect-adapter → effect-server}/error-response.ts +1 -1
  106. package/src/effect-server/index.ts +243 -0
  107. package/src/effect-source-loader/built-entry.ts +11 -9
  108. package/src/effect-source-loader/http-api-runtime.ts +3 -1
  109. package/src/effect-source-loader/loader.ts +24 -6
  110. package/src/effect-source-loader/operation-contracts.ts +9 -41
  111. package/src/effect-source-loader/paths.ts +55 -21
  112. package/src/effect-source-loader/rspack-loader.ts +0 -1
  113. package/src/server-global-vars/index.ts +46 -0
  114. package/dist/cjs/backend-federation/entry.js +0 -94
  115. package/dist/cjs/effect-adapter/entry.js +0 -99
  116. package/dist/cjs/effect-adapter/index.js +0 -194
  117. package/dist/esm/backend-federation/entry.mjs +0 -56
  118. package/dist/esm/effect-adapter/entry.mjs +0 -51
  119. package/dist/esm/effect-adapter/index.mjs +0 -143
  120. package/dist/esm-node/backend-federation/entry.mjs +0 -57
  121. package/dist/esm-node/effect-adapter/entry.mjs +0 -52
  122. package/dist/esm-node/effect-adapter/index.mjs +0 -144
  123. package/dist/types/backend-federation/entry.d.ts +0 -2
  124. package/dist/types/effect-adapter/cross-project-policy.d.ts +0 -4
  125. package/dist/types/effect-adapter/error-response.d.ts +0 -2
  126. package/dist/types/effect-adapter/index.d.ts +0 -21
  127. package/src/backend-federation/entry.ts +0 -125
  128. package/src/effect-adapter/entry.ts +0 -96
  129. package/src/effect-adapter/index.ts +0 -251
@@ -1,8 +1,10 @@
1
1
  import { fs, upath as path } from '@modern-js/utils';
2
2
 
3
- import { resolveEffectEntryFile } from './paths';
4
-
5
- const BUILT_ENTRY_EXT = /\.(?:[cm]?ts|tsx|jsx)$/u;
3
+ import {
4
+ emittedEffectEntry,
5
+ relativeEffectAppPath,
6
+ resolveEffectEntryFile,
7
+ } from './paths';
6
8
 
7
9
  export function resolveBuiltEffectEntry(
8
10
  appDirectory: string,
@@ -12,15 +14,15 @@ export function resolveBuiltEffectEntry(
12
14
  if (sourceEntry === undefined || sourceEntry.length === 0) {
13
15
  return undefined;
14
16
  }
15
- const relativeEntry = path.relative(appDirectory, sourceEntry);
16
- if (relativeEntry === '..' || relativeEntry.startsWith(`..${path.sep}`)) {
17
+ const relativeEntry = relativeEffectAppPath(appDirectory, sourceEntry);
18
+ if (relativeEntry === undefined) {
17
19
  throw new Error(
18
20
  `Effect BFF entry must be inside the application directory: ${sourceEntry}`,
19
21
  );
20
22
  }
21
- const builtEntry = path
22
- .resolve(distDirectory, relativeEntry)
23
- .replace(BUILT_ENTRY_EXT, '.js');
23
+ const builtEntry = emittedEffectEntry(
24
+ path.resolve(distDirectory, relativeEntry),
25
+ );
24
26
  return fs.existsSync(builtEntry) ? builtEntry : undefined;
25
27
  }
26
28
 
@@ -62,7 +64,7 @@ export function resolveEffectEntryPaths(options: {
62
64
  });
63
65
  const relativeEffectEntry =
64
66
  sourceEffectEntry !== undefined && sourceEffectEntry.length > 0
65
- ? path.relative(appDir, sourceEffectEntry).replace(BUILT_ENTRY_EXT, '.js')
67
+ ? emittedEffectEntry(path.relative(appDir, sourceEffectEntry))
66
68
  : '';
67
69
  return { sourceEffectEntry, relativeEffectEntry };
68
70
  }
@@ -3,7 +3,8 @@ import {
3
3
  type HttpApiLike,
4
4
  type HttpApiReflect,
5
5
  } from '@modern-js/bff-effect/effect';
6
- import { HttpApi } from 'effect/unstable/httpapi';
6
+ import { HttpApi } from 'effect/http-api';
7
+ import type { ServerGlobalVarsOptions } from '../server-global-vars';
7
8
  import { loadEffectSourceModule } from './loader';
8
9
 
9
10
  type HttpApiRuntime = {
@@ -29,6 +30,7 @@ export function getHttpApiRuntime(): Promise<HttpApiRuntime> {
29
30
  export function loadEffectApi(options: {
30
31
  appDir: string;
31
32
  resourcePath: string;
33
+ globalVars?: ServerGlobalVarsOptions;
32
34
  onDependency?: (dependency: string) => void;
33
35
  }): Promise<HttpApiLike | null> {
34
36
  return getHttpApiRuntime().then(httpApiRuntime =>
@@ -12,8 +12,12 @@ import {
12
12
  type Plugin,
13
13
  transform,
14
14
  } from 'esbuild';
15
+ import {
16
+ type ServerGlobalVarsOptions,
17
+ serializeServerGlobalVars,
18
+ } from '../server-global-vars';
15
19
 
16
- const NODE_TARGET = 'node26.7';
20
+ const NODE_TARGET = 'node26.10';
17
21
  const SOURCE_LOADERS = new Map<string, Loader>([
18
22
  ['.js', 'js'],
19
23
  ['.jsx', 'jsx'],
@@ -28,6 +32,8 @@ const SOURCE_LOADERS = new Map<string, Loader>([
28
32
  export type EffectSourceLoaderOptions = {
29
33
  resourcePath: string;
30
34
  appDir?: string;
35
+ /** `source.globalVars`, replaced in the loaded source graph. */
36
+ globalVars?: ServerGlobalVarsOptions;
31
37
  onDependency?: (dependency: string) => void;
32
38
  };
33
39
 
@@ -79,6 +85,9 @@ const nodeBuiltins = new Set([
79
85
  ...builtinModules.map(name => `node:${name}`),
80
86
  ]);
81
87
  const dependencyResolutionMarker = 'modern-js-effect-dependency-resolution';
88
+ // The BFF server runs lambdas inside these packages' Effect context storage.
89
+ // A bundled copy would own a second storage that the server never enters.
90
+ const BFF_RUNTIME_PACKAGE = /^@modern-js\/(?:bff-effect|plugin-bff)(?:\/|$)/;
82
91
 
83
92
  async function isEsmOnlyFile(filename: string) {
84
93
  const extension = path.extname(filename).toLowerCase();
@@ -125,10 +134,9 @@ function isBareSpecifier(specifier: string) {
125
134
  }
126
135
 
127
136
  /**
128
- * Keep installed registry dependencies external while bundling symlinked
129
- * workspace source packages. Registry packages remain executable from the
130
- * deployment node_modules tree; workspace TypeScript is bundled so the
131
- * generated entry is relocatable and directly executable by Node 26.7.
137
+ * Keep installed executable dependencies external to preserve runtime identity.
138
+ * Source requiring compilation is bundled even when pnpm injects a workspace
139
+ * package into node_modules: Node does not strip types inside that directory.
132
140
  */
133
141
  function externalizeInstalledDependencies(options: {
134
142
  runtimeResolveDir: string;
@@ -137,6 +145,9 @@ function externalizeInstalledDependencies(options: {
137
145
  name: 'modern-js-effect-installed-dependencies',
138
146
  setup(buildApi) {
139
147
  buildApi.onResolve({ filter: /.*/ }, async args => {
148
+ if (BFF_RUNTIME_PACKAGE.test(args.path)) {
149
+ return { external: true, path: args.path };
150
+ }
140
151
  if (
141
152
  !isBareSpecifier(args.path) ||
142
153
  nodeBuiltins.has(args.path) ||
@@ -167,7 +178,13 @@ function externalizeInstalledDependencies(options: {
167
178
  const realPath = await fs.promises
168
179
  .realpath(resolution.path)
169
180
  .catch(() => resolution.path);
170
- if (realPath.includes(`${path.sep}node_modules${path.sep}`)) {
181
+ const loader = SOURCE_LOADERS.get(path.extname(realPath).toLowerCase());
182
+ if (
183
+ realPath.includes(`${path.sep}node_modules${path.sep}`) &&
184
+ loader !== 'ts' &&
185
+ loader !== 'tsx' &&
186
+ loader !== 'jsx'
187
+ ) {
171
188
  const runtimeResolution = await buildApi.resolve(args.path, {
172
189
  importer: '',
173
190
  kind: args.kind,
@@ -341,6 +358,7 @@ export async function loadEffectSourceModule(
341
358
  js: `import { createRequire as __modernCreateEffectRequire } from 'node:module'; const require = __modernCreateEffectRequire(${JSON.stringify(pathToFileURL(resourcePath).href)});`,
342
359
  },
343
360
  bundle: true,
361
+ define: serializeServerGlobalVars(options.globalVars),
344
362
  entryPoints: [resourcePath],
345
363
  format: 'esm',
346
364
  jsx: 'automatic',
@@ -4,48 +4,19 @@ import {
4
4
  } from '@modern-js/bff-effect/effect';
5
5
  import {
6
6
  buildOperationContractMap,
7
- deriveOperationVersion,
7
+ resolveOperationProducer,
8
8
  } from '@modern-js/server-runtime-extensions/bff-policy/node';
9
- import { fs, upath as path } from '@modern-js/utils';
9
+ import { upath as path } from '@modern-js/utils';
10
+ import type { ServerGlobalVarsOptions } from '../server-global-vars';
10
11
  import { getHttpApiRuntime, loadEffectApi } from './http-api-runtime';
11
12
 
12
- function getPackageInfo(
13
- resourcePath: string,
14
- appDir: string,
15
- onDependency?: (dependency: string) => void,
16
- ): { name?: string; version?: string } {
17
- for (const startDir of [path.dirname(resourcePath), appDir]) {
18
- let current = path.resolve(startDir);
19
- for (let depth = 0; depth < 32; depth += 1) {
20
- const packageJsonPath = path.join(current, 'package.json');
21
- if (fs.existsSync(packageJsonPath)) {
22
- onDependency?.(packageJsonPath);
23
- try {
24
- const packageJson = fs.readJSONSync(packageJsonPath) as {
25
- name?: string;
26
- version?: string;
27
- };
28
- return { name: packageJson.name, version: packageJson.version };
29
- } catch {
30
- return {};
31
- }
32
- }
33
- const parent = path.dirname(current);
34
- if (parent === current) {
35
- break;
36
- }
37
- current = parent;
38
- }
39
- }
40
- return {};
41
- }
42
-
43
13
  /** Derives server policy metadata without emitting or typing a client. */
44
14
  export async function resolveEffectOperationContracts(options: {
45
15
  appDir: string;
46
16
  resourcePath: string;
47
17
  prefix: string;
48
18
  requestId?: string;
19
+ globalVars?: ServerGlobalVarsOptions;
49
20
  onDependency?: (dependency: string) => void;
50
21
  }) {
51
22
  const api = await loadEffectApi(options);
@@ -58,15 +29,12 @@ export async function resolveEffectOperationContracts(options: {
58
29
  api,
59
30
  options.prefix,
60
31
  );
61
- const packageInfo = getPackageInfo(
62
- options.resourcePath,
63
- options.appDir,
64
- options.onDependency,
65
- );
66
- const requestId = options.requestId?.trim() || packageInfo.name || 'default';
67
32
  return buildOperationContractMap({
68
33
  handlers: toOperationContractSources(endpoints),
69
- requestId,
70
- operationVersion: deriveOperationVersion(packageInfo.version),
34
+ ...resolveOperationProducer({
35
+ directories: [path.dirname(options.resourcePath), options.appDir],
36
+ requestId: options.requestId,
37
+ onDependency: options.onDependency,
38
+ }),
71
39
  });
72
40
  }
@@ -9,32 +9,66 @@ const JS_OR_TS_EXTS = [
9
9
  '.mts',
10
10
  '.cjs',
11
11
  '.cts',
12
- ] as const;
12
+ ];
13
13
 
14
- export function resolveEffectEntryFile(options: {
14
+ export const emittedEffectEntry = (entry: string) =>
15
+ entry.replace(/\.(?:[cm]?ts|tsx|jsx)$/u, '.js');
16
+
17
+ export function relativeEffectAppPath(appDir: string, entry: string) {
18
+ const relative = path.relative(appDir, entry);
19
+ return relative === '..' ||
20
+ relative.startsWith('../') ||
21
+ relative.split('/').includes('node_modules')
22
+ ? undefined
23
+ : relative;
24
+ }
25
+
26
+ function existingEntry(entry: string): string | undefined {
27
+ return path.extname(entry)
28
+ ? fs.existsSync(entry)
29
+ ? entry
30
+ : undefined
31
+ : findExists(JS_OR_TS_EXTS.map(ext => `${entry}${ext}`)) || undefined;
32
+ }
33
+
34
+ type EffectEntryOptions = {
15
35
  appDir: string;
16
36
  apiDir: string;
17
37
  effectEntry?: string;
18
- }): string | undefined {
19
- const { appDir, apiDir, effectEntry } = options;
38
+ };
39
+ export type EffectEntry =
40
+ | { kind: 'app-source'; path: string | undefined }
41
+ | { kind: 'built-output'; path: string | undefined }
42
+ | { kind: 'external-sdk'; path: string | undefined };
20
43
 
21
- const resolveEntry = (entryWithoutExt: string) => {
22
- if (path.extname(entryWithoutExt) !== '') {
23
- return fs.existsSync(entryWithoutExt) ? entryWithoutExt : undefined;
24
- }
25
-
26
- return (
27
- findExists(JS_OR_TS_EXTS.map(ext => `${entryWithoutExt}${ext}`)) ||
28
- undefined
29
- );
30
- };
31
-
32
- if (effectEntry !== undefined && effectEntry !== '') {
33
- const entryWithoutExt = path.isAbsolute(effectEntry)
34
- ? effectEntry
35
- : path.resolve(appDir, effectEntry);
36
- return resolveEntry(entryWithoutExt);
44
+ /** Classify ownership before resolving files: production works without source. */
45
+ export function resolveEffectEntry(
46
+ options: EffectEntryOptions & { distDir?: string },
47
+ ): EffectEntry {
48
+ const { appDir, apiDir, effectEntry, distDir } = options;
49
+ const entry = path.resolve(appDir, effectEntry || path.join(apiDir, 'index'));
50
+ if (distDir && relativeEffectAppPath(distDir, entry) !== undefined) {
51
+ return {
52
+ kind: 'built-output',
53
+ path: existingEntry(emittedEffectEntry(entry)),
54
+ };
37
55
  }
56
+ const relative = relativeEffectAppPath(appDir, entry);
57
+ if (relative === undefined) {
58
+ return { kind: 'external-sdk', path: existingEntry(entry) };
59
+ }
60
+ return distDir
61
+ ? {
62
+ kind: 'built-output',
63
+ path: existingEntry(
64
+ emittedEffectEntry(path.resolve(distDir, relative)),
65
+ ),
66
+ }
67
+ : { kind: 'app-source', path: existingEntry(entry) };
68
+ }
38
69
 
39
- return resolveEntry(path.resolve(apiDir, 'index'));
70
+ export function resolveEffectEntryFile(
71
+ options: EffectEntryOptions,
72
+ ): string | undefined {
73
+ return resolveEffectEntry(options).path;
40
74
  }
@@ -1,5 +1,4 @@
1
1
  import { realpathSync } from 'node:fs';
2
- import path from 'node:path';
3
2
  import type { Rspack } from '@rsbuild/core';
4
3
  import {
5
4
  bundleEffectWorkerRuntimeSource,
@@ -0,0 +1,46 @@
1
+ import type {
2
+ ServerGlobalVars,
3
+ ServerGlobalVarsContext,
4
+ ServerSourceConfigExtension,
5
+ } from '@modern-js/runtime-extensions/server-config';
6
+ import { applyOptionsChain } from '@modern-js/utils';
7
+
8
+ export type ServerGlobalVarsOptions = ServerSourceConfigExtension['globalVars'];
9
+
10
+ /** Each global name mapped to the JSON source text that replaces it. */
11
+ export type SerializedServerGlobalVars = Record<string, string>;
12
+
13
+ /**
14
+ * Resolves `source.globalVars` for BFF server code and serializes every value
15
+ * to the JSON text that replaces it. Dev source loading and build output use
16
+ * this one function, so both see the same values. A value without an exact
17
+ * JSON form (such as `undefined`, a function or a BigInt) is rejected.
18
+ */
19
+ export const serializeServerGlobalVars = (
20
+ options: ServerGlobalVarsOptions,
21
+ ): SerializedServerGlobalVars => {
22
+ const globalVars = applyOptionsChain<
23
+ ServerGlobalVars,
24
+ ServerGlobalVarsContext
25
+ >({}, options, { env: 'server', target: 'node' });
26
+
27
+ return Object.fromEntries(
28
+ Object.entries(globalVars).map(([key, value]) => {
29
+ let serialized: string | undefined;
30
+ try {
31
+ serialized = JSON.stringify(value);
32
+ } catch (error) {
33
+ throw new Error(
34
+ `source.globalVars["${key}"] cannot be serialized exactly for BFF server code.`,
35
+ { cause: error },
36
+ );
37
+ }
38
+ if (serialized === undefined) {
39
+ throw new Error(
40
+ `source.globalVars["${key}"] cannot be serialized exactly for BFF server code.`,
41
+ );
42
+ }
43
+ return [key, serialized];
44
+ }),
45
+ );
46
+ };
@@ -1,94 +0,0 @@
1
- "use strict";
2
- var __webpack_require__ = {};
3
- (()=>{
4
- __webpack_require__.d = (exports1, getters, values)=>{
5
- var define = (defs, kind)=>{
6
- for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
- enumerable: true,
8
- [kind]: defs[key]
9
- });
10
- };
11
- define(getters, "get");
12
- define(values, "value");
13
- };
14
- })();
15
- (()=>{
16
- __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
17
- })();
18
- (()=>{
19
- __webpack_require__.r = (exports1)=>{
20
- if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
21
- value: 'Module'
22
- });
23
- Object.defineProperty(exports1, '__esModule', {
24
- value: true
25
- });
26
- };
27
- })();
28
- var __webpack_exports__ = {};
29
- __webpack_require__.r(__webpack_exports__);
30
- __webpack_require__.d(__webpack_exports__, {
31
- loadBackendFederationExpose: ()=>loadBackendFederationExpose
32
- });
33
- const backend_federation_security_namespaceObject = require("@modern-js/server-runtime-extensions/backend-federation-security");
34
- const external_utils_js_namespaceObject = require("./utils.js");
35
- function decodeDataUrl(url) {
36
- const commaIndex = url.indexOf(',');
37
- if (commaIndex < 0) throw new Error('[BFF][Effect] Invalid backend federation data URL entry.');
38
- return decodeURIComponent(url.slice(commaIndex + 1));
39
- }
40
- async function readCommonJsEntrySource(remote) {
41
- if (remote.entry.startsWith('data:')) return decodeDataUrl(remote.entry);
42
- throw new Error(`[BFF][Effect] Backend federation remote ${remote.name} cannot load CommonJS entry ${remote.entry}.`);
43
- }
44
- async function importModuleEntry(remote) {
45
- const entry = await import(remote.entry);
46
- return entry.default ?? entry;
47
- }
48
- async function resolvePluginEntry(remote, plugins) {
49
- for (const plugin of plugins ?? []){
50
- const loadEntry = plugin.loadEntry;
51
- if ('function' != typeof loadEntry) continue;
52
- const entry = await loadEntry({
53
- remoteInfo: remote
54
- });
55
- if (entry) return entry;
56
- }
57
- }
58
- async function loadBackendFederationEntry(remote, options) {
59
- const requiresVerification = Boolean(remote.verification || options.entryPolicy?.expected);
60
- const isNetworkEntry = /^https?:\/\//iu.test(remote.entry);
61
- if (isNetworkEntry && !requiresVerification) throw new Error(`[BFF][Effect] Backend federation remote ${remote.name} requires verified entry bytes before network execution.`);
62
- if (requiresVerification) return (0, backend_federation_security_namespaceObject.loadVerifiedBackendFederationEntry)({
63
- ...options.entryPolicy,
64
- remote,
65
- ...remote.verification ? {
66
- verification: remote.verification
67
- } : {}
68
- });
69
- const pluginEntry = await resolvePluginEntry(remote, options.plugins);
70
- if (pluginEntry) return pluginEntry;
71
- if (remote.entryGlobalName) {
72
- const globalEntry = globalThis[remote.entryGlobalName];
73
- if ((0, external_utils_js_namespaceObject.isRecord)(globalEntry)) return globalEntry;
74
- }
75
- if ('module' === remote.type || remote.entry.startsWith('file:')) return importModuleEntry(remote);
76
- return (0, backend_federation_security_namespaceObject.evaluateBackendFederationCommonJsEntry)(remote, new TextEncoder().encode(await readCommonJsEntrySource(remote)), options.entryPolicy?.evaluateCommonJs);
77
- }
78
- async function loadBackendFederationExpose(remote, expose, options) {
79
- const entry = await loadBackendFederationEntry(remote, options);
80
- if ('function' == typeof entry.init) await entry.init({
81
- hostName: options.hostName
82
- });
83
- if ('function' != typeof entry.get) throw new Error(`[BFF][Effect] Backend federation remote ${remote.name} entry must expose get().`);
84
- const factory = await entry.get(expose);
85
- if ('function' != typeof factory) throw new Error(`[BFF][Effect] Backend federation expose ${remote.name}/${(0, external_utils_js_namespaceObject.normalizeExpose)(expose)} must load factory function.`);
86
- return factory();
87
- }
88
- exports.loadBackendFederationExpose = __webpack_exports__.loadBackendFederationExpose;
89
- for(var __rspack_i in __webpack_exports__)if (-1 === [
90
- "loadBackendFederationExpose"
91
- ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
92
- Object.defineProperty(exports, '__esModule', {
93
- value: true
94
- });
@@ -1,99 +0,0 @@
1
- "use strict";
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
- (()=>{
13
- __webpack_require__.d = (exports1, getters, values)=>{
14
- var define = (defs, kind)=>{
15
- for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
- enumerable: true,
17
- [kind]: defs[key]
18
- });
19
- };
20
- define(getters, "get");
21
- define(values, "value");
22
- };
23
- })();
24
- (()=>{
25
- __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
26
- })();
27
- (()=>{
28
- __webpack_require__.r = (exports1)=>{
29
- if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
30
- value: 'Module'
31
- });
32
- Object.defineProperty(exports1, '__esModule', {
33
- value: true
34
- });
35
- };
36
- })();
37
- var __webpack_exports__ = {};
38
- __webpack_require__.r(__webpack_exports__);
39
- __webpack_require__.d(__webpack_exports__, {
40
- resolveEffectAdapterEntryFile: ()=>resolveEffectAdapterEntryFile
41
- });
42
- const external_node_path_namespaceObject = require("node:path");
43
- var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
44
- require("@modern-js/server-runtime-extensions/server-config");
45
- const utils_namespaceObject = require("@modern-js/utils");
46
- const JS_OR_TS_EXTS = [
47
- '.js',
48
- '.jsx',
49
- '.ts',
50
- '.tsx',
51
- '.mjs',
52
- '.mts',
53
- '.cjs',
54
- '.cts'
55
- ];
56
- function resolveJsOrTsEntry(entryWithoutOrWithExt) {
57
- const extension = external_node_path_default().extname(entryWithoutOrWithExt);
58
- if (JS_OR_TS_EXTS.includes(extension)) return utils_namespaceObject.fs.existsSync(entryWithoutOrWithExt) ? entryWithoutOrWithExt : void 0;
59
- return (0, utils_namespaceObject.findExists)(JS_OR_TS_EXTS.map((ext)=>`${entryWithoutOrWithExt}${ext}`)) || void 0;
60
- }
61
- function builtEntryPath(entryPath) {
62
- return entryPath.replace(/\.(?:[cm]?ts|tsx|jsx)$/u, '.js');
63
- }
64
- function relativeAppPath(appDirectory, entryPath) {
65
- const relativePath = external_node_path_default().relative(appDirectory, entryPath);
66
- return '..' === relativePath || relativePath.startsWith(`..${external_node_path_default().sep}`) ? void 0 : relativePath;
67
- }
68
- function isDependencyPath(relativePath) {
69
- return relativePath?.split(/[\\/]/u).includes('node_modules') ?? false;
70
- }
71
- function resolveEffectAdapterEntryFile(api) {
72
- const { appDirectory, apiDirectory, distDirectory } = api.getServerContext();
73
- const appRoot = external_node_path_default().resolve(appDirectory || process.cwd());
74
- const productionRoot = (0, utils_namespaceObject.isProd)() && distDirectory ? external_node_path_default().resolve(distDirectory) : void 0;
75
- const configuredEntry = api.getServerConfig()?.bff?.effect?.entry;
76
- if (configuredEntry) {
77
- const sourceEntry = external_node_path_default().isAbsolute(configuredEntry) ? configuredEntry : external_node_path_default().resolve(appRoot, configuredEntry);
78
- if (productionRoot) {
79
- const relativeEntry = relativeAppPath(appRoot, sourceEntry);
80
- if (void 0 === relativeEntry || isDependencyPath(relativeEntry)) return resolveJsOrTsEntry(sourceEntry);
81
- return relativeEntry ? resolveJsOrTsEntry(builtEntryPath(external_node_path_default().resolve(productionRoot, relativeEntry))) : void 0;
82
- }
83
- return resolveJsOrTsEntry(sourceEntry);
84
- }
85
- const resolvedApiDirectory = external_node_path_default().resolve(appRoot, apiDirectory || utils_namespaceObject.API_DIR);
86
- const productionApiDirectory = productionRoot ? void 0 !== relativeAppPath(productionRoot, resolvedApiDirectory) ? resolvedApiDirectory : (()=>{
87
- const relativeApiDirectory = relativeAppPath(appRoot, resolvedApiDirectory);
88
- if (isDependencyPath(relativeApiDirectory)) return resolvedApiDirectory;
89
- return relativeApiDirectory ? external_node_path_default().resolve(productionRoot, relativeApiDirectory) : void 0;
90
- })() : resolvedApiDirectory;
91
- return productionApiDirectory ? resolveJsOrTsEntry(external_node_path_default().resolve(productionApiDirectory, 'index')) : void 0;
92
- }
93
- exports.resolveEffectAdapterEntryFile = __webpack_exports__.resolveEffectAdapterEntryFile;
94
- for(var __rspack_i in __webpack_exports__)if (-1 === [
95
- "resolveEffectAdapterEntryFile"
96
- ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
97
- Object.defineProperty(exports, '__esModule', {
98
- value: true
99
- });