@bleedingdev/modern-js-code-tools 3.9.0-ultramodern.12 → 3.9.0-ultramodern.13

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.
@@ -20,13 +20,42 @@ const normalize = (file)=>file.split(node_path.sep).join('/').replace(/^\.\//u,
20
20
  const errorMessage = (error)=>error instanceof Error ? error.message : String(error);
21
21
  const apiApp = (app)=>'vertical' === app.kind && 'ui-only' !== app.surfaceProfile && 'horizontal-remote' !== app.deliveryUnitKind;
22
22
  function configuredApps(root, supplied) {
23
- const source = supplied ?? JSON.parse(node_fs.readFileSync(node_path.join(root, '.modernjs/ultramodern.json'), 'utf8')).topology?.apps;
24
- if (!Array.isArray(source)) throw new Error('.modernjs/ultramodern.json: topology.apps must be an array');
23
+ const topology = supplied ? void 0 : JSON.parse(node_fs.readFileSync(node_path.join(root, 'topology/reference-topology.json'), 'utf8'));
24
+ if (topology && (!topology.shell || !Array.isArray(topology.verticals) || void 0 !== topology.shells && !Array.isArray(topology.shells))) throw new Error('topology/reference-topology.json: shell and verticals must be present');
25
+ const entries = topology?.shell ? [
26
+ topology.shell,
27
+ ...topology.shells ?? [],
28
+ ...topology.verticals ?? []
29
+ ] : void 0;
30
+ const source = supplied ?? entries?.map((entry)=>{
31
+ if (!entry || 'string' != typeof entry.path || !entry.path || node_path.isAbsolute(entry.path) || entry.path.split(/[\\/]/u).includes('..')) throw new Error('topology/reference-topology.json: each app must have an explicit workspace path');
32
+ const packageFile = node_path.join(root, entry.path, 'package.json');
33
+ const manifest = JSON.parse(node_fs.readFileSync(packageFile, 'utf8'));
34
+ if ('string' != typeof manifest.name || !manifest.name || void 0 !== entry.package && entry.package !== manifest.name) throw new Error(`${entry.path}/package.json: package name must match topology`);
35
+ const api = entry.api;
36
+ const stem = api?.stem ?? api?.readiness?.endpoint?.match(/^\/([a-z0-9]+(?:-[a-z0-9]+)*)\/readiness$/u)?.[1];
37
+ return {
38
+ id: entry.id,
39
+ kind: entry.kind,
40
+ path: entry.path,
41
+ package: manifest.name,
42
+ surfaceProfile: entry.surfaceProfile,
43
+ deliveryUnitKind: entry.deliveryUnitKind,
44
+ ...void 0 === api ? {} : {
45
+ api: {
46
+ stem,
47
+ prefix: api.bff?.prefix,
48
+ protocol: api.protocol
49
+ }
50
+ }
51
+ };
52
+ });
53
+ if (!Array.isArray(source)) throw new Error('topology/reference-topology.json: shell and verticals must describe apps');
25
54
  const paths = new Set();
26
55
  for (const app of source){
27
- if (!app || 'object' != typeof app || 'string' != typeof app.path || !app.path || node_path.isAbsolute(app.path) || app.path.split(/[\\/]/u).includes('..')) throw new Error('.modernjs/ultramodern.json: each app must have a relative workspace path');
56
+ if (!app || 'object' != typeof app || 'string' != typeof app.path || !app.path || node_path.isAbsolute(app.path) || app.path.split(/[\\/]/u).includes('..')) throw new Error('topology/reference-topology.json: each app must have a relative workspace path');
28
57
  const key = normalize(app.path);
29
- if (paths.has(key)) throw new Error(`.modernjs/ultramodern.json: duplicate app path ${key}`);
58
+ if (paths.has(key)) throw new Error(`topology/reference-topology.json: duplicate app path ${key}`);
30
59
  paths.add(key);
31
60
  for (const name of [
32
61
  'id',
@@ -35,7 +64,7 @@ function configuredApps(root, supplied) {
35
64
  'surfaceProfile',
36
65
  'deliveryUnitKind'
37
66
  ])if (void 0 !== app[name] && 'string' != typeof app[name]) throw new Error(`${key}: ${name} must be a string`);
38
- for (const [field, allowed] of Object.entries({
67
+ const allowedFields = {
39
68
  kind: [
40
69
  'shell',
41
70
  'vertical'
@@ -49,7 +78,11 @@ function configuredApps(root, supplied) {
49
78
  'microvertical',
50
79
  'horizontal-remote'
51
80
  ]
52
- }))if (void 0 !== app[field] && !allowed.includes(app[field])) throw new Error(`${key}: invalid ${field}`);
81
+ };
82
+ for (const field of Object.keys(allowedFields)){
83
+ const value = app[field];
84
+ if (void 0 !== value && !allowedFields[field].includes(value)) throw new Error(`${key}: invalid ${field}`);
85
+ }
53
86
  if (void 0 !== app.api) {
54
87
  if (!app.api || 'object' != typeof app.api || Array.isArray(app.api)) throw new Error(`${key}: api must be an object`);
55
88
  if (void 0 !== app.api.protocol && ![
@@ -137,12 +170,27 @@ function check(options, topology) {
137
170
  `${base}/index.tsx`
138
171
  ].find((candidate)=>exists(candidate));
139
172
  };
140
- const composedModules = (file)=>{
173
+ const clientExportFile = (appPath, exported)=>{
174
+ if ('string' != typeof exported || !exported.startsWith('./') || exported.split(/[\\/]/u).includes('..') || !/\.[cm]?[jt]sx?$/u.test(exported)) return;
175
+ const appDirectory = absolute(appPath);
176
+ const candidate = node_path.resolve(appDirectory, exported);
177
+ try {
178
+ const workspace = node_fs.realpathSync(root);
179
+ const owner = node_fs.realpathSync(appDirectory);
180
+ const real = node_fs.realpathSync(candidate);
181
+ if (!owner.startsWith(`${workspace}${node_path.sep}`) || !real.startsWith(`${owner}${node_path.sep}`) || !node_fs.statSync(real).isFile()) return;
182
+ } catch {
183
+ return;
184
+ }
185
+ return normalize(node_path.relative(root, candidate));
186
+ };
187
+ const composedModules = (file, appPath)=>{
141
188
  const order = [];
142
189
  const seen = new Set();
143
190
  const queue = [
144
191
  file
145
192
  ];
193
+ const owner = node_fs.realpathSync(absolute(appPath));
146
194
  while(queue.length > 0 && order.length < 128){
147
195
  const current = queue.shift();
148
196
  if (seen.has(current)) continue;
@@ -153,16 +201,19 @@ function check(options, topology) {
153
201
  for (const statement of ast.program.body){
154
202
  const source = (__rspack_external__babel_types_6e8337dd.isImportDeclaration(statement) || __rspack_external__babel_types_6e8337dd.isExportNamedDeclaration(statement) || __rspack_external__babel_types_6e8337dd.isExportAllDeclaration(statement)) && statement.source ? statement.source.value : void 0;
155
203
  const resolved = void 0 === source ? void 0 : resolveRelative(current, source);
156
- if (void 0 !== resolved && !seen.has(resolved)) queue.push(resolved);
204
+ if (void 0 !== resolved && !seen.has(resolved)) {
205
+ const real = node_fs.realpathSync(absolute(resolved));
206
+ if (real.startsWith(`${owner}${node_path.sep}`)) queue.push(resolved);
207
+ }
157
208
  }
158
209
  }
159
210
  return order;
160
211
  };
161
- const moduleShape = (file, imports, calls, patterns = [], defaultExport, composed = false)=>{
212
+ const moduleShape = (file, imports, calls, patterns = [], defaultExport, composedAppPath)=>{
162
213
  if (!exists(file)) return;
163
214
  const ast = parseFile(file);
164
215
  if (!ast) return;
165
- const shapeFiles = composed ? composedModules(file) : [
216
+ const shapeFiles = composedAppPath ? composedModules(file, composedAppPath) : [
166
217
  file
167
218
  ];
168
219
  const body = shapeFiles.flatMap((shapeFile)=>parseFile(shapeFile)?.program.body ?? []);
@@ -272,19 +323,25 @@ function check(options, topology) {
272
323
  }
273
324
  return;
274
325
  }
275
- if (app?.kind === 'vertical') assert(void 0 !== app.api, `${appPath}: vertical must declare its Effect API in .modernjs/ultramodern.json`);
326
+ if (app?.kind === 'vertical') assert(void 0 !== app.api, `${appPath}: vertical must declare its Effect API in topology/reference-topology.json`);
276
327
  const stem = app?.api?.stem ?? node_path.posix.basename(appPath);
277
328
  const rpc = app?.api?.protocol === 'rpc';
278
329
  const contract = `${appPath}/shared/${rpc ? 'rpc' : 'api'}.ts`;
279
- const client = `${appPath}/src/api/${stem}-${rpc ? 'rpc-client' : 'client'}.ts`;
280
330
  const entry = `${appPath}/api/index.ts`;
281
331
  for (const file of [
282
332
  entry,
283
- contract,
284
- client
333
+ contract
285
334
  ])assert(exists(file), `${file}: required API surface is missing`);
335
+ const packageFile = `${appPath}/package.json`;
336
+ assert(exists(packageFile), `${packageFile}: required API package is missing`);
337
+ if (!exists(packageFile)) return;
338
+ const manifest = JSON.parse(read(packageFile));
339
+ assert(manifest.exports?.['./api'] === `./shared/${rpc ? 'rpc' : 'api'}.ts`, `${packageFile}: invalid ./api export`);
340
+ const clientKey = `./api/${rpc ? 'rpc-client' : 'client'}`;
341
+ const client = clientExportFile(appPath, manifest.exports?.[clientKey]);
342
+ assert(void 0 !== client, `${packageFile}: invalid API client export`);
343
+ assert(manifest.exports?.[`./api/${rpc ? 'client' : 'rpc-client'}`] === void 0, `${packageFile}: forbidden opposite protocol client export`);
286
344
  noPath(`${appPath}/shared/${rpc ? 'api' : 'rpc'}.ts`, `must not emit a ${rpc ? 'REST' : 'RPC'} contract`);
287
- noPath(`${appPath}/src/api/${stem}-${rpc ? 'client' : 'rpc-client'}.ts`, `must not emit a ${rpc ? 'REST' : 'RPC'} client`);
288
345
  if (rpc) {
289
346
  moduleShape(entry, [
290
347
  [
@@ -350,21 +407,24 @@ function check(options, topology) {
350
407
  const violation = microVerticalApiBaselineViolation(stem, absolute(contract), expectation);
351
408
  if (violation) diagnostics.push(`${contract}: ${violation}`);
352
409
  }
353
- moduleShape(client, [
354
- [
355
- effect,
410
+ if (client) {
411
+ const relativeContract = node_path.posix.relative(node_path.posix.dirname(client), contract);
412
+ moduleShape(client, [
413
+ [
414
+ effect,
415
+ [
416
+ 'Effect',
417
+ rpc ? 'makeEffectRpcClient' : 'makeEffectHttpApiClient'
418
+ ]
419
+ ],
356
420
  [
357
- 'Effect',
358
- rpc ? 'makeEffectRpcClient' : 'makeEffectHttpApiClient'
421
+ relativeContract.startsWith('.') ? relativeContract : `./${relativeContract}`,
422
+ []
359
423
  ]
360
- ],
361
- [
362
- rpc ? '../../shared/rpc.ts' : '../../shared/api',
363
- []
364
- ]
365
- ], [
366
- rpc ? 'makeEffectRpcClient' : 'makeEffectHttpApiClient'
367
- ], [], void 0, true);
424
+ ], [
425
+ rpc ? 'makeEffectRpcClient' : 'makeEffectHttpApiClient'
426
+ ], [], void 0, appPath);
427
+ }
368
428
  moduleShape(`${appPath}/api/effect-api.ts`, [], [], [
369
429
  [
370
430
  /\bbackendFederationContract\b/u,
@@ -405,13 +465,6 @@ function check(options, topology) {
405
465
  'must enable strictEffectApproach'
406
466
  ]
407
467
  ]);
408
- const packageFile = `${appPath}/package.json`;
409
- if (exists(packageFile)) {
410
- const manifest = JSON.parse(read(packageFile));
411
- assert(manifest.exports?.['./api'] === `./shared/${rpc ? 'rpc' : 'api'}.ts`, `${packageFile}: invalid ./api export`);
412
- assert(manifest.exports?.[`./api/${rpc ? 'rpc-client' : 'client'}`] === `./src/api/${stem}-${rpc ? 'rpc-client' : 'client'}.ts`, `${packageFile}: invalid API client export`);
413
- assert(manifest.exports?.[`./api/${rpc ? 'client' : 'rpc-client'}`] === void 0, `${packageFile}: forbidden opposite protocol client export`);
414
- }
415
468
  });
416
469
  const shell = 'apps/shell-super-app';
417
470
  const verticals = apps.filter((app)=>app.path.startsWith('verticals/') && apiApp(app));
@@ -20,7 +20,7 @@ const createStrictEffectApiBoundariesRule = ()=>({
20
20
  });
21
21
  reportProgramPattern(context, node, source, /@modern-js\/plugin-bff\/(?:server|hono-server)(?![\w-])/u, 'UltraModern API workspaces must not import Hono server helpers; use @modern-js/bff-effect/effect-edge and HttpApi.');
22
22
  reportProgramPattern(context, node, source, /\bruntimeFramework\s*(?::|=)\s*['"]hono['"]/u, 'UltraModern API apps must use bff.runtimeFramework: "effect".');
23
- reportProgramPattern(context, node, source, /(?:from|import)\s*['"][^'"]*(?:api\/effect|shared\/effect)[^'"]*['"]|shared-effect-api/u, 'Import API code from direct api/index.ts, shared/api.ts or src/api/* paths, not api/effect, shared/effect or shared Effect API packages.');
23
+ reportProgramPattern(context, node, source, /(?:from|import)\s*['"][^'"]*(?:api\/effect|shared\/effect)(?=\/|\.[cm]?[jt]sx?['"]|['"])[^'"]*['"]|shared-effect-api/u, 'Import API code from direct api/index.ts, shared/api.ts or src/api/* paths, not api/effect, shared/effect or shared Effect API packages.');
24
24
  reportProgramPattern(context, node, source, /\bstrictEffectApproach\s*(?::|=)\s*false\b/u, 'UltraModern API apps must keep strictEffectApproach enabled.');
25
25
  if (isApiEntryFile(filename)) {
26
26
  const violation = strictEffectRuntimeTopologyViolation(source, createEffectApiImportResolver(filename));
@@ -4,8 +4,9 @@ import { SourceSyntaxError, parseSource, traverseSource, unwrapExpression } from
4
4
  import * as __rspack_external__babel_types_6e8337dd from "@babel/types";
5
5
  const edge = '@modern-js/bff-effect/effect-edge';
6
6
  const nodeRuntime = '@modern-js/bff-effect/effect';
7
- const sharedRuntime = /^@[^/]+\/shared-contracts\/server\/effect-bff-runtime$/u;
8
- const failure = 'Generated API entries must export defineEffectBff(...) or the server-only shared Effect BFF assembly helper with an explicitly composed handler Layer and an unshadowed executable root; entries must implement handlers through HttpApiBuilder.group.';
7
+ const assembly = '@modern-js/bff-effect/assembly';
8
+ const failure = 'Generated API entries must export defineEffectBff(...) or the native Effect BFF assembly helper with an explicitly composed handler Layer and an unshadowed executable root; entries must implement handlers through HttpApiBuilder.group.';
9
+ const MAX_API_SOURCE_MODULES = 256;
9
10
  function createEffectApiImportResolver(filename) {
10
11
  const directory = node_fs.realpathSync(node_path.dirname(filename));
11
12
  const owner = node_fs.realpathSync(node_path.resolve(directory, '..'));
@@ -37,7 +38,7 @@ function strictEffectRuntimeTopologyViolation(source, resolveImport) {
37
38
  const load = (input)=>{
38
39
  const existing = modules.get(input.id);
39
40
  if (existing) return existing;
40
- if (modules.size >= 64 || input.source.length > 1000000) throw new SourceSyntaxError('API source budget exceeded');
41
+ if (modules.size >= MAX_API_SOURCE_MODULES || input.source.length > 1000000) throw new SourceSyntaxError('API source budget exceeded');
41
42
  const file = parseSource(input.source, input.id, 'Invalid API syntax');
42
43
  const module = {
43
44
  ...input,
@@ -201,7 +202,7 @@ function strictEffectRuntimeTopologyViolation(source, resolveImport) {
201
202
  if (!__rspack_external__babel_types_6e8337dd.isBlockStatement(body)) return body;
202
203
  const statements = body.body;
203
204
  const last = statements.at(-1);
204
- return statements.slice(0, -1).every((statement)=>__rspack_external__babel_types_6e8337dd.isVariableDeclaration(statement)) && __rspack_external__babel_types_6e8337dd.isReturnStatement(last) ? last.argument : void 0;
205
+ return statements.slice(0, -1).every((statement)=>__rspack_external__babel_types_6e8337dd.isVariableDeclaration(statement) || __rspack_external__babel_types_6e8337dd.isTSTypeAliasDeclaration(statement) || __rspack_external__babel_types_6e8337dd.isTSInterfaceDeclaration(statement)) && __rspack_external__babel_types_6e8337dd.isReturnStatement(last) ? last.argument : void 0;
205
206
  };
206
207
  const pipe = (node, check)=>__rspack_external__babel_types_6e8337dd.isMemberExpression(node.callee) && !node.callee.computed && __rspack_external__babel_types_6e8337dd.isIdentifier(node.callee.property, {
207
208
  name: 'pipe'
@@ -290,7 +291,7 @@ function strictEffectRuntimeTopologyViolation(source, resolveImport) {
290
291
  if (value?.name === 'defineEffectBff' && [
291
292
  edge,
292
293
  nodeRuntime
293
- ].includes(value.specifier) || value?.name === 'assembleEffectBffRuntime' && sharedRuntime.test(value.specifier)) {
294
+ ].includes(value.specifier) || value?.name === 'assembleEffectBffRuntime' && value.specifier === assembly) {
294
295
  if (1 !== node.arguments.length) return false;
295
296
  const values = properties(node.arguments[0]);
296
297
  if (!values) return false;
@@ -1,6 +1,8 @@
1
1
  import "node:module";
2
2
  import node_fs from "node:fs";
3
+ import { createRequire } from "node:module";
3
4
  import node_path from "node:path";
5
+ import { exports as external_resolve_exports_exports } from "resolve.exports";
4
6
  import { baselinePublicIdentityIsExact } from "./microvertical-api-owner.js";
5
7
  import { SourceSyntaxError, parseSource, traverseSource, unwrapExpression } from "./source-analysis.js";
6
8
  import * as __rspack_external__babel_types_6e8337dd from "@babel/types";
@@ -82,16 +84,81 @@ const exportedConst = (sourceFile, name)=>{
82
84
  }))) return localConst(sourceFile, name);
83
85
  }
84
86
  };
85
- const resolveRelativeModulePath = (fromPath, specifier)=>{
86
- if (!/^\.\.?\//u.test(specifier)) return;
87
- const resolved = node_path.resolve(node_path.dirname(fromPath), specifier);
88
- const stem = resolved.replace(/\.(?:[cm]?[jt]sx?)$/u, '');
87
+ const inside = (file, boundary)=>file === boundary || file.startsWith(`${boundary}${node_path.sep}`);
88
+ const containingWorkspace = (file)=>{
89
+ for(let directory = node_path.dirname(file);; directory = node_path.dirname(directory)){
90
+ if (node_fs.existsSync(node_path.join(directory, 'pnpm-workspace.yaml'))) return node_fs.realpathSync(directory);
91
+ if (directory === node_path.dirname(directory)) return;
92
+ }
93
+ };
94
+ const sourceBoundary = (file, workspace)=>{
95
+ for(let directory = node_path.dirname(file);; directory = node_path.dirname(directory)){
96
+ if (node_fs.existsSync(node_path.join(directory, 'package.json')) && directory !== workspace) return node_fs.realpathSync(directory);
97
+ if (directory === workspace || directory === node_path.dirname(directory)) return node_fs.realpathSync(node_path.dirname(file));
98
+ }
99
+ };
100
+ const sourceFileAt = (target, boundary)=>{
101
+ const stem = target.replace(/\.(?:[cm]?[jt]sx?)$/u, '');
89
102
  for (const candidate of [
90
103
  `${stem}.ts`,
91
104
  `${stem}.tsx`,
92
- node_path.join(stem, 'index.ts'),
93
- node_path.join(stem, 'index.tsx')
94
- ])if (node_fs.existsSync(candidate) && node_fs.statSync(candidate).isFile()) return candidate;
105
+ `${stem}.mts`,
106
+ `${stem}.cts`,
107
+ target,
108
+ node_path.join(target, 'index.ts'),
109
+ node_path.join(target, 'index.tsx')
110
+ ])try {
111
+ const real = node_fs.realpathSync(candidate);
112
+ if (inside(real, boundary) && node_fs.statSync(real).isFile()) return real;
113
+ } catch {}
114
+ };
115
+ const packageEntry = (specifier)=>{
116
+ if (specifier.startsWith('.') || specifier.startsWith('/') || specifier.startsWith('#')) return;
117
+ const parts = specifier.split('/');
118
+ const count = specifier.startsWith('@') ? 2 : 1;
119
+ if (parts.length < count || parts.slice(0, count).some((part)=>!part)) return;
120
+ return {
121
+ name: parts.slice(0, count).join('/'),
122
+ exportKey: parts.length === count ? '.' : `./${parts.slice(count).join('/')}`
123
+ };
124
+ };
125
+ const resolveModulePath = (module, specifier, workspace)=>{
126
+ if (/^\.\.?\//u.test(specifier)) {
127
+ const file = sourceFileAt(node_path.resolve(node_path.dirname(module.path), specifier), module.boundary);
128
+ return void 0 === file ? void 0 : {
129
+ path: file,
130
+ boundary: module.boundary
131
+ };
132
+ }
133
+ const entry = packageEntry(specifier);
134
+ if (!entry || !workspace) return;
135
+ const paths = createRequire(module.path).resolve.paths(entry.name) ?? [];
136
+ for (const lookup of paths){
137
+ const directory = node_path.join(lookup, entry.name);
138
+ const manifest = node_path.join(directory, 'package.json');
139
+ if (!node_fs.existsSync(manifest)) continue;
140
+ const boundary = node_fs.realpathSync(directory);
141
+ if (!inside(boundary, workspace) || boundary.split(node_path.sep).includes('node_modules')) break;
142
+ const pkg = JSON.parse(node_fs.readFileSync(manifest, 'utf8'));
143
+ if (pkg.name !== entry.name || void 0 === pkg.exports) break;
144
+ let target;
145
+ try {
146
+ const targets = external_resolve_exports_exports(pkg, entry.exportKey, {
147
+ conditions: [
148
+ 'modern:source'
149
+ ]
150
+ });
151
+ target = Array.isArray(targets) ? targets[0] : void 0;
152
+ } catch {
153
+ break;
154
+ }
155
+ if (!target || !target.startsWith('./')) break;
156
+ const file = sourceFileAt(node_path.resolve(boundary, target), boundary);
157
+ return void 0 === file ? void 0 : {
158
+ path: file,
159
+ boundary
160
+ };
161
+ }
95
162
  };
96
163
  const createModuleReader = (root)=>{
97
164
  const modules = new Map([
@@ -100,14 +167,15 @@ const createModuleReader = (root)=>{
100
167
  root
101
168
  ]
102
169
  ]);
103
- return (filePath)=>{
170
+ return (filePath, boundary)=>{
104
171
  if (modules.has(filePath)) return modules.get(filePath);
105
172
  if (modules.size >= 256) return;
106
173
  let module;
107
174
  try {
108
175
  module = {
109
176
  file: parseConsumer(filePath),
110
- path: filePath
177
+ path: filePath,
178
+ boundary
111
179
  };
112
180
  } catch {
113
181
  module = void 0;
@@ -137,7 +205,7 @@ const reexportedBinding = (module, name)=>{
137
205
  if (!__rspack_external__babel_types_6e8337dd.isExportNamedDeclaration(statement) || 'type' === statement.exportKind) continue;
138
206
  const specifier = statement.specifiers.find((value)=>__rspack_external__babel_types_6e8337dd.isExportSpecifier(value) && 'type' !== value.exportKind && propertyName(value.exported) === name);
139
207
  if (void 0 !== specifier && __rspack_external__babel_types_6e8337dd.isExportSpecifier(specifier)) return {
140
- local: specifier.local.name,
208
+ local: __rspack_external__babel_types_6e8337dd.isIdentifier(specifier.local) ? specifier.local.name : specifier.local.value,
141
209
  ...statement.source ? {
142
210
  specifier: statement.source.value
143
211
  } : {}
@@ -152,7 +220,7 @@ const defaultExport = (module)=>{
152
220
  return __rspack_external__babel_types_6e8337dd.isExpression(declaration) ? declaration : void 0;
153
221
  }
154
222
  };
155
- const resolveBinding = (module, name, scope, readModule, seen)=>{
223
+ const resolveBinding = (module, name, scope, readModule, workspace, seen)=>{
156
224
  const key = `${scope}:${module.path}#${name}`;
157
225
  if (seen.has(key) || seen.size >= 512) return;
158
226
  seen.add(key);
@@ -162,9 +230,9 @@ const resolveBinding = (module, name, scope, readModule, seen)=>{
162
230
  module
163
231
  };
164
232
  const throughModule = (specifier, imported)=>{
165
- const resolvedPath = resolveRelativeModulePath(module.path, specifier);
166
- const target = void 0 === resolvedPath ? void 0 : readModule(resolvedPath);
167
- return void 0 === target ? void 0 : resolveBinding(target, imported, 'export', readModule, seen);
233
+ const resolved = resolveModulePath(module, specifier, workspace);
234
+ const target = resolved && readModule(resolved.path, resolved.boundary);
235
+ return void 0 === target ? void 0 : resolveBinding(target, imported, 'export', readModule, workspace, seen);
168
236
  };
169
237
  if ('local' === scope) {
170
238
  const imported = importedBinding(module, name);
@@ -172,14 +240,14 @@ const resolveBinding = (module, name, scope, readModule, seen)=>{
172
240
  }
173
241
  if ('default' === name) {
174
242
  const exported = defaultExport(module);
175
- if ('string' == typeof exported) return resolveBinding(module, exported, 'local', readModule, seen);
243
+ if ('string' == typeof exported) return resolveBinding(module, exported, 'local', readModule, workspace, seen);
176
244
  return void 0 === exported ? void 0 : {
177
245
  expression: exported,
178
246
  module
179
247
  };
180
248
  }
181
249
  const reexported = reexportedBinding(module, name);
182
- if (void 0 !== reexported) return void 0 === reexported.specifier ? resolveBinding(module, reexported.local, 'local', readModule, seen) : throughModule(reexported.specifier, reexported.local);
250
+ if (void 0 !== reexported) return void 0 === reexported.specifier ? resolveBinding(module, reexported.local, 'local', readModule, workspace, seen) : throughModule(reexported.specifier, reexported.local);
183
251
  for (const statement of module.file.program.body){
184
252
  if (!__rspack_external__babel_types_6e8337dd.isExportAllDeclaration(statement) || 'type' === statement.exportKind) continue;
185
253
  const resolved = throughModule(statement.source.value, name);
@@ -333,6 +401,7 @@ const nonEndpointCombinators = {
333
401
  };
334
402
  const reachableEndpoints = (rootModule, declaration)=>{
335
403
  const readModule = createModuleReader(rootModule);
404
+ const workspace = containingWorkspace(rootModule.path);
336
405
  const active = new Set();
337
406
  const endpoints = [];
338
407
  const identities = new Set();
@@ -354,7 +423,7 @@ const reachableEndpoints = (rootModule, declaration)=>{
354
423
  active.add(node);
355
424
  try {
356
425
  if (__rspack_external__babel_types_6e8337dd.isIdentifier(node)) {
357
- const resolved = resolveBinding(module, node.name, 'local', readModule, new Set());
426
+ const resolved = resolveBinding(module, node.name, 'local', readModule, workspace, new Set());
358
427
  return void 0 !== resolved && visit(resolved.expression, resolved.module, kind, group);
359
428
  }
360
429
  if ('endpoint' === kind) {
@@ -571,11 +640,13 @@ const configuredMicroVerticalApiStem = (verticalPath, verticals)=>{
571
640
  };
572
641
  const microVerticalApiBaselineViolation = (stem, filePath, expectation)=>{
573
642
  try {
574
- const sourceFile = parseConsumer(filePath);
643
+ const realPath = node_fs.realpathSync(filePath);
644
+ const sourceFile = parseConsumer(realPath);
575
645
  if (!baselinePublicIdentityIsExact(filePath, expectation)) return 'MicroVertical baseline imports must resolve the exact framework owner public export and schema identity';
576
646
  return validateParsedContract({
577
647
  file: sourceFile,
578
- path: filePath
648
+ path: realPath,
649
+ boundary: sourceBoundary(realPath, containingWorkspace(realPath))
579
650
  }, stem, expectation);
580
651
  } catch (error) {
581
652
  if (error instanceof SourceSyntaxError) return `MicroVertical root contract must be valid TypeScript syntax (${error.message})`;