@bleedingdev/modern-js-code-tools 3.9.0-ultramodern.17 → 3.9.0-ultramodern.18

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.
@@ -1,35 +1,13 @@
1
- import node_fs from "node:fs";
2
- import { createRequire } from "node:module";
3
- import node_path from "node:path";
4
- import { exports as external_resolve_exports_exports } from "resolve.exports";
5
1
  import { baselinePublicIdentityIsExact } from "./microvertical-api-owner.js";
6
- import { SourceSyntaxError, parseSource, traverseSource, unwrapExpression } from "./source-analysis.js";
2
+ import { createModuleGraph, exportedConst, localConst, propertyName } from "./module-graph.js";
3
+ import { SourceSyntaxError, unwrapExpression } from "./source-analysis.js";
7
4
  import * as __rspack_external__babel_types_6e8337dd from "@babel/types";
8
- function parseConsumer(filePath) {
9
- if (node_fs.statSync(filePath).size > 1000000) throw new Error(`${filePath}: consumer source exceeds 1 MB analysis budget`);
10
- const file = parseSource(node_fs.readFileSync(filePath, 'utf8'), filePath);
11
- traverseSource(file, {
12
- AssignmentExpression (p) {
13
- throw new SourceSyntaxError(`contract bindings must be immutable at ${p.node.start}`);
14
- },
15
- UpdateExpression (p) {
16
- throw new SourceSyntaxError(`contract bindings must be immutable at ${p.node.start}`);
17
- },
18
- TSModuleDeclaration () {
19
- throw new SourceSyntaxError('contract bindings must not be merged with namespaces');
20
- }
21
- });
22
- return file;
23
- }
24
5
  const camelCaseStem = (stem)=>stem.replaceAll(/-([a-z0-9])/gu, (_match, letter)=>letter.toUpperCase());
25
6
  const pascalCaseStem = (stem)=>{
26
7
  const camelStem = camelCaseStem(stem);
27
8
  return `${camelStem.slice(0, 1).toUpperCase()}${camelStem.slice(1)}`;
28
9
  };
29
10
  const identifierName = (node)=>void 0 !== node && __rspack_external__babel_types_6e8337dd.isIdentifier(node) ? node.name : void 0;
30
- const propertyName = (node)=>{
31
- if (void 0 !== node && (__rspack_external__babel_types_6e8337dd.isIdentifier(node) || __rspack_external__babel_types_6e8337dd.isStringLiteral(node) || __rspack_external__babel_types_6e8337dd.isNumericLiteral(node))) return __rspack_external__babel_types_6e8337dd.isIdentifier(node) ? node.name : String(node.value);
32
- };
33
11
  const accessPath = (node)=>{
34
12
  if (__rspack_external__babel_types_6e8337dd.isIdentifier(node)) return [
35
13
  node.name
@@ -58,201 +36,6 @@ const callExpression = (expression, callee)=>{
58
36
  const unwrapped = unwrapExpression(expression);
59
37
  return __rspack_external__babel_types_6e8337dd.isCallExpression(unwrapped) && isAccessPath(unwrapped.callee, callee) ? unwrapped : void 0;
60
38
  };
61
- const localConst = (sourceFile, name)=>{
62
- for (const item of sourceFile.program.body){
63
- const statement = __rspack_external__babel_types_6e8337dd.isExportNamedDeclaration(item) ? item.declaration : item;
64
- if (!__rspack_external__babel_types_6e8337dd.isVariableDeclaration(statement) || 'const' !== statement.kind) continue;
65
- const matches = statement.declarations.filter((declaration)=>__rspack_external__babel_types_6e8337dd.isIdentifier(declaration.id, {
66
- name
67
- }));
68
- if (1 === matches.length) return matches[0];
69
- }
70
- };
71
- const exportedConst = (sourceFile, name)=>{
72
- for (const statement of sourceFile.program.body)if (__rspack_external__babel_types_6e8337dd.isExportNamedDeclaration(statement) && 'type' !== statement.exportKind) {
73
- if (__rspack_external__babel_types_6e8337dd.isVariableDeclaration(statement.declaration) && 'const' === statement.declaration.kind) {
74
- const declaration = statement.declaration.declarations.find((value)=>__rspack_external__babel_types_6e8337dd.isIdentifier(value.id, {
75
- name
76
- }));
77
- if (declaration) return declaration;
78
- }
79
- if (!statement.source && statement.specifiers.some((value)=>__rspack_external__babel_types_6e8337dd.isExportSpecifier(value) && 'type' !== value.exportKind && __rspack_external__babel_types_6e8337dd.isIdentifier(value.local, {
80
- name
81
- }) && __rspack_external__babel_types_6e8337dd.isIdentifier(value.exported, {
82
- name
83
- }))) return localConst(sourceFile, name);
84
- }
85
- };
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, '');
101
- for (const candidate of [
102
- `${stem}.ts`,
103
- `${stem}.tsx`,
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
- }
161
- };
162
- const createModuleReader = (root)=>{
163
- const modules = new Map([
164
- [
165
- root.path,
166
- root
167
- ]
168
- ]);
169
- return (filePath, boundary)=>{
170
- if (modules.has(filePath)) return modules.get(filePath);
171
- if (modules.size >= 256) return;
172
- let module;
173
- try {
174
- module = {
175
- file: parseConsumer(filePath),
176
- path: filePath,
177
- boundary
178
- };
179
- } catch {
180
- module = void 0;
181
- }
182
- modules.set(filePath, module);
183
- return module;
184
- };
185
- };
186
- const importedBinding = (module, name)=>{
187
- for (const statement of module.file.program.body)if (__rspack_external__babel_types_6e8337dd.isImportDeclaration(statement) && 'type' !== statement.importKind) {
188
- for (const specifier of statement.specifiers)if (__rspack_external__babel_types_6e8337dd.isIdentifier(specifier.local, {
189
- name
190
- })) {
191
- if (__rspack_external__babel_types_6e8337dd.isImportSpecifier(specifier) && 'type' !== specifier.importKind) return {
192
- imported: propertyName(specifier.imported) ?? name,
193
- specifier: statement.source.value
194
- };
195
- if (__rspack_external__babel_types_6e8337dd.isImportDefaultSpecifier(specifier)) return {
196
- imported: 'default',
197
- specifier: statement.source.value
198
- };
199
- }
200
- }
201
- };
202
- const reexportedBinding = (module, name)=>{
203
- for (const statement of module.file.program.body){
204
- if (!__rspack_external__babel_types_6e8337dd.isExportNamedDeclaration(statement) || 'type' === statement.exportKind) continue;
205
- const specifier = statement.specifiers.find((value)=>__rspack_external__babel_types_6e8337dd.isExportSpecifier(value) && 'type' !== value.exportKind && propertyName(value.exported) === name);
206
- if (void 0 !== specifier && __rspack_external__babel_types_6e8337dd.isExportSpecifier(specifier)) return {
207
- local: __rspack_external__babel_types_6e8337dd.isIdentifier(specifier.local) ? specifier.local.name : specifier.local.value,
208
- ...statement.source ? {
209
- specifier: statement.source.value
210
- } : {}
211
- };
212
- }
213
- };
214
- const defaultExport = (module)=>{
215
- for (const statement of module.file.program.body){
216
- if (!__rspack_external__babel_types_6e8337dd.isExportDefaultDeclaration(statement)) continue;
217
- const declaration = statement.declaration;
218
- if (__rspack_external__babel_types_6e8337dd.isIdentifier(declaration)) return declaration.name;
219
- return __rspack_external__babel_types_6e8337dd.isExpression(declaration) ? declaration : void 0;
220
- }
221
- };
222
- const resolveBinding = (module, name, scope, readModule, workspace, seen)=>{
223
- const key = `${scope}:${module.path}#${name}`;
224
- if (seen.has(key) || seen.size >= 512) return;
225
- seen.add(key);
226
- const declaration = 'export' === scope ? exportedConst(module.file, name) : localConst(module.file, name);
227
- if (declaration?.init) return {
228
- expression: declaration.init,
229
- module
230
- };
231
- const throughModule = (specifier, imported)=>{
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);
235
- };
236
- if ('local' === scope) {
237
- const imported = importedBinding(module, name);
238
- return void 0 === imported ? void 0 : throughModule(imported.specifier, imported.imported);
239
- }
240
- if ('default' === name) {
241
- const exported = defaultExport(module);
242
- if ('string' == typeof exported) return resolveBinding(module, exported, 'local', readModule, workspace, seen);
243
- return void 0 === exported ? void 0 : {
244
- expression: exported,
245
- module
246
- };
247
- }
248
- const reexported = reexportedBinding(module, name);
249
- if (void 0 !== reexported) return void 0 === reexported.specifier ? resolveBinding(module, reexported.local, 'local', readModule, workspace, seen) : throughModule(reexported.specifier, reexported.local);
250
- for (const statement of module.file.program.body){
251
- if (!__rspack_external__babel_types_6e8337dd.isExportAllDeclaration(statement) || 'type' === statement.exportKind) continue;
252
- const resolved = throughModule(statement.source.value, name);
253
- if (void 0 !== resolved) return resolved;
254
- }
255
- };
256
39
  const objectLiteral = (expression)=>{
257
40
  if (null == expression) return;
258
41
  const unwrapped = unwrapExpression(expression);
@@ -380,9 +163,13 @@ const rootComposesFoundation = (sourceFile, declaration, stem, foundationName)=>
380
163
  return void 0 !== chain && isAccessPath(chain.base.callee, [
381
164
  'HttpApi',
382
165
  'make'
383
- ]) && 1 === chain.base.arguments.length && stringLiteral(chain.base.arguments[0]) === `${pascalCaseStem(stem)}Api` && chain.methods.length > 0 && chain.methods.every((method, index)=>1 === method.arguments.length && ('add' === method.name || 'addHttpApi' === method.name || index === chain.methods.length - 1 && 'pipe' === method.name && 'identity' === identifierName(method.arguments[0]) && importsExactBindings(sourceFile, 'effect', [
166
+ ]) && 1 === chain.base.arguments.length && stringLiteral(chain.base.arguments[0]) === `${pascalCaseStem(stem)}Api` && chain.methods.length > 0 && chain.methods.every((method, index)=>{
167
+ const combinatorArity = nonEndpointCombinators.api[method.name];
168
+ if (void 0 !== combinatorArity) return method.arguments.length === combinatorArity;
169
+ return 1 === method.arguments.length && ('add' === method.name || 'addHttpApi' === method.name || index === chain.methods.length - 1 && 'pipe' === method.name && 'identity' === identifierName(method.arguments[0]) && importsExactBindings(sourceFile, 'effect', [
384
170
  'identity'
385
- ]))) && first?.name === 'addHttpApi' && identifierName(first.arguments[0]) === foundationName;
171
+ ]));
172
+ }) && first?.name === 'addHttpApi' && identifierName(first.arguments[0]) === foundationName;
386
173
  };
387
174
  const nonEndpointCombinators = {
388
175
  api: {
@@ -398,9 +185,7 @@ const nonEndpointCombinators = {
398
185
  middleware: 1
399
186
  }
400
187
  };
401
- const reachableEndpoints = (rootModule, declaration)=>{
402
- const readModule = createModuleReader(rootModule);
403
- const workspace = containingWorkspace(rootModule.path);
188
+ const reachableEndpoints = (graph, declaration)=>{
404
189
  const active = new Set();
405
190
  const endpoints = [];
406
191
  const identities = new Set();
@@ -422,8 +207,8 @@ const reachableEndpoints = (rootModule, declaration)=>{
422
207
  active.add(node);
423
208
  try {
424
209
  if (__rspack_external__babel_types_6e8337dd.isIdentifier(node)) {
425
- const resolved = resolveBinding(module, node.name, 'local', readModule, workspace, new Set());
426
- return void 0 !== resolved && visit(resolved.expression, resolved.module, kind, group);
210
+ const resolved = graph.resolve(module, node.name, 'local');
211
+ return resolved?.kind === 'declaration' && visit(resolved.expression, resolved.module, kind, group);
427
212
  }
428
213
  if ('endpoint' === kind) {
429
214
  if (!__rspack_external__babel_types_6e8337dd.isCallExpression(node) || node.arguments.length < 2 || node.arguments.length > 3) return false;
@@ -478,7 +263,7 @@ const reachableEndpoints = (rootModule, declaration)=>{
478
263
  active.delete(node);
479
264
  }
480
265
  };
481
- return visit(declaration?.init, rootModule, 'api') ? endpoints : void 0;
266
+ return visit(declaration?.init, graph.root, 'api') ? endpoints : void 0;
482
267
  };
483
268
  const operationContextFields = (property)=>{
484
269
  const constructorCall = exactCall(property.value, [
@@ -609,8 +394,8 @@ const readinessSchemaIsShared = (declaration, markerSchemaName, ownerMarkerIsIde
609
394
  return void 0 !== schema && (schema.identity && ownerMarkerIsIdentity || 1 === schema.assignments.size && identifierName(schema.assignments.get('marker')?.value) === markerSchemaName);
610
395
  };
611
396
  const declarationIsIdentifier = (declaration, identifier)=>declaration?.init != null && identifierName(unwrapExpression(declaration.init)) === identifier;
612
- const validateParsedContract = (module, stem, expectation)=>{
613
- const sourceFile = module.file;
397
+ const validateParsedContract = (graph, stem, expectation)=>{
398
+ const sourceFile = graph.root.file;
614
399
  const exportStem = camelCaseStem(stem);
615
400
  const foundationName = `${exportStem}FoundationApi`;
616
401
  const markerSchemaName = `${exportStem}MarkerSchema`;
@@ -627,7 +412,7 @@ const validateParsedContract = (module, stem, expectation)=>{
627
412
  if (!readinessSchemaIsShared(exportedConst(sourceFile, readinessSchemaName), markerSchemaName, declarationIsIdentifier(markerDeclaration, 'MicroVerticalBuildMarkerSchema'))) return 'MicroVertical readiness schema must consume the shared readiness schema without overriding shared fields';
628
413
  if (!foundationIsExact(exportedConst(sourceFile, foundationName), stem, readinessSchemaName)) return 'MicroVertical readiness foundation API must directly compose its exact readiness endpoint and foundation identity';
629
414
  if (!rootComposesFoundation(sourceFile, exportedConst(sourceFile, `${exportStem}Api`), stem, foundationName)) return 'MicroVertical root API must explicitly compose its readiness foundation API';
630
- const endpoints = reachableEndpoints(module, exportedConst(sourceFile, `${exportStem}Api`));
415
+ const endpoints = reachableEndpoints(graph, exportedConst(sourceFile, `${exportStem}Api`));
631
416
  if (!endpoints) return 'MicroVertical root API must compose bounded native endpoint declarations without ambiguous identities';
632
417
  if (!operationMapIsConnected(exportedConst(sourceFile, `${exportStem}OperationContexts`), stem, expectation.operationPaths ?? {}, endpoints)) return 'MicroVertical operation map must construct every operation with the shared context constructor';
633
418
  if (!metadataIsExact(exportedConst(sourceFile, `${exportStem}ApiContract`), expectation, endpoints)) return 'MicroVertical root contract must keep exact owner and API path metadata without forbidden fields';
@@ -639,14 +424,9 @@ const configuredMicroVerticalApiStem = (verticalPath, verticals)=>{
639
424
  };
640
425
  const microVerticalApiBaselineViolation = (stem, filePath, expectation)=>{
641
426
  try {
642
- const realPath = node_fs.realpathSync(filePath);
643
- const sourceFile = parseConsumer(realPath);
427
+ const graph = createModuleGraph(filePath);
644
428
  if (!baselinePublicIdentityIsExact(filePath, expectation)) return 'MicroVertical baseline imports must resolve the exact framework owner public export and schema identity';
645
- return validateParsedContract({
646
- file: sourceFile,
647
- path: realPath,
648
- boundary: sourceBoundary(realPath, containingWorkspace(realPath))
649
- }, stem, expectation);
429
+ return validateParsedContract(graph, stem, expectation);
650
430
  } catch (error) {
651
431
  if (error instanceof SourceSyntaxError) return `MicroVertical root contract must be valid TypeScript syntax (${error.message})`;
652
432
  throw error;
@@ -3,7 +3,8 @@ import node_path from "node:path";
3
3
  import { parse } from "@babel/parser";
4
4
  import { configuredMicroVerticalApiStem, microVerticalApiBaselineViolation } from "./microvertical-api-baseline.js";
5
5
  import { baselinePackage, resolveBaselinePackageDirectory } from "./microvertical-api-owner.js";
6
- import { consumerParserPlugins } from "./source-analysis.js";
6
+ import { createModuleGraph } from "./module-graph.js";
7
+ import { SourceSyntaxError, consumerParserPlugins } from "./source-analysis.js";
7
8
  import { createEffectApiImportResolver, strictEffectRuntimeTopologyViolation } from "./strict-effect-runtime.js";
8
9
  import * as __rspack_external__babel_types_6e8337dd from "@babel/types";
9
10
  const ignored = new Set([
@@ -407,6 +408,27 @@ function check(options, topology) {
407
408
  const violation = microVerticalApiBaselineViolation(stem, absolute(contract), expectation);
408
409
  if (violation) diagnostics.push(`${contract}: ${violation}`);
409
410
  }
411
+ if (options.contractRules?.length && exists(contract)) {
412
+ let graph;
413
+ try {
414
+ graph = createModuleGraph(absolute(contract));
415
+ } catch (error) {
416
+ if (!(error instanceof SourceSyntaxError)) throw error;
417
+ diagnostics.push(`${contract}: contract rules need a parseable contract with immutable bindings (${error.message})`);
418
+ }
419
+ if (graph) {
420
+ const context = {
421
+ appPath,
422
+ protocol: rpc ? 'rpc' : 'rest',
423
+ graph
424
+ };
425
+ for (const rule of options.contractRules)guarded(`${contract} (rule ${rule.name || 'anonymous'})`, ()=>{
426
+ const messages = rule(context);
427
+ if (!Array.isArray(messages) || !messages.every((message)=>'string' == typeof message)) throw new Error('contract rule must return an array of violation messages (return [] when the contract passes)');
428
+ for (const message of messages)diagnostics.push(`${contract}: ${message}`);
429
+ });
430
+ }
431
+ }
410
432
  if (client) {
411
433
  const relativeContract = node_path.posix.relative(node_path.posix.dirname(client), contract);
412
434
  moduleShape(client, [
@@ -500,4 +522,4 @@ function check(options, topology) {
500
522
  }
501
523
  const checkMicroVerticalApiBoundaries = (options)=>check(options, true);
502
524
  const checkMicroVerticalApiConsumerFiles = (options)=>check(options, false);
503
- export { checkMicroVerticalApiBoundaries, checkMicroVerticalApiConsumerFiles, configuredMicroVerticalApiStem, microVerticalApiBaselineViolation };
525
+ export { checkMicroVerticalApiBoundaries, checkMicroVerticalApiConsumerFiles, configuredMicroVerticalApiStem, createModuleGraph, microVerticalApiBaselineViolation };
@@ -0,0 +1,260 @@
1
+ import node_fs from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import node_path from "node:path";
4
+ import { exports as external_resolve_exports_exports } from "resolve.exports";
5
+ import { SourceSyntaxError, parseSource, traverseSource } from "./source-analysis.js";
6
+ import * as __rspack_external__babel_types_6e8337dd from "@babel/types";
7
+ const MAX_MODULES = 256;
8
+ const MAX_LOOKUPS = 512;
9
+ function parseConsumer(filePath) {
10
+ if (node_fs.statSync(filePath).size > 1000000) throw new Error(`${filePath}: consumer source exceeds 1 MB analysis budget`);
11
+ const file = parseSource(node_fs.readFileSync(filePath, 'utf8'), filePath);
12
+ traverseSource(file, {
13
+ AssignmentExpression (p) {
14
+ throw new SourceSyntaxError(`contract bindings must be immutable at ${p.node.start}`);
15
+ },
16
+ UpdateExpression (p) {
17
+ throw new SourceSyntaxError(`contract bindings must be immutable at ${p.node.start}`);
18
+ },
19
+ TSModuleDeclaration () {
20
+ throw new SourceSyntaxError('contract bindings must not be merged with namespaces');
21
+ }
22
+ });
23
+ return file;
24
+ }
25
+ const propertyName = (node)=>{
26
+ if (void 0 !== node && (__rspack_external__babel_types_6e8337dd.isIdentifier(node) || __rspack_external__babel_types_6e8337dd.isStringLiteral(node) || __rspack_external__babel_types_6e8337dd.isNumericLiteral(node))) return __rspack_external__babel_types_6e8337dd.isIdentifier(node) ? node.name : String(node.value);
27
+ };
28
+ const localConst = (sourceFile, name)=>{
29
+ for (const item of sourceFile.program.body){
30
+ const statement = __rspack_external__babel_types_6e8337dd.isExportNamedDeclaration(item) ? item.declaration : item;
31
+ if (!__rspack_external__babel_types_6e8337dd.isVariableDeclaration(statement) || 'const' !== statement.kind) continue;
32
+ const matches = statement.declarations.filter((declaration)=>__rspack_external__babel_types_6e8337dd.isIdentifier(declaration.id, {
33
+ name
34
+ }));
35
+ if (1 === matches.length) return matches[0];
36
+ }
37
+ };
38
+ const exportedConst = (sourceFile, name)=>{
39
+ for (const statement of sourceFile.program.body)if (__rspack_external__babel_types_6e8337dd.isExportNamedDeclaration(statement) && 'type' !== statement.exportKind) {
40
+ if (__rspack_external__babel_types_6e8337dd.isVariableDeclaration(statement.declaration) && 'const' === statement.declaration.kind) {
41
+ const declaration = statement.declaration.declarations.find((value)=>__rspack_external__babel_types_6e8337dd.isIdentifier(value.id, {
42
+ name
43
+ }));
44
+ if (declaration) return declaration;
45
+ }
46
+ if (!statement.source && statement.specifiers.some((value)=>__rspack_external__babel_types_6e8337dd.isExportSpecifier(value) && 'type' !== value.exportKind && __rspack_external__babel_types_6e8337dd.isIdentifier(value.local, {
47
+ name
48
+ }) && __rspack_external__babel_types_6e8337dd.isIdentifier(value.exported, {
49
+ name
50
+ }))) return localConst(sourceFile, name);
51
+ }
52
+ };
53
+ const inside = (file, boundary)=>file === boundary || file.startsWith(`${boundary}${node_path.sep}`);
54
+ const containingWorkspace = (file)=>{
55
+ for(let directory = node_path.dirname(file);; directory = node_path.dirname(directory)){
56
+ if (node_fs.existsSync(node_path.join(directory, 'pnpm-workspace.yaml'))) return node_fs.realpathSync(directory);
57
+ if (directory === node_path.dirname(directory)) return;
58
+ }
59
+ };
60
+ const sourceBoundary = (file, workspace)=>{
61
+ for(let directory = node_path.dirname(file);; directory = node_path.dirname(directory)){
62
+ if (node_fs.existsSync(node_path.join(directory, 'package.json')) && directory !== workspace) return node_fs.realpathSync(directory);
63
+ if (directory === workspace || directory === node_path.dirname(directory)) return node_fs.realpathSync(node_path.dirname(file));
64
+ }
65
+ };
66
+ const sourceFileAt = (target, boundary)=>{
67
+ const stem = target.replace(/\.(?:[cm]?[jt]sx?)$/u, '');
68
+ for (const candidate of [
69
+ `${stem}.ts`,
70
+ `${stem}.tsx`,
71
+ `${stem}.mts`,
72
+ `${stem}.cts`,
73
+ target,
74
+ node_path.join(target, 'index.ts'),
75
+ node_path.join(target, 'index.tsx')
76
+ ])try {
77
+ const real = node_fs.realpathSync(candidate);
78
+ if (inside(real, boundary) && node_fs.statSync(real).isFile()) return real;
79
+ } catch {}
80
+ };
81
+ const packageEntry = (specifier)=>{
82
+ if (specifier.startsWith('.') || specifier.startsWith('/') || specifier.startsWith('#')) return;
83
+ const parts = specifier.split('/');
84
+ const count = specifier.startsWith('@') ? 2 : 1;
85
+ if (parts.length < count || parts.slice(0, count).some((part)=>!part)) return;
86
+ return {
87
+ name: parts.slice(0, count).join('/'),
88
+ exportKey: parts.length === count ? '.' : `./${parts.slice(count).join('/')}`
89
+ };
90
+ };
91
+ const resolveModulePath = (module, specifier, workspace)=>{
92
+ if (/^\.\.?\//u.test(specifier)) {
93
+ const file = sourceFileAt(node_path.resolve(node_path.dirname(module.path), specifier), module.boundary);
94
+ return void 0 === file ? void 0 : {
95
+ kind: 'module',
96
+ path: file,
97
+ boundary: module.boundary
98
+ };
99
+ }
100
+ const entry = packageEntry(specifier);
101
+ if (!entry) return;
102
+ if (!workspace) return {
103
+ kind: 'external'
104
+ };
105
+ const paths = createRequire(module.path).resolve.paths(entry.name) ?? [];
106
+ for (const lookup of paths){
107
+ const directory = node_path.join(lookup, entry.name);
108
+ const manifest = node_path.join(directory, 'package.json');
109
+ if (!node_fs.existsSync(manifest)) continue;
110
+ const boundary = node_fs.realpathSync(directory);
111
+ if (!inside(boundary, workspace) || boundary.split(node_path.sep).includes('node_modules')) break;
112
+ const pkg = JSON.parse(node_fs.readFileSync(manifest, 'utf8'));
113
+ if (pkg.name !== entry.name || void 0 === pkg.exports) return;
114
+ let target;
115
+ try {
116
+ const targets = external_resolve_exports_exports(pkg, entry.exportKey, {
117
+ conditions: [
118
+ 'modern:source'
119
+ ]
120
+ });
121
+ target = Array.isArray(targets) ? targets[0] : void 0;
122
+ } catch {
123
+ return;
124
+ }
125
+ if (!target || !target.startsWith('./')) return;
126
+ const file = sourceFileAt(node_path.resolve(boundary, target), boundary);
127
+ return void 0 === file ? void 0 : {
128
+ kind: 'module',
129
+ path: file,
130
+ boundary
131
+ };
132
+ }
133
+ return {
134
+ kind: 'external'
135
+ };
136
+ };
137
+ const importedBinding = (module, name)=>{
138
+ for (const statement of module.file.program.body)if (__rspack_external__babel_types_6e8337dd.isImportDeclaration(statement) && 'type' !== statement.importKind) {
139
+ for (const specifier of statement.specifiers)if (__rspack_external__babel_types_6e8337dd.isIdentifier(specifier.local, {
140
+ name
141
+ })) {
142
+ if (__rspack_external__babel_types_6e8337dd.isImportSpecifier(specifier) && 'type' !== specifier.importKind) return {
143
+ imported: propertyName(specifier.imported) ?? name,
144
+ specifier: statement.source.value
145
+ };
146
+ if (__rspack_external__babel_types_6e8337dd.isImportDefaultSpecifier(specifier)) return {
147
+ imported: 'default',
148
+ specifier: statement.source.value
149
+ };
150
+ }
151
+ }
152
+ };
153
+ const reexportedBinding = (module, name)=>{
154
+ for (const statement of module.file.program.body){
155
+ if (!__rspack_external__babel_types_6e8337dd.isExportNamedDeclaration(statement) || 'type' === statement.exportKind) continue;
156
+ const specifier = statement.specifiers.find((value)=>__rspack_external__babel_types_6e8337dd.isExportSpecifier(value) && 'type' !== value.exportKind && propertyName(value.exported) === name);
157
+ if (void 0 !== specifier && __rspack_external__babel_types_6e8337dd.isExportSpecifier(specifier)) return {
158
+ local: __rspack_external__babel_types_6e8337dd.isIdentifier(specifier.local) ? specifier.local.name : specifier.local.value,
159
+ ...statement.source ? {
160
+ specifier: statement.source.value
161
+ } : {}
162
+ };
163
+ }
164
+ };
165
+ const defaultExport = (module)=>{
166
+ for (const statement of module.file.program.body){
167
+ if (!__rspack_external__babel_types_6e8337dd.isExportDefaultDeclaration(statement)) continue;
168
+ const declaration = statement.declaration;
169
+ if (__rspack_external__babel_types_6e8337dd.isIdentifier(declaration)) return declaration.name;
170
+ return __rspack_external__babel_types_6e8337dd.isExpression(declaration) ? declaration : void 0;
171
+ }
172
+ };
173
+ function createModuleGraph(filePath) {
174
+ const realPath = node_fs.realpathSync(filePath);
175
+ const workspace = containingWorkspace(realPath);
176
+ const root = {
177
+ file: parseConsumer(realPath),
178
+ path: realPath,
179
+ boundary: sourceBoundary(realPath, workspace)
180
+ };
181
+ const modules = new Map([
182
+ [
183
+ root.path,
184
+ root
185
+ ]
186
+ ]);
187
+ const readModule = (modulePath, boundary)=>{
188
+ if (modules.has(modulePath)) return modules.get(modulePath);
189
+ if (modules.size >= MAX_MODULES) return;
190
+ let module;
191
+ try {
192
+ module = {
193
+ file: parseConsumer(modulePath),
194
+ path: modulePath,
195
+ boundary
196
+ };
197
+ } catch {
198
+ module = void 0;
199
+ }
200
+ modules.set(modulePath, module);
201
+ return module;
202
+ };
203
+ const resolveBinding = (module, name, scope, chain, seen)=>{
204
+ const key = `${scope}:${module.path}#${name}`;
205
+ if (seen.has(key) || seen.size >= MAX_LOOKUPS) return;
206
+ seen.add(key);
207
+ const last = chain.at(-1);
208
+ const hops = last?.path === module.path && last.name === name ? chain : [
209
+ ...chain,
210
+ {
211
+ path: module.path,
212
+ name
213
+ }
214
+ ];
215
+ const declaration = 'export' === scope ? exportedConst(module.file, name) : localConst(module.file, name);
216
+ if (declaration?.init) return {
217
+ kind: 'declaration',
218
+ expression: declaration.init,
219
+ module,
220
+ chain: hops
221
+ };
222
+ const throughModule = (specifier, imported, allowExternal)=>{
223
+ const target = resolveModulePath(module, specifier, workspace);
224
+ if (target?.kind === 'external') return allowExternal ? {
225
+ kind: 'external',
226
+ specifier,
227
+ name: imported,
228
+ chain: hops
229
+ } : void 0;
230
+ const next = target && readModule(target.path, target.boundary);
231
+ return void 0 === next ? void 0 : resolveBinding(next, imported, 'export', hops, seen);
232
+ };
233
+ if ('local' === scope) {
234
+ const imported = importedBinding(module, name);
235
+ return void 0 === imported ? void 0 : throughModule(imported.specifier, imported.imported, true);
236
+ }
237
+ if ('default' === name) {
238
+ const exported = defaultExport(module);
239
+ if ('string' == typeof exported) return resolveBinding(module, exported, 'local', hops, seen);
240
+ return void 0 === exported ? void 0 : {
241
+ kind: 'declaration',
242
+ expression: exported,
243
+ module,
244
+ chain: hops
245
+ };
246
+ }
247
+ const reexported = reexportedBinding(module, name);
248
+ if (void 0 !== reexported) return void 0 === reexported.specifier ? resolveBinding(module, reexported.local, 'local', hops, seen) : throughModule(reexported.specifier, reexported.local, true);
249
+ for (const statement of module.file.program.body){
250
+ if (!__rspack_external__babel_types_6e8337dd.isExportAllDeclaration(statement) || 'type' === statement.exportKind) continue;
251
+ const resolved = throughModule(statement.source.value, name, false);
252
+ if (void 0 !== resolved) return resolved;
253
+ }
254
+ };
255
+ return {
256
+ root,
257
+ resolve: (module, name, scope)=>resolveBinding(module, name, scope, [], new Set())
258
+ };
259
+ }
260
+ export { createModuleGraph, exportedConst, localConst, parseConsumer, propertyName };