@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.
- package/dist/cjs/microvertical-api-baseline.cjs +8 -2
- package/dist/cjs/microvertical-api-boundary.cjs +397 -32
- package/dist/cjs/module-graph.cjs +44 -2
- package/dist/cjs/strict-effect-runtime.cjs +59 -6
- package/dist/esm/microvertical-api-baseline.js +1 -1
- package/dist/esm/microvertical-api-boundary.js +399 -34
- package/dist/esm/module-graph.js +44 -2
- package/dist/esm/strict-effect-runtime.js +59 -6
- package/dist/esm-node/microvertical-api-baseline.js +1 -1
- package/dist/esm-node/microvertical-api-boundary.js +399 -34
- package/dist/esm-node/module-graph.js +44 -2
- package/dist/esm-node/strict-effect-runtime.js +59 -6
- package/dist/types/microvertical-api-baseline.d.ts +4 -0
- package/dist/types/microvertical-api-boundary.d.ts +3 -2
- package/dist/types/module-graph.d.ts +8 -0
- package/package.json +6 -6
|
@@ -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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
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.
|
|
76
|
-
"@babel/traverse": "^8.0.
|
|
75
|
+
"@babel/parser": "^8.0.7",
|
|
76
|
+
"@babel/traverse": "^8.0.7",
|
|
77
77
|
"@babel/types": "^8.0.6",
|
|
78
|
-
"oxlint": "1.
|
|
79
|
-
"resolve.exports": "2.0.
|
|
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.
|
|
84
|
+
"@types/node": "^26.6.5"
|
|
85
85
|
},
|
|
86
86
|
"sideEffects": false,
|
|
87
87
|
"publishConfig": {
|