@bleedingdev/modern-js-code-tools 3.9.3-ultramodern.1 → 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.
@@ -8,6 +8,19 @@ const nodeRuntime = '@modern-js/bff-effect/effect';
8
8
  const assembly = '@modern-js/bff-effect/assembly';
9
9
  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.';
10
10
  const MAX_API_SOURCE_MODULES = 256;
11
+ const httpRouteMethods = new Set([
12
+ '*',
13
+ 'GET',
14
+ 'POST',
15
+ 'PUT',
16
+ 'PATCH',
17
+ 'DELETE',
18
+ 'HEAD',
19
+ 'OPTIONS',
20
+ 'TRACE',
21
+ 'CONNECT',
22
+ 'QUERY'
23
+ ]);
11
24
  function createEffectApiImportResolver(filename) {
12
25
  const directory = node_fs.realpathSync(node_path.dirname(filename));
13
26
  const owner = node_fs.realpathSync(node_path.resolve(directory, '..'));
@@ -55,9 +68,12 @@ function strictEffectRuntimeTopologyViolation(source, resolveImport) {
55
68
  })) {
56
69
  let target = nodePath.isAssignmentExpression() ? nodePath.node.left : nodePath.node.argument;
57
70
  while(__rspack_external__babel_types_6e8337dd.isMemberExpression(target))target = target.object;
58
- if (__rspack_external__babel_types_6e8337dd.isIdentifier(target)) {
59
- const binding = nodePath.scope.getBinding(target.name);
60
- if (binding) mutated.add(binding);
71
+ let binding = __rspack_external__babel_types_6e8337dd.isIdentifier(target) ? nodePath.scope.getBinding(target.name) : void 0;
72
+ while(binding && !mutated.has(binding)){
73
+ mutated.add(binding);
74
+ const declarator = binding.path.node;
75
+ const alias = 'const' === binding.kind && __rspack_external__babel_types_6e8337dd.isVariableDeclarator(declarator) && declarator.init ? unwrapExpression(declarator.init, true) : void 0;
76
+ binding = __rspack_external__babel_types_6e8337dd.isIdentifier(alias) ? binding.path.scope.getBinding(alias.name) : void 0;
61
77
  }
62
78
  }
63
79
  if (nodePath.isTSModuleDeclaration() && __rspack_external__babel_types_6e8337dd.isIdentifier(nodePath.node.id)) {
@@ -232,11 +248,48 @@ function strictEffectRuntimeTopologyViolation(source, resolveImport) {
232
248
  if (method(node.callee, 'Layer', 'mergeAll', layerSources)) return node.arguments.length > 0 && node.arguments.every((argument)=>handlers(argument, api));
233
249
  return method(node.callee, 'HttpApiBuilder', 'group') && 3 === node.arguments.length && apiIdentity(node.arguments[0]) === api && handled(node.arguments[2]);
234
250
  });
235
- const transport = (node)=>guarded(node, (node)=>{
251
+ const effectSources = [
252
+ edge,
253
+ 'effect',
254
+ 'effect/Effect'
255
+ ];
256
+ const routeHandler = (node)=>{
257
+ node = unwrap(node);
258
+ if (!__rspack_external__babel_types_6e8337dd.isCallExpression(node) || !method(node.callee, 'HttpRouter', 'add') || 3 !== node.arguments.length) return;
259
+ const [verb, route, handler] = node.arguments;
260
+ return __rspack_external__babel_types_6e8337dd.isStringLiteral(verb) && httpRouteMethods.has(verb.value) && __rspack_external__babel_types_6e8337dd.isStringLiteral(route) && (route.value.startsWith('/') || '*' === route.value) && (__rspack_external__babel_types_6e8337dd.isArrowFunctionExpression(handler) || __rspack_external__babel_types_6e8337dd.isFunctionExpression(handler)) ? handler : void 0;
261
+ };
262
+ const effectReference = (node)=>guarded(node, (node)=>{
236
263
  const init = initialized(node);
237
- if (init) return transport(init);
264
+ if (init) return __rspack_external__babel_types_6e8337dd.isIdentifier(unwrap(init)) && effectReference(init);
265
+ const value = imported(node);
266
+ return !!value && !value.namespace;
267
+ });
268
+ const capturedRouteFactory = (node)=>guarded(node, (node)=>{
269
+ const init = initialized(node) ?? externalValue(node);
270
+ if (init) return capturedRouteFactory(init);
271
+ if (!__rspack_external__babel_types_6e8337dd.isArrowFunctionExpression(node) || node.async || 1 !== node.params.length || !__rspack_external__babel_types_6e8337dd.isIdentifier(node.params[0]) || __rspack_external__babel_types_6e8337dd.isBlockStatement(node.body)) return false;
272
+ const handler = routeHandler(node.body);
273
+ const parameter = binding(node.params[0]);
274
+ return !!handler && !!parameter && parameter.referencePaths.some((reference)=>!!reference.findParent((path)=>path.node === handler));
275
+ });
276
+ const capturedTransport = (node)=>guarded(node, (node)=>{
277
+ const init = initialized(node);
278
+ if (init) return capturedTransport(init);
279
+ if (!__rspack_external__babel_types_6e8337dd.isCallExpression(node)) return false;
280
+ if (method(node.callee, 'Effect', 'map', effectSources)) return 2 === node.arguments.length && effectReference(node.arguments[0]) && capturedRouteFactory(node.arguments[1]);
281
+ if (!__rspack_external__babel_types_6e8337dd.isMemberExpression(node.callee) || node.callee.computed || !__rspack_external__babel_types_6e8337dd.isIdentifier(node.callee.property, {
282
+ name: 'pipe'
283
+ }) || 1 !== node.arguments.length || !effectReference(node.callee.object)) return false;
284
+ const map = unwrap(node.arguments[0]);
285
+ return __rspack_external__babel_types_6e8337dd.isCallExpression(map) && method(map.callee, 'Effect', 'map', effectSources) && 1 === map.arguments.length && capturedRouteFactory(map.arguments[0]);
286
+ });
287
+ const transport = (node, provided = false)=>guarded(node, (node)=>{
288
+ const init = initialized(node) ?? externalValue(node);
289
+ if (init) return transport(init, provided);
238
290
  if (!__rspack_external__babel_types_6e8337dd.isCallExpression(node)) return method(node, 'Layer', 'empty', layerSources);
239
- return pipe(node, transport) || method(node.callee, 'HttpRouter', 'cors') || method(node.callee, 'Layer', 'mergeAll', layerSources) && node.arguments.length > 0 && node.arguments.every(transport);
291
+ const providedHere = provided || node.arguments.some((argument)=>__rspack_external__babel_types_6e8337dd.isCallExpression(argument) && method(argument.callee, 'Layer', 'provide', layerSources) && 1 === argument.arguments.length);
292
+ return pipe(node, (value)=>transport(value, providedHere)) || void 0 !== routeHandler(node) || provided && method(node.callee, 'Layer', 'unwrap', layerSources) && 1 === node.arguments.length && capturedTransport(node.arguments[0]) || method(node.callee, 'HttpRouter', 'cors') || method(node.callee, 'Layer', 'mergeAll', layerSources) && node.arguments.length > 0 && node.arguments.every((argument)=>transport(argument, provided));
240
293
  });
241
294
  const directLayer = (node, api)=>guarded(node, (node)=>{
242
295
  const init = initialized(node);
@@ -1,3 +1,7 @@
1
+ /** `order-items` -> `orderItems`: the stem as contract export names spell it. */
2
+ export declare const camelCaseStem: (stem: string) => string;
3
+ /** `order-items` -> `OrderItems`. */
4
+ export declare const pascalCaseStem: (stem: string) => string;
1
5
  export interface MicroVerticalApiBaselineExpectation {
2
6
  /** Optional override for operation IDs outside reachable endpoint naming conventions. */
3
7
  readonly operationPaths?: Readonly<Record<string, string>>;
@@ -6,7 +6,8 @@ export { createModuleGraph } from './module-graph.js';
6
6
  export interface MicroVerticalConfiguredApp {
7
7
  readonly path: string;
8
8
  readonly id?: string;
9
- readonly kind?: string;
9
+ /** `shell` or `vertical`; selects the rules the app is checked against. */
10
+ readonly kind: string;
10
11
  readonly package?: string;
11
12
  readonly surfaceProfile?: string;
12
13
  readonly deliveryUnitKind?: string;
@@ -22,7 +23,7 @@ export interface MicroVerticalApiSourceRuleContext {
22
23
  /** Workspace-relative path of `module`. */
23
24
  readonly file: string;
24
25
  readonly module: SourceModule;
25
- /** One graph per check, shared by every rule and source file. */
26
+ /** One graph per source file, shared by every rule for that file. */
26
27
  readonly graph: ModuleGraph;
27
28
  }
28
29
  /** A consumer-owned source rule; each returned message is a violation. */
@@ -67,6 +67,14 @@ export interface ModuleGraph {
67
67
  * over-budget bindings return undefined so callers fail closed.
68
68
  */
69
69
  resolve(module: SourceModule, name: string, scope: 'export' | 'local'): ResolvedBinding | undefined;
70
+ /**
71
+ * `resolve` for one lexical occurrence: an identifier `module` references
72
+ * or declares, or `namespace.member` on a namespace import. The binding is
73
+ * the one in scope at that node, not the module-scope name.
74
+ */
75
+ resolveReference(module: SourceModule, reference: t.Node): ResolvedBinding | undefined;
76
+ /** True only for an identifier `module` references that has no binding (a global). */
77
+ isUnboundReference(module: SourceModule, reference: t.Node): boolean;
70
78
  /**
71
79
  * Every value `expression` (a node of `module`) can evaluate to, following
72
80
  * any binding kind, destructuring, member access into object literals,
package/package.json CHANGED
@@ -23,7 +23,7 @@
23
23
  "engines": {
24
24
  "node": ">=20"
25
25
  },
26
- "version": "3.9.3-ultramodern.1",
26
+ "version": "3.9.3-ultramodern.10",
27
27
  "types": "./dist/types/index.d.ts",
28
28
  "main": "./dist/esm-node/index.js",
29
29
  "typesVersions": {
@@ -72,16 +72,16 @@
72
72
  "bin"
73
73
  ],
74
74
  "dependencies": {
75
- "@babel/parser": "^8.0.6",
76
- "@babel/traverse": "^8.0.6",
75
+ "@babel/parser": "^8.0.7",
76
+ "@babel/traverse": "^8.0.7",
77
77
  "@babel/types": "^8.0.6",
78
- "oxlint": "1.86.0",
79
- "resolve.exports": "2.0.3"
78
+ "oxlint": "1.88.0",
79
+ "resolve.exports": "2.0.4"
80
80
  },
81
81
  "devDependencies": {
82
82
  "@rslib/core": "1.0.3",
83
83
  "@scripts/rstest-config": "2.66.0",
84
- "@types/node": "^26.6.3"
84
+ "@types/node": "^26.6.5"
85
85
  },
86
86
  "sideEffects": false,
87
87
  "publishConfig": {