@bleedingdev/modern-js-code-tools 3.9.0-ultramodern.9 → 3.9.3-ultramodern.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/bin/modern-api-check-files.mjs +4 -1
  2. package/bin/modern-api-check.mjs +1 -1
  3. package/bin/modern-i18n-check.mjs +4 -0
  4. package/dist/cjs/cli/microvertical-api-check.cjs +36 -7
  5. package/dist/cjs/cli/workspace-source-check.cjs +90 -17
  6. package/dist/cjs/microvertical-api-baseline.cjs +89 -246
  7. package/dist/cjs/microvertical-api-boundary.cjs +507 -64
  8. package/dist/cjs/microvertical-api-owner.cjs +5 -2
  9. package/dist/cjs/module-graph.cjs +1862 -0
  10. package/dist/cjs/oxlint-plugin/rules/strict-effect-api-boundaries.cjs +1 -1
  11. package/dist/cjs/source-analysis.cjs +108 -0
  12. package/dist/cjs/strict-effect-runtime.cjs +75 -57
  13. package/dist/esm/cli/microvertical-api-check.js +26 -7
  14. package/dist/esm/cli/workspace-source-check.js +86 -13
  15. package/dist/esm/microvertical-api-baseline.js +66 -214
  16. package/dist/esm/microvertical-api-boundary.js +505 -65
  17. package/dist/esm/microvertical-api-owner.js +5 -2
  18. package/dist/esm/module-graph.js +1804 -0
  19. package/dist/esm/oxlint-plugin/rules/strict-effect-api-boundaries.js +1 -1
  20. package/dist/esm/source-analysis.js +48 -0
  21. package/dist/esm/strict-effect-runtime.js +75 -56
  22. package/dist/esm-node/cli/microvertical-api-check.js +26 -7
  23. package/dist/esm-node/cli/workspace-source-check.js +86 -13
  24. package/dist/esm-node/microvertical-api-baseline.js +66 -214
  25. package/dist/esm-node/microvertical-api-boundary.js +505 -65
  26. package/dist/esm-node/microvertical-api-owner.js +5 -2
  27. package/dist/esm-node/module-graph.js +1805 -0
  28. package/dist/esm-node/oxlint-plugin/rules/strict-effect-api-boundaries.js +1 -1
  29. package/dist/esm-node/source-analysis.js +49 -0
  30. package/dist/esm-node/strict-effect-runtime.js +75 -56
  31. package/dist/types/cli/microvertical-api-check.d.ts +1 -1
  32. package/dist/types/cli/workspace-source-check.d.ts +1 -1
  33. package/dist/types/microvertical-api-baseline.d.ts +4 -5
  34. package/dist/types/microvertical-api-boundary.d.ts +17 -2
  35. package/dist/types/microvertical-api-owner.d.ts +1 -1
  36. package/dist/types/module-graph.d.ts +100 -0
  37. package/dist/types/source-analysis.d.ts +13 -0
  38. package/package.json +17 -13
@@ -1,14 +1,5 @@
1
1
  "use strict";
2
2
  var __webpack_require__ = {};
3
- (()=>{
4
- __webpack_require__.n = (module)=>{
5
- var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
- __webpack_require__.d(getter, {
7
- a: getter
8
- });
9
- return getter;
10
- };
11
- })();
12
3
  (()=>{
13
4
  __webpack_require__.d = (exports1, getters, values)=>{
14
5
  var define = (defs, kind)=>{
@@ -37,75 +28,21 @@ var __webpack_require__ = {};
37
28
  var __webpack_exports__ = {};
38
29
  __webpack_require__.r(__webpack_exports__);
39
30
  __webpack_require__.d(__webpack_exports__, {
31
+ camelCaseStem: ()=>camelCaseStem,
40
32
  configuredMicroVerticalApiStem: ()=>configuredMicroVerticalApiStem,
41
- consumerParserPlugins: ()=>consumerParserPlugins,
42
- microVerticalApiBaselineViolation: ()=>microVerticalApiBaselineViolation
33
+ microVerticalApiBaselineViolation: ()=>microVerticalApiBaselineViolation,
34
+ pascalCaseStem: ()=>pascalCaseStem
43
35
  });
44
- const external_node_fs_namespaceObject = require("node:fs");
45
- var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
46
- const external_node_path_namespaceObject = require("node:path");
47
- var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
48
- const parser_namespaceObject = require("@babel/parser");
49
- const traverse_namespaceObject = require("@babel/traverse");
50
- var traverse_default = /*#__PURE__*/ __webpack_require__.n(traverse_namespaceObject);
51
36
  const types_namespaceObject = require("@babel/types");
52
37
  const external_microvertical_api_owner_cjs_namespaceObject = require("./microvertical-api-owner.cjs");
53
- const consumerParserPlugins = (filePath)=>filePath.endsWith('.tsx') || filePath.endsWith('.jsx') ? [
54
- "typescript",
55
- 'jsx'
56
- ] : [
57
- "typescript"
58
- ];
59
- class ConsumerSyntaxError extends Error {
60
- }
61
- class ConsumerValidationHub extends traverse_namespaceObject.Hub {
62
- buildError(_node, message) {
63
- return new ConsumerSyntaxError(message);
64
- }
65
- }
66
- function parseConsumer(filePath) {
67
- if (external_node_fs_default().statSync(filePath).size > 1000000) throw new Error(`${filePath}: consumer source exceeds 1 MB analysis budget`);
68
- let file;
69
- try {
70
- file = (0, parser_namespaceObject.parse)(external_node_fs_default().readFileSync(filePath, 'utf8'), {
71
- sourceType: 'module',
72
- sourceFilename: filePath,
73
- plugins: consumerParserPlugins(filePath)
74
- });
75
- } catch (error) {
76
- if ('object' == typeof error && null !== error && 'code' in error && 'BABEL_PARSER_SYNTAX_ERROR' === error.code) throw new ConsumerSyntaxError(error instanceof Error ? error.message : String(error));
77
- throw error;
78
- }
79
- const program = traverse_namespaceObject.NodePath.get({
80
- hub: new ConsumerValidationHub(),
81
- parentPath: void 0,
82
- parent: file,
83
- container: file,
84
- key: 'program'
85
- });
86
- program.setContext();
87
- traverse_default()(file, {
88
- AssignmentExpression (p) {
89
- throw new ConsumerSyntaxError(`contract bindings must be immutable at ${p.node.start}`);
90
- },
91
- UpdateExpression (p) {
92
- throw new ConsumerSyntaxError(`contract bindings must be immutable at ${p.node.start}`);
93
- },
94
- TSModuleDeclaration () {
95
- throw new ConsumerSyntaxError('contract bindings must not be merged with namespaces');
96
- }
97
- }, program.scope, void 0, program);
98
- return file;
99
- }
38
+ const external_module_graph_cjs_namespaceObject = require("./module-graph.cjs");
39
+ const external_source_analysis_cjs_namespaceObject = require("./source-analysis.cjs");
100
40
  const camelCaseStem = (stem)=>stem.replaceAll(/-([a-z0-9])/gu, (_match, letter)=>letter.toUpperCase());
101
41
  const pascalCaseStem = (stem)=>{
102
42
  const camelStem = camelCaseStem(stem);
103
43
  return `${camelStem.slice(0, 1).toUpperCase()}${camelStem.slice(1)}`;
104
44
  };
105
45
  const identifierName = (node)=>void 0 !== node && types_namespaceObject.isIdentifier(node) ? node.name : void 0;
106
- const propertyName = (node)=>{
107
- if (void 0 !== node && (types_namespaceObject.isIdentifier(node) || types_namespaceObject.isStringLiteral(node) || types_namespaceObject.isNumericLiteral(node))) return types_namespaceObject.isIdentifier(node) ? node.name : String(node.value);
108
- };
109
46
  const accessPath = (node)=>{
110
47
  if (types_namespaceObject.isIdentifier(node)) return [
111
48
  node.name
@@ -119,165 +56,31 @@ const accessPath = (node)=>{
119
56
  }
120
57
  };
121
58
  const isAccessPath = (node, expected)=>accessPath(node)?.join('.') === expected.join('.');
122
- const unwrapExpression = (expression)=>{
123
- let current = expression;
124
- while(types_namespaceObject.isTSAsExpression(current) || types_namespaceObject.isParenthesizedExpression(current) || types_namespaceObject.isTSSatisfiesExpression(current))current = current.expression;
125
- return current;
126
- };
127
59
  const stringLiteral = (expression)=>{
128
60
  if (null == expression) return;
129
- const unwrapped = unwrapExpression(expression);
61
+ const unwrapped = (0, external_source_analysis_cjs_namespaceObject.unwrapExpression)(expression);
130
62
  return types_namespaceObject.isStringLiteral(unwrapped) ? unwrapped.value : void 0;
131
63
  };
132
64
  const numericLiteral = (expression)=>{
133
65
  if (null == expression) return;
134
- const unwrapped = unwrapExpression(expression);
66
+ const unwrapped = (0, external_source_analysis_cjs_namespaceObject.unwrapExpression)(expression);
135
67
  return types_namespaceObject.isNumericLiteral(unwrapped) ? Number(unwrapped.value) : void 0;
136
68
  };
137
69
  const callExpression = (expression, callee)=>{
138
70
  if (null == expression) return;
139
- const unwrapped = unwrapExpression(expression);
71
+ const unwrapped = (0, external_source_analysis_cjs_namespaceObject.unwrapExpression)(expression);
140
72
  return types_namespaceObject.isCallExpression(unwrapped) && isAccessPath(unwrapped.callee, callee) ? unwrapped : void 0;
141
73
  };
142
- const localConst = (sourceFile, name)=>{
143
- for (const item of sourceFile.program.body){
144
- const statement = types_namespaceObject.isExportNamedDeclaration(item) ? item.declaration : item;
145
- if (!types_namespaceObject.isVariableDeclaration(statement) || 'const' !== statement.kind) continue;
146
- const matches = statement.declarations.filter((declaration)=>types_namespaceObject.isIdentifier(declaration.id, {
147
- name
148
- }));
149
- if (1 === matches.length) return matches[0];
150
- }
151
- };
152
- const exportedConst = (sourceFile, name)=>{
153
- for (const statement of sourceFile.program.body)if (types_namespaceObject.isExportNamedDeclaration(statement) && 'type' !== statement.exportKind) {
154
- if (types_namespaceObject.isVariableDeclaration(statement.declaration) && 'const' === statement.declaration.kind) {
155
- const declaration = statement.declaration.declarations.find((value)=>types_namespaceObject.isIdentifier(value.id, {
156
- name
157
- }));
158
- if (declaration) return declaration;
159
- }
160
- if (!statement.source && statement.specifiers.some((value)=>types_namespaceObject.isExportSpecifier(value) && 'type' !== value.exportKind && types_namespaceObject.isIdentifier(value.local, {
161
- name
162
- }) && types_namespaceObject.isIdentifier(value.exported, {
163
- name
164
- }))) return localConst(sourceFile, name);
165
- }
166
- };
167
- const resolveRelativeModulePath = (fromPath, specifier)=>{
168
- if (!/^\.\.?\//u.test(specifier)) return;
169
- const resolved = external_node_path_default().resolve(external_node_path_default().dirname(fromPath), specifier);
170
- const stem = resolved.replace(/\.(?:[cm]?[jt]sx?)$/u, '');
171
- for (const candidate of [
172
- `${stem}.ts`,
173
- `${stem}.tsx`,
174
- external_node_path_default().join(stem, 'index.ts'),
175
- external_node_path_default().join(stem, 'index.tsx')
176
- ])if (external_node_fs_default().existsSync(candidate) && external_node_fs_default().statSync(candidate).isFile()) return candidate;
177
- };
178
- const createModuleReader = (root)=>{
179
- const modules = new Map([
180
- [
181
- root.path,
182
- root
183
- ]
184
- ]);
185
- return (filePath)=>{
186
- if (modules.has(filePath)) return modules.get(filePath);
187
- if (modules.size >= 256) return;
188
- let module;
189
- try {
190
- module = {
191
- file: parseConsumer(filePath),
192
- path: filePath
193
- };
194
- } catch {
195
- module = void 0;
196
- }
197
- modules.set(filePath, module);
198
- return module;
199
- };
200
- };
201
- const importedBinding = (module, name)=>{
202
- for (const statement of module.file.program.body)if (types_namespaceObject.isImportDeclaration(statement) && 'type' !== statement.importKind) {
203
- for (const specifier of statement.specifiers)if (types_namespaceObject.isIdentifier(specifier.local, {
204
- name
205
- })) {
206
- if (types_namespaceObject.isImportSpecifier(specifier) && 'type' !== specifier.importKind) return {
207
- imported: propertyName(specifier.imported) ?? name,
208
- specifier: statement.source.value
209
- };
210
- if (types_namespaceObject.isImportDefaultSpecifier(specifier)) return {
211
- imported: 'default',
212
- specifier: statement.source.value
213
- };
214
- }
215
- }
216
- };
217
- const reexportedBinding = (module, name)=>{
218
- for (const statement of module.file.program.body){
219
- if (!types_namespaceObject.isExportNamedDeclaration(statement) || 'type' === statement.exportKind) continue;
220
- const specifier = statement.specifiers.find((value)=>types_namespaceObject.isExportSpecifier(value) && 'type' !== value.exportKind && propertyName(value.exported) === name);
221
- if (void 0 !== specifier && types_namespaceObject.isExportSpecifier(specifier)) return {
222
- local: specifier.local.name,
223
- ...statement.source ? {
224
- specifier: statement.source.value
225
- } : {}
226
- };
227
- }
228
- };
229
- const defaultExport = (module)=>{
230
- for (const statement of module.file.program.body){
231
- if (!types_namespaceObject.isExportDefaultDeclaration(statement)) continue;
232
- const declaration = statement.declaration;
233
- if (types_namespaceObject.isIdentifier(declaration)) return declaration.name;
234
- return types_namespaceObject.isExpression(declaration) ? declaration : void 0;
235
- }
236
- };
237
- const resolveBinding = (module, name, scope, readModule, seen)=>{
238
- const key = `${scope}:${module.path}#${name}`;
239
- if (seen.has(key) || seen.size >= 512) return;
240
- seen.add(key);
241
- const declaration = 'export' === scope ? exportedConst(module.file, name) : localConst(module.file, name);
242
- if (declaration?.init) return {
243
- expression: declaration.init,
244
- module
245
- };
246
- const throughModule = (specifier, imported)=>{
247
- const resolvedPath = resolveRelativeModulePath(module.path, specifier);
248
- const target = void 0 === resolvedPath ? void 0 : readModule(resolvedPath);
249
- return void 0 === target ? void 0 : resolveBinding(target, imported, 'export', readModule, seen);
250
- };
251
- if ('local' === scope) {
252
- const imported = importedBinding(module, name);
253
- return void 0 === imported ? void 0 : throughModule(imported.specifier, imported.imported);
254
- }
255
- if ('default' === name) {
256
- const exported = defaultExport(module);
257
- if ('string' == typeof exported) return resolveBinding(module, exported, 'local', readModule, seen);
258
- return void 0 === exported ? void 0 : {
259
- expression: exported,
260
- module
261
- };
262
- }
263
- const reexported = reexportedBinding(module, name);
264
- if (void 0 !== reexported) return void 0 === reexported.specifier ? resolveBinding(module, reexported.local, 'local', readModule, seen) : throughModule(reexported.specifier, reexported.local);
265
- for (const statement of module.file.program.body){
266
- if (!types_namespaceObject.isExportAllDeclaration(statement) || 'type' === statement.exportKind) continue;
267
- const resolved = throughModule(statement.source.value, name);
268
- if (void 0 !== resolved) return resolved;
269
- }
270
- };
271
74
  const objectLiteral = (expression)=>{
272
75
  if (null == expression) return;
273
- const unwrapped = unwrapExpression(expression);
76
+ const unwrapped = (0, external_source_analysis_cjs_namespaceObject.unwrapExpression)(expression);
274
77
  return types_namespaceObject.isObjectExpression(unwrapped) ? unwrapped : void 0;
275
78
  };
276
79
  const propertyAssignments = (properties)=>{
277
80
  const assignments = new Map();
278
81
  for (const property of properties){
279
82
  if (!types_namespaceObject.isObjectProperty(property) || property.computed || property.shorthand) return;
280
- const name = propertyName(property.key);
83
+ const name = (0, external_module_graph_cjs_namespaceObject.propertyName)(property.key);
281
84
  if (void 0 === name || assignments.has(name)) return;
282
85
  assignments.set(name, property);
283
86
  }
@@ -289,7 +92,7 @@ const exactCall = (expression, callee, argumentCount)=>{
289
92
  };
290
93
  const sharedSchemaObject = (declaration, sharedSchemaName, protectedFields)=>{
291
94
  if (declaration?.init == null) return;
292
- const initializer = unwrapExpression(declaration.init);
95
+ const initializer = (0, external_source_analysis_cjs_namespaceObject.unwrapExpression)(declaration.init);
293
96
  if (types_namespaceObject.isIdentifier(initializer) && initializer.name === sharedSchemaName) return {
294
97
  assignments: new Map(),
295
98
  identity: true
@@ -313,14 +116,14 @@ const sharedSchemaObject = (declaration, sharedSchemaName, protectedFields)=>{
313
116
  };
314
117
  const directCallChain = (expression)=>{
315
118
  if (null == expression) return;
316
- let current = unwrapExpression(expression);
119
+ let current = (0, external_source_analysis_cjs_namespaceObject.unwrapExpression)(expression);
317
120
  const methods = [];
318
121
  while(types_namespaceObject.isCallExpression(current) && types_namespaceObject.isMemberExpression(current.callee) && !current.callee.computed && types_namespaceObject.isIdentifier(current.callee.property) && !types_namespaceObject.isIdentifier(current.callee.object)){
319
122
  methods.unshift({
320
123
  arguments: current.arguments,
321
124
  name: current.callee.property.name
322
125
  });
323
- current = unwrapExpression(current.callee.object);
126
+ current = (0, external_source_analysis_cjs_namespaceObject.unwrapExpression)(current.callee.object);
324
127
  }
325
128
  if (!types_namespaceObject.isCallExpression(current)) return;
326
129
  return {
@@ -331,7 +134,7 @@ const directCallChain = (expression)=>{
331
134
  const brandedStringSchemaIsExact = (declaration, brand)=>{
332
135
  const initializer = declaration?.init;
333
136
  if (null == initializer) return false;
334
- const pipeCall = unwrapExpression(initializer);
137
+ const pipeCall = (0, external_source_analysis_cjs_namespaceObject.unwrapExpression)(initializer);
335
138
  if (!types_namespaceObject.isCallExpression(pipeCall) || !types_namespaceObject.isMemberExpression(pipeCall.callee) || pipeCall.callee.computed || !types_namespaceObject.isIdentifier(pipeCall.callee.property, {
336
139
  name: 'pipe'
337
140
  }) || !isAccessPath(pipeCall.callee.object, [
@@ -367,14 +170,21 @@ const singleAddedArgument = (expression, factory, names)=>{
367
170
  if (1 !== chain.base.arguments.length || !names.includes(stringLiteral(chain.base.arguments[0]) ?? '') || 1 !== chain.methods.length || method?.name !== 'add' || 1 !== method.arguments.length) return;
368
171
  return method.arguments[0];
369
172
  };
370
- const foundationIsExact = (declaration, stem, readinessSchemaName)=>{
371
- const group = singleAddedArgument(declaration?.init, [
173
+ const rootGroupExpression = (graph, expression)=>{
174
+ if (void 0 === expression) return;
175
+ const node = (0, external_source_analysis_cjs_namespaceObject.unwrapExpression)(expression);
176
+ if (!types_namespaceObject.isIdentifier(node)) return node;
177
+ const resolved = graph.resolve(graph.root, node.name, 'local');
178
+ return resolved?.kind === 'declaration' && resolved.module === graph.root ? (0, external_source_analysis_cjs_namespaceObject.unwrapExpression)(resolved.expression) : void 0;
179
+ };
180
+ const foundationGroup = (graph, declaration, stem, readinessSchemaName)=>{
181
+ const group = rootGroupExpression(graph, singleAddedArgument(declaration?.init, [
372
182
  'HttpApi',
373
183
  'make'
374
184
  ], [
375
185
  `${pascalCaseStem(stem)}FoundationApi`,
376
186
  `${pascalCaseStem(stem)}ApiFoundation`
377
- ]);
187
+ ]));
378
188
  const endpointExpression = singleAddedArgument(group, [
379
189
  'HttpApiGroup',
380
190
  'make'
@@ -387,17 +197,24 @@ const foundationIsExact = (declaration, stem, readinessSchemaName)=>{
387
197
  ], 3);
388
198
  const endpointOptions = objectLiteral(endpoint?.arguments[2]);
389
199
  const endpointProperties = void 0 === endpointOptions ? void 0 : propertyAssignments(endpointOptions.properties);
390
- return void 0 !== endpoint && 'readiness' === stringLiteral(endpoint.arguments[0]) && stringLiteral(endpoint.arguments[1]) === `/${stem}/readiness` && endpointProperties?.size === 1 && identifierName(endpointProperties.get('success')?.value) === readinessSchemaName;
200
+ return void 0 !== endpoint && 'readiness' === stringLiteral(endpoint.arguments[0]) && stringLiteral(endpoint.arguments[1]) === `/${stem}/readiness` && endpointProperties?.size === 1 && identifierName(endpointProperties.get('success')?.value) === readinessSchemaName ? group : void 0;
391
201
  };
392
- const rootComposesFoundation = (sourceFile, declaration, stem, foundationName)=>{
202
+ const rootComposesFoundation = (graph, declaration, stem, foundationName, foundation)=>{
203
+ const sourceFile = graph.root.file;
393
204
  const chain = directCallChain(declaration?.init);
394
205
  const first = chain?.methods[0];
206
+ const firstArgument = first?.arguments[0];
395
207
  return void 0 !== chain && isAccessPath(chain.base.callee, [
396
208
  'HttpApi',
397
209
  'make'
398
- ]) && 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', [
210
+ ]) && 1 === chain.base.arguments.length && stringLiteral(chain.base.arguments[0]) === `${pascalCaseStem(stem)}Api` && chain.methods.length > 0 && chain.methods.every((method, index)=>{
211
+ const combinatorArity = nonEndpointCombinators.api[method.name];
212
+ if (void 0 !== combinatorArity) return method.arguments.length === combinatorArity;
213
+ if ('add' === method.name) return method.arguments.length > 0;
214
+ return 1 === method.arguments.length && ('addHttpApi' === method.name || index === chain.methods.length - 1 && 'pipe' === method.name && 'identity' === identifierName(method.arguments[0]) && importsExactBindings(sourceFile, 'effect', [
399
215
  'identity'
400
- ]))) && first?.name === 'addHttpApi' && identifierName(first.arguments[0]) === foundationName;
216
+ ]));
217
+ }) && void 0 !== firstArgument && (first?.name === 'addHttpApi' && identifierName(firstArgument) === foundationName || first?.name === 'add' && types_namespaceObject.isIdentifier(firstArgument) && rootGroupExpression(graph, firstArgument) === foundation);
401
218
  };
402
219
  const nonEndpointCombinators = {
403
220
  api: {
@@ -413,8 +230,7 @@ const nonEndpointCombinators = {
413
230
  middleware: 1
414
231
  }
415
232
  };
416
- const reachableEndpoints = (rootModule, declaration)=>{
417
- const readModule = createModuleReader(rootModule);
233
+ const reachableEndpoints = (graph, declaration)=>{
418
234
  const active = new Set();
419
235
  const endpoints = [];
420
236
  const identities = new Set();
@@ -431,13 +247,13 @@ const reachableEndpoints = (rootModule, declaration)=>{
431
247
  let visits = 0;
432
248
  const visit = (expression, module, kind, group = '')=>{
433
249
  if (!expression) return false;
434
- const node = unwrapExpression(expression);
250
+ const node = (0, external_source_analysis_cjs_namespaceObject.unwrapExpression)(expression);
435
251
  if (active.has(node) || active.size >= 128 || ++visits > 2048) return false;
436
252
  active.add(node);
437
253
  try {
438
254
  if (types_namespaceObject.isIdentifier(node)) {
439
- const resolved = resolveBinding(module, node.name, 'local', readModule, new Set());
440
- return void 0 !== resolved && visit(resolved.expression, resolved.module, kind, group);
255
+ const resolved = graph.resolve(module, node.name, 'local');
256
+ return resolved?.kind === 'declaration' && visit(resolved.expression, resolved.module, kind, group);
441
257
  }
442
258
  if ('endpoint' === kind) {
443
259
  if (!types_namespaceObject.isCallExpression(node) || node.arguments.length < 2 || node.arguments.length > 3) return false;
@@ -481,18 +297,36 @@ const reachableEndpoints = (rootModule, declaration)=>{
481
297
  }
482
298
  const combinatorArity = combinators[method.name];
483
299
  if (void 0 !== combinatorArity) return method.arguments.length === combinatorArity;
300
+ if ('add' === method.name) return method.arguments.length > 0 && method.arguments.every((argument)=>visitAdded(argument, module, 'api' === kind ? 'group' : 'endpoint', 'group' === kind ? name : ''));
484
301
  if (1 !== method.arguments.length) return false;
485
302
  if ('pipe' === method.name) return 'identity' === identifierName(method.arguments[0]) && importsExactBindings(module.file, 'effect', [
486
303
  'identity'
487
304
  ]);
488
- if ('add' === method.name) return visit(method.arguments[0], module, 'api' === kind ? 'group' : 'endpoint', 'group' === kind ? name : '');
489
305
  return 'api' === kind && 'addHttpApi' === method.name && visit(method.arguments[0], module, 'api');
490
306
  });
491
307
  } finally{
492
308
  active.delete(node);
493
309
  }
494
310
  };
495
- return visit(declaration?.init, rootModule, 'api') ? endpoints : void 0;
311
+ const visitAdded = (argument, module, kind, group)=>{
312
+ if (!types_namespaceObject.isSpreadElement(argument)) return visit(argument, module, kind, group);
313
+ let node = (0, external_source_analysis_cjs_namespaceObject.unwrapExpression)(argument.argument);
314
+ let owner = module;
315
+ if (types_namespaceObject.isIdentifier(node)) {
316
+ const resolved = graph.resolve(module, node.name, 'local');
317
+ if (resolved?.kind !== 'declaration') return false;
318
+ node = (0, external_source_analysis_cjs_namespaceObject.unwrapExpression)(resolved.expression);
319
+ owner = resolved.module;
320
+ }
321
+ if (!types_namespaceObject.isArrayExpression(node) || active.has(node) || ++visits > 2048) return false;
322
+ active.add(node);
323
+ try {
324
+ return node.elements.every((element)=>null !== element && visitAdded(element, owner, kind, group));
325
+ } finally{
326
+ active.delete(node);
327
+ }
328
+ };
329
+ return visit(declaration?.init, graph.root, 'api') ? endpoints : void 0;
496
330
  };
497
331
  const operationContextFields = (property)=>{
498
332
  const constructorCall = exactCall(property.value, [
@@ -585,7 +419,7 @@ const markerSchemaIsShared = (sourceFile, declaration)=>{
585
419
  'version'
586
420
  ]);
587
421
  if (void 0 === schema || schema.identity) return schema?.identity === true;
588
- const brandedField = (property, brand)=>identifierName(property.value) === `${brand}Schema` && brandedStringSchemaIsExact(localConst(sourceFile, `${brand}Schema`), brand);
422
+ const brandedField = (property, brand)=>identifierName(property.value) === `${brand}Schema` && brandedStringSchemaIsExact((0, external_module_graph_cjs_namespaceObject.localConst)(sourceFile, `${brand}Schema`), brand);
589
423
  const validators = new Map([
590
424
  [
591
425
  'appId',
@@ -622,14 +456,14 @@ const readinessSchemaIsShared = (declaration, markerSchemaName, ownerMarkerIsIde
622
456
  ]);
623
457
  return void 0 !== schema && (schema.identity && ownerMarkerIsIdentity || 1 === schema.assignments.size && identifierName(schema.assignments.get('marker')?.value) === markerSchemaName);
624
458
  };
625
- const declarationIsIdentifier = (declaration, identifier)=>declaration?.init != null && identifierName(unwrapExpression(declaration.init)) === identifier;
626
- const validateParsedContract = (module, stem, expectation)=>{
627
- const sourceFile = module.file;
459
+ const declarationIsIdentifier = (declaration, identifier)=>declaration?.init != null && identifierName((0, external_source_analysis_cjs_namespaceObject.unwrapExpression)(declaration.init)) === identifier;
460
+ const validateParsedContract = (graph, stem, expectation)=>{
461
+ const sourceFile = graph.root.file;
628
462
  const exportStem = camelCaseStem(stem);
629
463
  const foundationName = `${exportStem}FoundationApi`;
630
464
  const markerSchemaName = `${exportStem}MarkerSchema`;
631
465
  const readinessSchemaName = `${exportStem}ReadinessSchema`;
632
- const markerDeclaration = exportedConst(sourceFile, markerSchemaName);
466
+ const markerDeclaration = (0, external_module_graph_cjs_namespaceObject.exportedConst)(sourceFile, markerSchemaName);
633
467
  if (!importsExactBindings(sourceFile, expectation.effectClientPackage, [
634
468
  'HttpApi',
635
469
  'HttpApiEndpoint',
@@ -638,13 +472,14 @@ const validateParsedContract = (module, stem, expectation)=>{
638
472
  ])) return 'MicroVertical root contract must import exact Effect API primitives from the framework client package';
639
473
  if (!importsSharedBaselinePrimitives(sourceFile, expectation.baselinePackage)) return 'MicroVertical root contract must import exact baseline primitives from the framework baseline package';
640
474
  if (!markerSchemaIsShared(sourceFile, markerDeclaration)) return 'MicroVertical root contract must consume the shared build marker schema without overriding shared fields';
641
- if (!readinessSchemaIsShared(exportedConst(sourceFile, readinessSchemaName), markerSchemaName, declarationIsIdentifier(markerDeclaration, 'MicroVerticalBuildMarkerSchema'))) return 'MicroVertical readiness schema must consume the shared readiness schema without overriding shared fields';
642
- if (!foundationIsExact(exportedConst(sourceFile, foundationName), stem, readinessSchemaName)) return 'MicroVertical readiness foundation API must directly compose its exact readiness endpoint and foundation identity';
643
- if (!rootComposesFoundation(sourceFile, exportedConst(sourceFile, `${exportStem}Api`), stem, foundationName)) return 'MicroVertical root API must explicitly compose its readiness foundation API';
644
- const endpoints = reachableEndpoints(module, exportedConst(sourceFile, `${exportStem}Api`));
475
+ if (!readinessSchemaIsShared((0, external_module_graph_cjs_namespaceObject.exportedConst)(sourceFile, readinessSchemaName), markerSchemaName, declarationIsIdentifier(markerDeclaration, 'MicroVerticalBuildMarkerSchema'))) return 'MicroVertical readiness schema must consume the shared readiness schema without overriding shared fields';
476
+ const foundation = foundationGroup(graph, (0, external_module_graph_cjs_namespaceObject.exportedConst)(sourceFile, foundationName), stem, readinessSchemaName);
477
+ if (void 0 === foundation) return 'MicroVertical readiness foundation API must directly compose its exact readiness endpoint and foundation identity';
478
+ if (!rootComposesFoundation(graph, (0, external_module_graph_cjs_namespaceObject.exportedConst)(sourceFile, `${exportStem}Api`), stem, foundationName, foundation)) return 'MicroVertical root API must explicitly compose its readiness foundation API';
479
+ const endpoints = reachableEndpoints(graph, (0, external_module_graph_cjs_namespaceObject.exportedConst)(sourceFile, `${exportStem}Api`));
645
480
  if (!endpoints) return 'MicroVertical root API must compose bounded native endpoint declarations without ambiguous identities';
646
- if (!operationMapIsConnected(exportedConst(sourceFile, `${exportStem}OperationContexts`), stem, expectation.operationPaths ?? {}, endpoints)) return 'MicroVertical operation map must construct every operation with the shared context constructor';
647
- if (!metadataIsExact(exportedConst(sourceFile, `${exportStem}ApiContract`), expectation, endpoints)) return 'MicroVertical root contract must keep exact owner and API path metadata without forbidden fields';
481
+ if (!operationMapIsConnected((0, external_module_graph_cjs_namespaceObject.exportedConst)(sourceFile, `${exportStem}OperationContexts`), stem, expectation.operationPaths ?? {}, endpoints)) return 'MicroVertical operation map must construct every operation with the shared context constructor';
482
+ if (!metadataIsExact((0, external_module_graph_cjs_namespaceObject.exportedConst)(sourceFile, `${exportStem}ApiContract`), expectation, endpoints)) return 'MicroVertical root contract must keep exact owner and API path metadata without forbidden fields';
648
483
  };
649
484
  const configuredMicroVerticalApiStem = (verticalPath, verticals)=>{
650
485
  const topologyVertical = verticals.find((vertical)=>(vertical.path ?? `verticals/${vertical.id}`) === verticalPath);
@@ -653,24 +488,32 @@ const configuredMicroVerticalApiStem = (verticalPath, verticals)=>{
653
488
  };
654
489
  const microVerticalApiBaselineViolation = (stem, filePath, expectation)=>{
655
490
  try {
656
- const sourceFile = parseConsumer(filePath);
657
- 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';
658
- return validateParsedContract({
659
- file: sourceFile,
660
- path: filePath
661
- }, stem, expectation);
491
+ const modules = (0, external_module_graph_cjs_namespaceObject.createModuleGraph)();
492
+ const graph = {
493
+ ...modules,
494
+ root: modules.module(filePath)
495
+ };
496
+ const [mutation] = graph.root.mutations;
497
+ if (mutation) return `MicroVertical root contract must be valid TypeScript syntax (contract bindings must be immutable at ${mutation.start})`;
498
+ let identityMismatch;
499
+ if (!(0, external_microvertical_api_owner_cjs_namespaceObject.baselinePublicIdentityIsExact)(filePath, expectation, (message)=>{
500
+ identityMismatch = message;
501
+ })) return `MicroVertical baseline imports must resolve the exact framework owner public export and schema identity${identityMismatch ? ` (${identityMismatch})` : ''}`;
502
+ return validateParsedContract(graph, stem, expectation);
662
503
  } catch (error) {
663
- if (error instanceof ConsumerSyntaxError) return `MicroVertical root contract must be valid TypeScript syntax (${error.message})`;
504
+ if (error instanceof external_source_analysis_cjs_namespaceObject.SourceSyntaxError) return `MicroVertical root contract must be valid TypeScript syntax (${error.message})`;
664
505
  throw error;
665
506
  }
666
507
  };
508
+ exports.camelCaseStem = __webpack_exports__.camelCaseStem;
667
509
  exports.configuredMicroVerticalApiStem = __webpack_exports__.configuredMicroVerticalApiStem;
668
- exports.consumerParserPlugins = __webpack_exports__.consumerParserPlugins;
669
510
  exports.microVerticalApiBaselineViolation = __webpack_exports__.microVerticalApiBaselineViolation;
511
+ exports.pascalCaseStem = __webpack_exports__.pascalCaseStem;
670
512
  for(var __rspack_i in __webpack_exports__)if (-1 === [
513
+ "camelCaseStem",
671
514
  "configuredMicroVerticalApiStem",
672
- "consumerParserPlugins",
673
- "microVerticalApiBaselineViolation"
515
+ "microVerticalApiBaselineViolation",
516
+ "pascalCaseStem"
674
517
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
675
518
  Object.defineProperty(exports, '__esModule', {
676
519
  value: true