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

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.
@@ -42,9 +42,11 @@ __webpack_require__.d(__webpack_exports__, {
42
42
  });
43
43
  const external_node_fs_namespaceObject = require("node:fs");
44
44
  var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
45
+ const external_node_module_namespaceObject = require("node:module");
45
46
  const external_node_path_namespaceObject = require("node:path");
46
47
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
47
48
  const types_namespaceObject = require("@babel/types");
49
+ const external_resolve_exports_namespaceObject = require("resolve.exports");
48
50
  const external_microvertical_api_owner_cjs_namespaceObject = require("./microvertical-api-owner.cjs");
49
51
  const external_source_analysis_cjs_namespaceObject = require("./source-analysis.cjs");
50
52
  function parseConsumer(filePath) {
@@ -125,16 +127,81 @@ const exportedConst = (sourceFile, name)=>{
125
127
  }))) return localConst(sourceFile, name);
126
128
  }
127
129
  };
128
- const resolveRelativeModulePath = (fromPath, specifier)=>{
129
- if (!/^\.\.?\//u.test(specifier)) return;
130
- const resolved = external_node_path_default().resolve(external_node_path_default().dirname(fromPath), specifier);
131
- const stem = resolved.replace(/\.(?:[cm]?[jt]sx?)$/u, '');
130
+ const inside = (file, boundary)=>file === boundary || file.startsWith(`${boundary}${external_node_path_default().sep}`);
131
+ const containingWorkspace = (file)=>{
132
+ for(let directory = external_node_path_default().dirname(file);; directory = external_node_path_default().dirname(directory)){
133
+ if (external_node_fs_default().existsSync(external_node_path_default().join(directory, 'pnpm-workspace.yaml'))) return external_node_fs_default().realpathSync(directory);
134
+ if (directory === external_node_path_default().dirname(directory)) return;
135
+ }
136
+ };
137
+ const sourceBoundary = (file, workspace)=>{
138
+ for(let directory = external_node_path_default().dirname(file);; directory = external_node_path_default().dirname(directory)){
139
+ if (external_node_fs_default().existsSync(external_node_path_default().join(directory, 'package.json')) && directory !== workspace) return external_node_fs_default().realpathSync(directory);
140
+ if (directory === workspace || directory === external_node_path_default().dirname(directory)) return external_node_fs_default().realpathSync(external_node_path_default().dirname(file));
141
+ }
142
+ };
143
+ const sourceFileAt = (target, boundary)=>{
144
+ const stem = target.replace(/\.(?:[cm]?[jt]sx?)$/u, '');
132
145
  for (const candidate of [
133
146
  `${stem}.ts`,
134
147
  `${stem}.tsx`,
135
- external_node_path_default().join(stem, 'index.ts'),
136
- external_node_path_default().join(stem, 'index.tsx')
137
- ])if (external_node_fs_default().existsSync(candidate) && external_node_fs_default().statSync(candidate).isFile()) return candidate;
148
+ `${stem}.mts`,
149
+ `${stem}.cts`,
150
+ target,
151
+ external_node_path_default().join(target, 'index.ts'),
152
+ external_node_path_default().join(target, 'index.tsx')
153
+ ])try {
154
+ const real = external_node_fs_default().realpathSync(candidate);
155
+ if (inside(real, boundary) && external_node_fs_default().statSync(real).isFile()) return real;
156
+ } catch {}
157
+ };
158
+ const packageEntry = (specifier)=>{
159
+ if (specifier.startsWith('.') || specifier.startsWith('/') || specifier.startsWith('#')) return;
160
+ const parts = specifier.split('/');
161
+ const count = specifier.startsWith('@') ? 2 : 1;
162
+ if (parts.length < count || parts.slice(0, count).some((part)=>!part)) return;
163
+ return {
164
+ name: parts.slice(0, count).join('/'),
165
+ exportKey: parts.length === count ? '.' : `./${parts.slice(count).join('/')}`
166
+ };
167
+ };
168
+ const resolveModulePath = (module, specifier, workspace)=>{
169
+ if (/^\.\.?\//u.test(specifier)) {
170
+ const file = sourceFileAt(external_node_path_default().resolve(external_node_path_default().dirname(module.path), specifier), module.boundary);
171
+ return void 0 === file ? void 0 : {
172
+ path: file,
173
+ boundary: module.boundary
174
+ };
175
+ }
176
+ const entry = packageEntry(specifier);
177
+ if (!entry || !workspace) return;
178
+ const paths = (0, external_node_module_namespaceObject.createRequire)(module.path).resolve.paths(entry.name) ?? [];
179
+ for (const lookup of paths){
180
+ const directory = external_node_path_default().join(lookup, entry.name);
181
+ const manifest = external_node_path_default().join(directory, 'package.json');
182
+ if (!external_node_fs_default().existsSync(manifest)) continue;
183
+ const boundary = external_node_fs_default().realpathSync(directory);
184
+ if (!inside(boundary, workspace) || boundary.split(external_node_path_default().sep).includes('node_modules')) break;
185
+ const pkg = JSON.parse(external_node_fs_default().readFileSync(manifest, 'utf8'));
186
+ if (pkg.name !== entry.name || void 0 === pkg.exports) break;
187
+ let target;
188
+ try {
189
+ const targets = (0, external_resolve_exports_namespaceObject.exports)(pkg, entry.exportKey, {
190
+ conditions: [
191
+ 'modern:source'
192
+ ]
193
+ });
194
+ target = Array.isArray(targets) ? targets[0] : void 0;
195
+ } catch {
196
+ break;
197
+ }
198
+ if (!target || !target.startsWith('./')) break;
199
+ const file = sourceFileAt(external_node_path_default().resolve(boundary, target), boundary);
200
+ return void 0 === file ? void 0 : {
201
+ path: file,
202
+ boundary
203
+ };
204
+ }
138
205
  };
139
206
  const createModuleReader = (root)=>{
140
207
  const modules = new Map([
@@ -143,14 +210,15 @@ const createModuleReader = (root)=>{
143
210
  root
144
211
  ]
145
212
  ]);
146
- return (filePath)=>{
213
+ return (filePath, boundary)=>{
147
214
  if (modules.has(filePath)) return modules.get(filePath);
148
215
  if (modules.size >= 256) return;
149
216
  let module;
150
217
  try {
151
218
  module = {
152
219
  file: parseConsumer(filePath),
153
- path: filePath
220
+ path: filePath,
221
+ boundary
154
222
  };
155
223
  } catch {
156
224
  module = void 0;
@@ -180,7 +248,7 @@ const reexportedBinding = (module, name)=>{
180
248
  if (!types_namespaceObject.isExportNamedDeclaration(statement) || 'type' === statement.exportKind) continue;
181
249
  const specifier = statement.specifiers.find((value)=>types_namespaceObject.isExportSpecifier(value) && 'type' !== value.exportKind && propertyName(value.exported) === name);
182
250
  if (void 0 !== specifier && types_namespaceObject.isExportSpecifier(specifier)) return {
183
- local: specifier.local.name,
251
+ local: types_namespaceObject.isIdentifier(specifier.local) ? specifier.local.name : specifier.local.value,
184
252
  ...statement.source ? {
185
253
  specifier: statement.source.value
186
254
  } : {}
@@ -195,7 +263,7 @@ const defaultExport = (module)=>{
195
263
  return types_namespaceObject.isExpression(declaration) ? declaration : void 0;
196
264
  }
197
265
  };
198
- const resolveBinding = (module, name, scope, readModule, seen)=>{
266
+ const resolveBinding = (module, name, scope, readModule, workspace, seen)=>{
199
267
  const key = `${scope}:${module.path}#${name}`;
200
268
  if (seen.has(key) || seen.size >= 512) return;
201
269
  seen.add(key);
@@ -205,9 +273,9 @@ const resolveBinding = (module, name, scope, readModule, seen)=>{
205
273
  module
206
274
  };
207
275
  const throughModule = (specifier, imported)=>{
208
- const resolvedPath = resolveRelativeModulePath(module.path, specifier);
209
- const target = void 0 === resolvedPath ? void 0 : readModule(resolvedPath);
210
- return void 0 === target ? void 0 : resolveBinding(target, imported, 'export', readModule, seen);
276
+ const resolved = resolveModulePath(module, specifier, workspace);
277
+ const target = resolved && readModule(resolved.path, resolved.boundary);
278
+ return void 0 === target ? void 0 : resolveBinding(target, imported, 'export', readModule, workspace, seen);
211
279
  };
212
280
  if ('local' === scope) {
213
281
  const imported = importedBinding(module, name);
@@ -215,14 +283,14 @@ const resolveBinding = (module, name, scope, readModule, seen)=>{
215
283
  }
216
284
  if ('default' === name) {
217
285
  const exported = defaultExport(module);
218
- if ('string' == typeof exported) return resolveBinding(module, exported, 'local', readModule, seen);
286
+ if ('string' == typeof exported) return resolveBinding(module, exported, 'local', readModule, workspace, seen);
219
287
  return void 0 === exported ? void 0 : {
220
288
  expression: exported,
221
289
  module
222
290
  };
223
291
  }
224
292
  const reexported = reexportedBinding(module, name);
225
- if (void 0 !== reexported) return void 0 === reexported.specifier ? resolveBinding(module, reexported.local, 'local', readModule, seen) : throughModule(reexported.specifier, reexported.local);
293
+ if (void 0 !== reexported) return void 0 === reexported.specifier ? resolveBinding(module, reexported.local, 'local', readModule, workspace, seen) : throughModule(reexported.specifier, reexported.local);
226
294
  for (const statement of module.file.program.body){
227
295
  if (!types_namespaceObject.isExportAllDeclaration(statement) || 'type' === statement.exportKind) continue;
228
296
  const resolved = throughModule(statement.source.value, name);
@@ -376,6 +444,7 @@ const nonEndpointCombinators = {
376
444
  };
377
445
  const reachableEndpoints = (rootModule, declaration)=>{
378
446
  const readModule = createModuleReader(rootModule);
447
+ const workspace = containingWorkspace(rootModule.path);
379
448
  const active = new Set();
380
449
  const endpoints = [];
381
450
  const identities = new Set();
@@ -397,7 +466,7 @@ const reachableEndpoints = (rootModule, declaration)=>{
397
466
  active.add(node);
398
467
  try {
399
468
  if (types_namespaceObject.isIdentifier(node)) {
400
- const resolved = resolveBinding(module, node.name, 'local', readModule, new Set());
469
+ const resolved = resolveBinding(module, node.name, 'local', readModule, workspace, new Set());
401
470
  return void 0 !== resolved && visit(resolved.expression, resolved.module, kind, group);
402
471
  }
403
472
  if ('endpoint' === kind) {
@@ -614,11 +683,13 @@ const configuredMicroVerticalApiStem = (verticalPath, verticals)=>{
614
683
  };
615
684
  const microVerticalApiBaselineViolation = (stem, filePath, expectation)=>{
616
685
  try {
617
- const sourceFile = parseConsumer(filePath);
686
+ const realPath = external_node_fs_default().realpathSync(filePath);
687
+ const sourceFile = parseConsumer(realPath);
618
688
  if (!(0, external_microvertical_api_owner_cjs_namespaceObject.baselinePublicIdentityIsExact)(filePath, expectation)) return 'MicroVertical baseline imports must resolve the exact framework owner public export and schema identity';
619
689
  return validateParsedContract({
620
690
  file: sourceFile,
621
- path: filePath
691
+ path: realPath,
692
+ boundary: sourceBoundary(realPath, containingWorkspace(realPath))
622
693
  }, stem, expectation);
623
694
  } catch (error) {
624
695
  if (error instanceof external_source_analysis_cjs_namespaceObject.SourceSyntaxError) return `MicroVertical root contract must be valid TypeScript syntax (${error.message})`;
@@ -66,13 +66,42 @@ const normalize = (file)=>file.split(external_node_path_default().sep).join('/')
66
66
  const errorMessage = (error)=>error instanceof Error ? error.message : String(error);
67
67
  const apiApp = (app)=>'vertical' === app.kind && 'ui-only' !== app.surfaceProfile && 'horizontal-remote' !== app.deliveryUnitKind;
68
68
  function configuredApps(root, supplied) {
69
- const source = supplied ?? JSON.parse(external_node_fs_default().readFileSync(external_node_path_default().join(root, '.modernjs/ultramodern.json'), 'utf8')).topology?.apps;
70
- if (!Array.isArray(source)) throw new Error('.modernjs/ultramodern.json: topology.apps must be an array');
69
+ const topology = supplied ? void 0 : JSON.parse(external_node_fs_default().readFileSync(external_node_path_default().join(root, 'topology/reference-topology.json'), 'utf8'));
70
+ 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');
71
+ const entries = topology?.shell ? [
72
+ topology.shell,
73
+ ...topology.shells ?? [],
74
+ ...topology.verticals ?? []
75
+ ] : void 0;
76
+ const source = supplied ?? entries?.map((entry)=>{
77
+ if (!entry || 'string' != typeof entry.path || !entry.path || external_node_path_default().isAbsolute(entry.path) || entry.path.split(/[\\/]/u).includes('..')) throw new Error('topology/reference-topology.json: each app must have an explicit workspace path');
78
+ const packageFile = external_node_path_default().join(root, entry.path, 'package.json');
79
+ const manifest = JSON.parse(external_node_fs_default().readFileSync(packageFile, 'utf8'));
80
+ 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`);
81
+ const api = entry.api;
82
+ const stem = api?.stem ?? api?.readiness?.endpoint?.match(/^\/([a-z0-9]+(?:-[a-z0-9]+)*)\/readiness$/u)?.[1];
83
+ return {
84
+ id: entry.id,
85
+ kind: entry.kind,
86
+ path: entry.path,
87
+ package: manifest.name,
88
+ surfaceProfile: entry.surfaceProfile,
89
+ deliveryUnitKind: entry.deliveryUnitKind,
90
+ ...void 0 === api ? {} : {
91
+ api: {
92
+ stem,
93
+ prefix: api.bff?.prefix,
94
+ protocol: api.protocol
95
+ }
96
+ }
97
+ };
98
+ });
99
+ if (!Array.isArray(source)) throw new Error('topology/reference-topology.json: shell and verticals must describe apps');
71
100
  const paths = new Set();
72
101
  for (const app of source){
73
- if (!app || 'object' != typeof app || 'string' != typeof app.path || !app.path || external_node_path_default().isAbsolute(app.path) || app.path.split(/[\\/]/u).includes('..')) throw new Error('.modernjs/ultramodern.json: each app must have a relative workspace path');
102
+ if (!app || 'object' != typeof app || 'string' != typeof app.path || !app.path || external_node_path_default().isAbsolute(app.path) || app.path.split(/[\\/]/u).includes('..')) throw new Error('topology/reference-topology.json: each app must have a relative workspace path');
74
103
  const key = normalize(app.path);
75
- if (paths.has(key)) throw new Error(`.modernjs/ultramodern.json: duplicate app path ${key}`);
104
+ if (paths.has(key)) throw new Error(`topology/reference-topology.json: duplicate app path ${key}`);
76
105
  paths.add(key);
77
106
  for (const name of [
78
107
  'id',
@@ -81,7 +110,7 @@ function configuredApps(root, supplied) {
81
110
  'surfaceProfile',
82
111
  'deliveryUnitKind'
83
112
  ])if (void 0 !== app[name] && 'string' != typeof app[name]) throw new Error(`${key}: ${name} must be a string`);
84
- for (const [field, allowed] of Object.entries({
113
+ const allowedFields = {
85
114
  kind: [
86
115
  'shell',
87
116
  'vertical'
@@ -95,7 +124,11 @@ function configuredApps(root, supplied) {
95
124
  'microvertical',
96
125
  'horizontal-remote'
97
126
  ]
98
- }))if (void 0 !== app[field] && !allowed.includes(app[field])) throw new Error(`${key}: invalid ${field}`);
127
+ };
128
+ for (const field of Object.keys(allowedFields)){
129
+ const value = app[field];
130
+ if (void 0 !== value && !allowedFields[field].includes(value)) throw new Error(`${key}: invalid ${field}`);
131
+ }
99
132
  if (void 0 !== app.api) {
100
133
  if (!app.api || 'object' != typeof app.api || Array.isArray(app.api)) throw new Error(`${key}: api must be an object`);
101
134
  if (void 0 !== app.api.protocol && ![
@@ -183,12 +216,27 @@ function check(options, topology) {
183
216
  `${base}/index.tsx`
184
217
  ].find((candidate)=>exists(candidate));
185
218
  };
186
- const composedModules = (file)=>{
219
+ const clientExportFile = (appPath, exported)=>{
220
+ if ('string' != typeof exported || !exported.startsWith('./') || exported.split(/[\\/]/u).includes('..') || !/\.[cm]?[jt]sx?$/u.test(exported)) return;
221
+ const appDirectory = absolute(appPath);
222
+ const candidate = external_node_path_default().resolve(appDirectory, exported);
223
+ try {
224
+ const workspace = external_node_fs_default().realpathSync(root);
225
+ const owner = external_node_fs_default().realpathSync(appDirectory);
226
+ const real = external_node_fs_default().realpathSync(candidate);
227
+ if (!owner.startsWith(`${workspace}${external_node_path_default().sep}`) || !real.startsWith(`${owner}${external_node_path_default().sep}`) || !external_node_fs_default().statSync(real).isFile()) return;
228
+ } catch {
229
+ return;
230
+ }
231
+ return normalize(external_node_path_default().relative(root, candidate));
232
+ };
233
+ const composedModules = (file, appPath)=>{
187
234
  const order = [];
188
235
  const seen = new Set();
189
236
  const queue = [
190
237
  file
191
238
  ];
239
+ const owner = external_node_fs_default().realpathSync(absolute(appPath));
192
240
  while(queue.length > 0 && order.length < 128){
193
241
  const current = queue.shift();
194
242
  if (seen.has(current)) continue;
@@ -199,16 +247,19 @@ function check(options, topology) {
199
247
  for (const statement of ast.program.body){
200
248
  const source = (types_namespaceObject.isImportDeclaration(statement) || types_namespaceObject.isExportNamedDeclaration(statement) || types_namespaceObject.isExportAllDeclaration(statement)) && statement.source ? statement.source.value : void 0;
201
249
  const resolved = void 0 === source ? void 0 : resolveRelative(current, source);
202
- if (void 0 !== resolved && !seen.has(resolved)) queue.push(resolved);
250
+ if (void 0 !== resolved && !seen.has(resolved)) {
251
+ const real = external_node_fs_default().realpathSync(absolute(resolved));
252
+ if (real.startsWith(`${owner}${external_node_path_default().sep}`)) queue.push(resolved);
253
+ }
203
254
  }
204
255
  }
205
256
  return order;
206
257
  };
207
- const moduleShape = (file, imports, calls, patterns = [], defaultExport, composed = false)=>{
258
+ const moduleShape = (file, imports, calls, patterns = [], defaultExport, composedAppPath)=>{
208
259
  if (!exists(file)) return;
209
260
  const ast = parseFile(file);
210
261
  if (!ast) return;
211
- const shapeFiles = composed ? composedModules(file) : [
262
+ const shapeFiles = composedAppPath ? composedModules(file, composedAppPath) : [
212
263
  file
213
264
  ];
214
265
  const body = shapeFiles.flatMap((shapeFile)=>parseFile(shapeFile)?.program.body ?? []);
@@ -318,19 +369,25 @@ function check(options, topology) {
318
369
  }
319
370
  return;
320
371
  }
321
- if (app?.kind === 'vertical') assert(void 0 !== app.api, `${appPath}: vertical must declare its Effect API in .modernjs/ultramodern.json`);
372
+ if (app?.kind === 'vertical') assert(void 0 !== app.api, `${appPath}: vertical must declare its Effect API in topology/reference-topology.json`);
322
373
  const stem = app?.api?.stem ?? external_node_path_default().posix.basename(appPath);
323
374
  const rpc = app?.api?.protocol === 'rpc';
324
375
  const contract = `${appPath}/shared/${rpc ? 'rpc' : 'api'}.ts`;
325
- const client = `${appPath}/src/api/${stem}-${rpc ? 'rpc-client' : 'client'}.ts`;
326
376
  const entry = `${appPath}/api/index.ts`;
327
377
  for (const file of [
328
378
  entry,
329
- contract,
330
- client
379
+ contract
331
380
  ])assert(exists(file), `${file}: required API surface is missing`);
381
+ const packageFile = `${appPath}/package.json`;
382
+ assert(exists(packageFile), `${packageFile}: required API package is missing`);
383
+ if (!exists(packageFile)) return;
384
+ const manifest = JSON.parse(read(packageFile));
385
+ assert(manifest.exports?.['./api'] === `./shared/${rpc ? 'rpc' : 'api'}.ts`, `${packageFile}: invalid ./api export`);
386
+ const clientKey = `./api/${rpc ? 'rpc-client' : 'client'}`;
387
+ const client = clientExportFile(appPath, manifest.exports?.[clientKey]);
388
+ assert(void 0 !== client, `${packageFile}: invalid API client export`);
389
+ assert(manifest.exports?.[`./api/${rpc ? 'client' : 'rpc-client'}`] === void 0, `${packageFile}: forbidden opposite protocol client export`);
332
390
  noPath(`${appPath}/shared/${rpc ? 'api' : 'rpc'}.ts`, `must not emit a ${rpc ? 'REST' : 'RPC'} contract`);
333
- noPath(`${appPath}/src/api/${stem}-${rpc ? 'client' : 'rpc-client'}.ts`, `must not emit a ${rpc ? 'REST' : 'RPC'} client`);
334
391
  if (rpc) {
335
392
  moduleShape(entry, [
336
393
  [
@@ -396,21 +453,24 @@ function check(options, topology) {
396
453
  const violation = (0, external_microvertical_api_baseline_cjs_namespaceObject.microVerticalApiBaselineViolation)(stem, absolute(contract), expectation);
397
454
  if (violation) diagnostics.push(`${contract}: ${violation}`);
398
455
  }
399
- moduleShape(client, [
400
- [
401
- effect,
456
+ if (client) {
457
+ const relativeContract = external_node_path_default().posix.relative(external_node_path_default().posix.dirname(client), contract);
458
+ moduleShape(client, [
459
+ [
460
+ effect,
461
+ [
462
+ 'Effect',
463
+ rpc ? 'makeEffectRpcClient' : 'makeEffectHttpApiClient'
464
+ ]
465
+ ],
402
466
  [
403
- 'Effect',
404
- rpc ? 'makeEffectRpcClient' : 'makeEffectHttpApiClient'
467
+ relativeContract.startsWith('.') ? relativeContract : `./${relativeContract}`,
468
+ []
405
469
  ]
406
- ],
407
- [
408
- rpc ? '../../shared/rpc.ts' : '../../shared/api',
409
- []
410
- ]
411
- ], [
412
- rpc ? 'makeEffectRpcClient' : 'makeEffectHttpApiClient'
413
- ], [], void 0, true);
470
+ ], [
471
+ rpc ? 'makeEffectRpcClient' : 'makeEffectHttpApiClient'
472
+ ], [], void 0, appPath);
473
+ }
414
474
  moduleShape(`${appPath}/api/effect-api.ts`, [], [], [
415
475
  [
416
476
  /\bbackendFederationContract\b/u,
@@ -451,13 +511,6 @@ function check(options, topology) {
451
511
  'must enable strictEffectApproach'
452
512
  ]
453
513
  ]);
454
- const packageFile = `${appPath}/package.json`;
455
- if (exists(packageFile)) {
456
- const manifest = JSON.parse(read(packageFile));
457
- assert(manifest.exports?.['./api'] === `./shared/${rpc ? 'rpc' : 'api'}.ts`, `${packageFile}: invalid ./api export`);
458
- assert(manifest.exports?.[`./api/${rpc ? 'rpc-client' : 'client'}`] === `./src/api/${stem}-${rpc ? 'rpc-client' : 'client'}.ts`, `${packageFile}: invalid API client export`);
459
- assert(manifest.exports?.[`./api/${rpc ? 'client' : 'rpc-client'}`] === void 0, `${packageFile}: forbidden opposite protocol client export`);
460
- }
461
514
  });
462
515
  const shell = 'apps/shell-super-app';
463
516
  const verticals = apps.filter((app)=>app.path.startsWith('verticals/') && apiApp(app));
@@ -52,7 +52,7 @@ const createStrictEffectApiBoundariesRule = ()=>({
52
52
  });
53
53
  (0, external_ast_cjs_namespaceObject.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.');
54
54
  (0, external_ast_cjs_namespaceObject.reportProgramPattern)(context, node, source, /\bruntimeFramework\s*(?::|=)\s*['"]hono['"]/u, 'UltraModern API apps must use bff.runtimeFramework: "effect".');
55
- (0, external_ast_cjs_namespaceObject.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.');
55
+ (0, external_ast_cjs_namespaceObject.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.');
56
56
  (0, external_ast_cjs_namespaceObject.reportProgramPattern)(context, node, source, /\bstrictEffectApproach\s*(?::|=)\s*false\b/u, 'UltraModern API apps must keep strictEffectApproach enabled.');
57
57
  if ((0, external_ast_cjs_namespaceObject.isApiEntryFile)(filename)) {
58
58
  const violation = (0, external_strict_effect_runtime_cjs_namespaceObject.strictEffectRuntimeTopologyViolation)(source, (0, external_strict_effect_runtime_cjs_namespaceObject.createEffectApiImportResolver)(filename));
@@ -48,8 +48,9 @@ const types_namespaceObject = require("@babel/types");
48
48
  const external_source_analysis_cjs_namespaceObject = require("./source-analysis.cjs");
49
49
  const edge = '@modern-js/bff-effect/effect-edge';
50
50
  const nodeRuntime = '@modern-js/bff-effect/effect';
51
- const sharedRuntime = /^@[^/]+\/shared-contracts\/server\/effect-bff-runtime$/u;
52
- 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.';
51
+ const assembly = '@modern-js/bff-effect/assembly';
52
+ 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.';
53
+ const MAX_API_SOURCE_MODULES = 256;
53
54
  function createEffectApiImportResolver(filename) {
54
55
  const directory = external_node_fs_default().realpathSync(external_node_path_default().dirname(filename));
55
56
  const owner = external_node_fs_default().realpathSync(external_node_path_default().resolve(directory, '..'));
@@ -81,7 +82,7 @@ function strictEffectRuntimeTopologyViolation(source, resolveImport) {
81
82
  const load = (input)=>{
82
83
  const existing = modules.get(input.id);
83
84
  if (existing) return existing;
84
- if (modules.size >= 64 || input.source.length > 1000000) throw new external_source_analysis_cjs_namespaceObject.SourceSyntaxError('API source budget exceeded');
85
+ if (modules.size >= MAX_API_SOURCE_MODULES || input.source.length > 1000000) throw new external_source_analysis_cjs_namespaceObject.SourceSyntaxError('API source budget exceeded');
85
86
  const file = (0, external_source_analysis_cjs_namespaceObject.parseSource)(input.source, input.id, 'Invalid API syntax');
86
87
  const module = {
87
88
  ...input,
@@ -245,7 +246,7 @@ function strictEffectRuntimeTopologyViolation(source, resolveImport) {
245
246
  if (!types_namespaceObject.isBlockStatement(body)) return body;
246
247
  const statements = body.body;
247
248
  const last = statements.at(-1);
248
- return statements.slice(0, -1).every((statement)=>types_namespaceObject.isVariableDeclaration(statement)) && types_namespaceObject.isReturnStatement(last) ? last.argument : void 0;
249
+ return statements.slice(0, -1).every((statement)=>types_namespaceObject.isVariableDeclaration(statement) || types_namespaceObject.isTSTypeAliasDeclaration(statement) || types_namespaceObject.isTSInterfaceDeclaration(statement)) && types_namespaceObject.isReturnStatement(last) ? last.argument : void 0;
249
250
  };
250
251
  const pipe = (node, check)=>types_namespaceObject.isMemberExpression(node.callee) && !node.callee.computed && types_namespaceObject.isIdentifier(node.callee.property, {
251
252
  name: 'pipe'
@@ -334,7 +335,7 @@ function strictEffectRuntimeTopologyViolation(source, resolveImport) {
334
335
  if (value?.name === 'defineEffectBff' && [
335
336
  edge,
336
337
  nodeRuntime
337
- ].includes(value.specifier) || value?.name === 'assembleEffectBffRuntime' && sharedRuntime.test(value.specifier)) {
338
+ ].includes(value.specifier) || value?.name === 'assembleEffectBffRuntime' && value.specifier === assembly) {
338
339
  if (1 !== node.arguments.length) return false;
339
340
  const values = properties(node.arguments[0]);
340
341
  if (!values) return false;
@@ -1,5 +1,7 @@
1
1
  import node_fs from "node:fs";
2
+ import { createRequire } from "node:module";
2
3
  import node_path from "node:path";
4
+ import { exports as external_resolve_exports_exports } from "resolve.exports";
3
5
  import { baselinePublicIdentityIsExact } from "./microvertical-api-owner.js";
4
6
  import { SourceSyntaxError, parseSource, traverseSource, unwrapExpression } from "./source-analysis.js";
5
7
  import * as __rspack_external__babel_types_6e8337dd from "@babel/types";
@@ -81,16 +83,81 @@ const exportedConst = (sourceFile, name)=>{
81
83
  }))) return localConst(sourceFile, name);
82
84
  }
83
85
  };
84
- const resolveRelativeModulePath = (fromPath, specifier)=>{
85
- if (!/^\.\.?\//u.test(specifier)) return;
86
- const resolved = node_path.resolve(node_path.dirname(fromPath), specifier);
87
- const stem = resolved.replace(/\.(?:[cm]?[jt]sx?)$/u, '');
86
+ const inside = (file, boundary)=>file === boundary || file.startsWith(`${boundary}${node_path.sep}`);
87
+ const containingWorkspace = (file)=>{
88
+ for(let directory = node_path.dirname(file);; directory = node_path.dirname(directory)){
89
+ if (node_fs.existsSync(node_path.join(directory, 'pnpm-workspace.yaml'))) return node_fs.realpathSync(directory);
90
+ if (directory === node_path.dirname(directory)) return;
91
+ }
92
+ };
93
+ const sourceBoundary = (file, workspace)=>{
94
+ for(let directory = node_path.dirname(file);; directory = node_path.dirname(directory)){
95
+ if (node_fs.existsSync(node_path.join(directory, 'package.json')) && directory !== workspace) return node_fs.realpathSync(directory);
96
+ if (directory === workspace || directory === node_path.dirname(directory)) return node_fs.realpathSync(node_path.dirname(file));
97
+ }
98
+ };
99
+ const sourceFileAt = (target, boundary)=>{
100
+ const stem = target.replace(/\.(?:[cm]?[jt]sx?)$/u, '');
88
101
  for (const candidate of [
89
102
  `${stem}.ts`,
90
103
  `${stem}.tsx`,
91
- node_path.join(stem, 'index.ts'),
92
- node_path.join(stem, 'index.tsx')
93
- ])if (node_fs.existsSync(candidate) && node_fs.statSync(candidate).isFile()) return candidate;
104
+ `${stem}.mts`,
105
+ `${stem}.cts`,
106
+ target,
107
+ node_path.join(target, 'index.ts'),
108
+ node_path.join(target, 'index.tsx')
109
+ ])try {
110
+ const real = node_fs.realpathSync(candidate);
111
+ if (inside(real, boundary) && node_fs.statSync(real).isFile()) return real;
112
+ } catch {}
113
+ };
114
+ const packageEntry = (specifier)=>{
115
+ if (specifier.startsWith('.') || specifier.startsWith('/') || specifier.startsWith('#')) return;
116
+ const parts = specifier.split('/');
117
+ const count = specifier.startsWith('@') ? 2 : 1;
118
+ if (parts.length < count || parts.slice(0, count).some((part)=>!part)) return;
119
+ return {
120
+ name: parts.slice(0, count).join('/'),
121
+ exportKey: parts.length === count ? '.' : `./${parts.slice(count).join('/')}`
122
+ };
123
+ };
124
+ const resolveModulePath = (module, specifier, workspace)=>{
125
+ if (/^\.\.?\//u.test(specifier)) {
126
+ const file = sourceFileAt(node_path.resolve(node_path.dirname(module.path), specifier), module.boundary);
127
+ return void 0 === file ? void 0 : {
128
+ path: file,
129
+ boundary: module.boundary
130
+ };
131
+ }
132
+ const entry = packageEntry(specifier);
133
+ if (!entry || !workspace) return;
134
+ const paths = createRequire(module.path).resolve.paths(entry.name) ?? [];
135
+ for (const lookup of paths){
136
+ const directory = node_path.join(lookup, entry.name);
137
+ const manifest = node_path.join(directory, 'package.json');
138
+ if (!node_fs.existsSync(manifest)) continue;
139
+ const boundary = node_fs.realpathSync(directory);
140
+ if (!inside(boundary, workspace) || boundary.split(node_path.sep).includes('node_modules')) break;
141
+ const pkg = JSON.parse(node_fs.readFileSync(manifest, 'utf8'));
142
+ if (pkg.name !== entry.name || void 0 === pkg.exports) break;
143
+ let target;
144
+ try {
145
+ const targets = external_resolve_exports_exports(pkg, entry.exportKey, {
146
+ conditions: [
147
+ 'modern:source'
148
+ ]
149
+ });
150
+ target = Array.isArray(targets) ? targets[0] : void 0;
151
+ } catch {
152
+ break;
153
+ }
154
+ if (!target || !target.startsWith('./')) break;
155
+ const file = sourceFileAt(node_path.resolve(boundary, target), boundary);
156
+ return void 0 === file ? void 0 : {
157
+ path: file,
158
+ boundary
159
+ };
160
+ }
94
161
  };
95
162
  const createModuleReader = (root)=>{
96
163
  const modules = new Map([
@@ -99,14 +166,15 @@ const createModuleReader = (root)=>{
99
166
  root
100
167
  ]
101
168
  ]);
102
- return (filePath)=>{
169
+ return (filePath, boundary)=>{
103
170
  if (modules.has(filePath)) return modules.get(filePath);
104
171
  if (modules.size >= 256) return;
105
172
  let module;
106
173
  try {
107
174
  module = {
108
175
  file: parseConsumer(filePath),
109
- path: filePath
176
+ path: filePath,
177
+ boundary
110
178
  };
111
179
  } catch {
112
180
  module = void 0;
@@ -136,7 +204,7 @@ const reexportedBinding = (module, name)=>{
136
204
  if (!__rspack_external__babel_types_6e8337dd.isExportNamedDeclaration(statement) || 'type' === statement.exportKind) continue;
137
205
  const specifier = statement.specifiers.find((value)=>__rspack_external__babel_types_6e8337dd.isExportSpecifier(value) && 'type' !== value.exportKind && propertyName(value.exported) === name);
138
206
  if (void 0 !== specifier && __rspack_external__babel_types_6e8337dd.isExportSpecifier(specifier)) return {
139
- local: specifier.local.name,
207
+ local: __rspack_external__babel_types_6e8337dd.isIdentifier(specifier.local) ? specifier.local.name : specifier.local.value,
140
208
  ...statement.source ? {
141
209
  specifier: statement.source.value
142
210
  } : {}
@@ -151,7 +219,7 @@ const defaultExport = (module)=>{
151
219
  return __rspack_external__babel_types_6e8337dd.isExpression(declaration) ? declaration : void 0;
152
220
  }
153
221
  };
154
- const resolveBinding = (module, name, scope, readModule, seen)=>{
222
+ const resolveBinding = (module, name, scope, readModule, workspace, seen)=>{
155
223
  const key = `${scope}:${module.path}#${name}`;
156
224
  if (seen.has(key) || seen.size >= 512) return;
157
225
  seen.add(key);
@@ -161,9 +229,9 @@ const resolveBinding = (module, name, scope, readModule, seen)=>{
161
229
  module
162
230
  };
163
231
  const throughModule = (specifier, imported)=>{
164
- const resolvedPath = resolveRelativeModulePath(module.path, specifier);
165
- const target = void 0 === resolvedPath ? void 0 : readModule(resolvedPath);
166
- return void 0 === target ? void 0 : resolveBinding(target, imported, 'export', readModule, seen);
232
+ const resolved = resolveModulePath(module, specifier, workspace);
233
+ const target = resolved && readModule(resolved.path, resolved.boundary);
234
+ return void 0 === target ? void 0 : resolveBinding(target, imported, 'export', readModule, workspace, seen);
167
235
  };
168
236
  if ('local' === scope) {
169
237
  const imported = importedBinding(module, name);
@@ -171,14 +239,14 @@ const resolveBinding = (module, name, scope, readModule, seen)=>{
171
239
  }
172
240
  if ('default' === name) {
173
241
  const exported = defaultExport(module);
174
- if ('string' == typeof exported) return resolveBinding(module, exported, 'local', readModule, seen);
242
+ if ('string' == typeof exported) return resolveBinding(module, exported, 'local', readModule, workspace, seen);
175
243
  return void 0 === exported ? void 0 : {
176
244
  expression: exported,
177
245
  module
178
246
  };
179
247
  }
180
248
  const reexported = reexportedBinding(module, name);
181
- if (void 0 !== reexported) return void 0 === reexported.specifier ? resolveBinding(module, reexported.local, 'local', readModule, seen) : throughModule(reexported.specifier, reexported.local);
249
+ if (void 0 !== reexported) return void 0 === reexported.specifier ? resolveBinding(module, reexported.local, 'local', readModule, workspace, seen) : throughModule(reexported.specifier, reexported.local);
182
250
  for (const statement of module.file.program.body){
183
251
  if (!__rspack_external__babel_types_6e8337dd.isExportAllDeclaration(statement) || 'type' === statement.exportKind) continue;
184
252
  const resolved = throughModule(statement.source.value, name);
@@ -332,6 +400,7 @@ const nonEndpointCombinators = {
332
400
  };
333
401
  const reachableEndpoints = (rootModule, declaration)=>{
334
402
  const readModule = createModuleReader(rootModule);
403
+ const workspace = containingWorkspace(rootModule.path);
335
404
  const active = new Set();
336
405
  const endpoints = [];
337
406
  const identities = new Set();
@@ -353,7 +422,7 @@ const reachableEndpoints = (rootModule, declaration)=>{
353
422
  active.add(node);
354
423
  try {
355
424
  if (__rspack_external__babel_types_6e8337dd.isIdentifier(node)) {
356
- const resolved = resolveBinding(module, node.name, 'local', readModule, new Set());
425
+ const resolved = resolveBinding(module, node.name, 'local', readModule, workspace, new Set());
357
426
  return void 0 !== resolved && visit(resolved.expression, resolved.module, kind, group);
358
427
  }
359
428
  if ('endpoint' === kind) {
@@ -570,11 +639,13 @@ const configuredMicroVerticalApiStem = (verticalPath, verticals)=>{
570
639
  };
571
640
  const microVerticalApiBaselineViolation = (stem, filePath, expectation)=>{
572
641
  try {
573
- const sourceFile = parseConsumer(filePath);
642
+ const realPath = node_fs.realpathSync(filePath);
643
+ const sourceFile = parseConsumer(realPath);
574
644
  if (!baselinePublicIdentityIsExact(filePath, expectation)) return 'MicroVertical baseline imports must resolve the exact framework owner public export and schema identity';
575
645
  return validateParsedContract({
576
646
  file: sourceFile,
577
- path: filePath
647
+ path: realPath,
648
+ boundary: sourceBoundary(realPath, containingWorkspace(realPath))
578
649
  }, stem, expectation);
579
650
  } catch (error) {
580
651
  if (error instanceof SourceSyntaxError) return `MicroVertical root contract must be valid TypeScript syntax (${error.message})`;