@bleedingdev/modern-js-code-tools 3.9.0-ultramodern.2 → 3.9.0-ultramodern.21

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 (42) hide show
  1. package/bin/modern-api-check-files.mjs +7 -0
  2. package/bin/modern-api-check.mjs +4 -0
  3. package/bin/modern-i18n-check.mjs +4 -0
  4. package/dist/cjs/cli/microvertical-api-check.cjs +100 -0
  5. package/dist/cjs/cli/oxlint.cjs +9 -5
  6. package/dist/cjs/cli/workspace-source-check.cjs +90 -17
  7. package/dist/cjs/microvertical-api-baseline.cjs +505 -0
  8. package/dist/cjs/microvertical-api-boundary.cjs +586 -0
  9. package/dist/cjs/microvertical-api-owner.cjs +217 -0
  10. package/dist/cjs/module-graph.cjs +321 -0
  11. package/dist/cjs/oxlint-plugin/rules/strict-effect-api-boundaries.cjs +8 -6
  12. package/dist/cjs/source-analysis.cjs +104 -0
  13. package/dist/cjs/strict-effect-runtime.cjs +376 -0
  14. package/dist/esm/cli/microvertical-api-check.js +52 -0
  15. package/dist/esm/cli/oxlint.js +10 -6
  16. package/dist/esm/cli/workspace-source-check.js +86 -13
  17. package/dist/esm/microvertical-api-baseline.js +464 -0
  18. package/dist/esm/microvertical-api-boundary.js +525 -0
  19. package/dist/esm/microvertical-api-owner.js +162 -0
  20. package/dist/esm/module-graph.js +260 -0
  21. package/dist/esm/oxlint-plugin/rules/strict-effect-api-boundaries.js +8 -6
  22. package/dist/esm/source-analysis.js +44 -0
  23. package/dist/esm/strict-effect-runtime.js +324 -0
  24. package/dist/esm-node/cli/microvertical-api-check.js +53 -0
  25. package/dist/esm-node/cli/oxlint.js +10 -6
  26. package/dist/esm-node/cli/workspace-source-check.js +86 -13
  27. package/dist/esm-node/microvertical-api-baseline.js +465 -0
  28. package/dist/esm-node/microvertical-api-boundary.js +526 -0
  29. package/dist/esm-node/microvertical-api-owner.js +163 -0
  30. package/dist/esm-node/module-graph.js +261 -0
  31. package/dist/esm-node/oxlint-plugin/rules/strict-effect-api-boundaries.js +8 -6
  32. package/dist/esm-node/source-analysis.js +45 -0
  33. package/dist/esm-node/strict-effect-runtime.js +325 -0
  34. package/dist/types/cli/microvertical-api-check.d.ts +1 -0
  35. package/dist/types/cli/workspace-source-check.d.ts +1 -1
  36. package/dist/types/microvertical-api-baseline.d.ts +23 -0
  37. package/dist/types/microvertical-api-boundary.d.ts +46 -0
  38. package/dist/types/microvertical-api-owner.d.ts +6 -0
  39. package/dist/types/module-graph.d.ts +52 -0
  40. package/dist/types/source-analysis.d.ts +10 -0
  41. package/dist/types/strict-effect-runtime.d.ts +10 -0
  42. package/package.json +29 -6
@@ -0,0 +1,217 @@
1
+ "use strict";
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
+ (()=>{
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
22
+ };
23
+ })();
24
+ (()=>{
25
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
26
+ })();
27
+ (()=>{
28
+ __webpack_require__.r = (exports1)=>{
29
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
30
+ value: 'Module'
31
+ });
32
+ Object.defineProperty(exports1, '__esModule', {
33
+ value: true
34
+ });
35
+ };
36
+ })();
37
+ var __webpack_exports__ = {};
38
+ __webpack_require__.r(__webpack_exports__);
39
+ __webpack_require__.d(__webpack_exports__, {
40
+ baselinePackage: ()=>baselinePackage,
41
+ baselinePublicIdentityIsExact: ()=>baselinePublicIdentityIsExact,
42
+ resolveBaselinePackageDirectory: ()=>resolveBaselinePackageDirectory
43
+ });
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_module_namespaceObject = require("node:module");
47
+ const external_node_path_namespaceObject = require("node:path");
48
+ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
49
+ const parser_namespaceObject = require("@babel/parser");
50
+ const types_namespaceObject = require("@babel/types");
51
+ const baselinePackage = '@modern-js/bff-effect/microvertical-api';
52
+ const ownerName = '@modern-js/bff-effect';
53
+ const within = (root, file)=>file.startsWith(`${root}${external_node_path_default().sep}`);
54
+ function resolveBaselinePackageDirectory(fromFile) {
55
+ const lookup = (0, external_node_module_namespaceObject.createRequire)(fromFile).resolve.paths(baselinePackage);
56
+ for (const directory of lookup ?? []){
57
+ const candidate = external_node_path_default().join(directory, ownerName);
58
+ if (!external_node_fs_default().existsSync(candidate)) continue;
59
+ const root = external_node_fs_default().realpathSync(candidate);
60
+ const manifest = JSON.parse(external_node_fs_default().readFileSync(external_node_path_default().join(root, 'package.json'), 'utf8'));
61
+ if (![
62
+ ownerName,
63
+ '@bleedingdev/modern-js-bff-effect'
64
+ ].includes(manifest.name)) throw new Error(`${fromFile}: ${baselinePackage} resolved to unrelated package ${String(manifest.name)}`);
65
+ const target = importTarget(manifest.exports?.['./microvertical-api']);
66
+ if (!target?.startsWith('./')) throw new Error(`${fromFile}: ${baselinePackage} has no public Node import export`);
67
+ external_node_fs_default().statSync(external_node_path_default().resolve(root, target));
68
+ return root;
69
+ }
70
+ throw new Error(`${fromFile}: cannot resolve installed ${baselinePackage}`);
71
+ }
72
+ function importTarget(value) {
73
+ if ('string' == typeof value) return value;
74
+ if (!value || 'object' != typeof value || Array.isArray(value)) return;
75
+ for (const [condition, target] of Object.entries(value))if ([
76
+ 'node',
77
+ 'import',
78
+ 'default'
79
+ ].includes(condition)) {
80
+ const resolved = importTarget(target);
81
+ if (resolved) return resolved;
82
+ }
83
+ }
84
+ function baselinePublicIdentityIsExact(fromFile, expectation) {
85
+ const owner = external_node_fs_default().realpathSync(expectation.baselinePackageDirectory);
86
+ const manifest = JSON.parse(external_node_fs_default().readFileSync(external_node_path_default().join(owner, 'package.json'), 'utf8'));
87
+ if (expectation.baselinePackage !== baselinePackage || ![
88
+ ownerName,
89
+ '@bleedingdev/modern-js-bff-effect'
90
+ ].includes(manifest.name)) return false;
91
+ let resolvedOwner;
92
+ try {
93
+ resolvedOwner = resolveBaselinePackageDirectory(fromFile);
94
+ } catch (error) {
95
+ if (error instanceof Error && error.message.includes('resolved to unrelated package')) return false;
96
+ throw error;
97
+ }
98
+ if (resolvedOwner !== owner) return false;
99
+ const target = importTarget(manifest.exports?.['./microvertical-api']);
100
+ if (!target?.startsWith('./')) return false;
101
+ const modules = new Map();
102
+ const load = (filename)=>{
103
+ const real = external_node_fs_default().realpathSync(filename);
104
+ if (!within(owner, real)) return;
105
+ let file = modules.get(real);
106
+ if (!file) {
107
+ if (modules.size >= 64 || external_node_fs_default().statSync(real).size > 1000000) throw new Error(`${real}: public export analysis budget exceeded`);
108
+ file = (0, parser_namespaceObject.parse)(external_node_fs_default().readFileSync(real, 'utf8'), {
109
+ sourceType: 'module',
110
+ sourceFilename: real,
111
+ plugins: [
112
+ "typescript"
113
+ ]
114
+ });
115
+ modules.set(real, file);
116
+ }
117
+ return {
118
+ file,
119
+ real
120
+ };
121
+ };
122
+ const follow = (from, specifier)=>{
123
+ if (!specifier.startsWith('.')) return;
124
+ const candidate = external_node_path_default().resolve(external_node_path_default().dirname(from), specifier);
125
+ if (!within(owner, candidate)) return;
126
+ return [
127
+ candidate,
128
+ `${candidate}.ts`,
129
+ `${candidate}.js`,
130
+ external_node_path_default().join(candidate, 'index.ts'),
131
+ external_node_path_default().join(candidate, 'index.js')
132
+ ].find((file)=>external_node_fs_default().existsSync(file) && external_node_fs_default().statSync(file).isFile());
133
+ };
134
+ const exportedOwner = (filename, name, seen = new Set())=>{
135
+ const loaded = load(filename);
136
+ if (!loaded) return;
137
+ const { file, real } = loaded;
138
+ const key = `${real}:${name}`;
139
+ if (seen.has(key)) return;
140
+ seen = new Set([
141
+ ...seen,
142
+ key
143
+ ]);
144
+ const explicit = [];
145
+ const stars = [];
146
+ for (const statement of file.program.body){
147
+ if (types_namespaceObject.isExportAllDeclaration(statement) && 'type' !== statement.exportKind) {
148
+ const next = follow(real, statement.source.value);
149
+ if (!next) return;
150
+ stars.push(next);
151
+ }
152
+ if (!types_namespaceObject.isExportNamedDeclaration(statement) || 'type' === statement.exportKind) continue;
153
+ const declaration = statement.declaration;
154
+ if (types_namespaceObject.isVariableDeclaration(declaration) && declaration.declarations.some((value)=>types_namespaceObject.isIdentifier(value.id, {
155
+ name
156
+ }))) explicit.push(real);
157
+ if ((types_namespaceObject.isFunctionDeclaration(declaration) || types_namespaceObject.isClassDeclaration(declaration)) && types_namespaceObject.isIdentifier(declaration.id, {
158
+ name
159
+ })) explicit.push(real);
160
+ for (const value of statement.specifiers)if (types_namespaceObject.isExportSpecifier(value) && 'type' !== value.exportKind && types_namespaceObject.isIdentifier(value.exported, {
161
+ name
162
+ })) {
163
+ if (!types_namespaceObject.isIdentifier(value.local, {
164
+ name
165
+ })) {
166
+ explicit.push(void 0);
167
+ continue;
168
+ }
169
+ if (statement.source) {
170
+ const next = follow(real, statement.source.value);
171
+ explicit.push(next ? exportedOwner(next, name, seen) : void 0);
172
+ } else {
173
+ const local = file.program.body.find((item)=>types_namespaceObject.isVariableDeclaration(item) && item.declarations.some((value)=>types_namespaceObject.isIdentifier(value.id, {
174
+ name
175
+ })) || (types_namespaceObject.isFunctionDeclaration(item) || types_namespaceObject.isClassDeclaration(item)) && types_namespaceObject.isIdentifier(item.id, {
176
+ name
177
+ }));
178
+ if (local) {
179
+ explicit.push(real);
180
+ continue;
181
+ }
182
+ const imported = file.program.body.find((item)=>types_namespaceObject.isImportDeclaration(item) && 'type' !== item.importKind && item.specifiers.some((value)=>types_namespaceObject.isImportSpecifier(value) && 'type' !== value.importKind && types_namespaceObject.isIdentifier(value.local, {
183
+ name
184
+ }) && types_namespaceObject.isIdentifier(value.imported, {
185
+ name
186
+ })));
187
+ const next = types_namespaceObject.isImportDeclaration(imported) ? follow(real, imported.source.value) : void 0;
188
+ explicit.push(next ? exportedOwner(next, name, seen) : void 0);
189
+ }
190
+ }
191
+ }
192
+ if (explicit.length) return 1 === explicit.length ? explicit[0] : void 0;
193
+ const owners = stars.map((next)=>exportedOwner(next, name, seen));
194
+ const unique = new Set(owners.filter((value)=>void 0 !== value));
195
+ return 1 === unique.size ? [
196
+ ...unique
197
+ ][0] : void 0;
198
+ };
199
+ const entry = external_node_path_default().resolve(owner, target);
200
+ const owners = [
201
+ 'MicroVerticalBuildMarkerSchema',
202
+ 'MicroVerticalReadinessSchema',
203
+ 'createMicroVerticalOperationContext'
204
+ ].map((name)=>exportedOwner(entry, name));
205
+ return void 0 !== owners[0] && owners.every((value)=>value === owners[0]);
206
+ }
207
+ exports.baselinePackage = __webpack_exports__.baselinePackage;
208
+ exports.baselinePublicIdentityIsExact = __webpack_exports__.baselinePublicIdentityIsExact;
209
+ exports.resolveBaselinePackageDirectory = __webpack_exports__.resolveBaselinePackageDirectory;
210
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
211
+ "baselinePackage",
212
+ "baselinePublicIdentityIsExact",
213
+ "resolveBaselinePackageDirectory"
214
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
215
+ Object.defineProperty(exports, '__esModule', {
216
+ value: true
217
+ });
@@ -0,0 +1,321 @@
1
+ "use strict";
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
+ (()=>{
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
22
+ };
23
+ })();
24
+ (()=>{
25
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
26
+ })();
27
+ (()=>{
28
+ __webpack_require__.r = (exports1)=>{
29
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
30
+ value: 'Module'
31
+ });
32
+ Object.defineProperty(exports1, '__esModule', {
33
+ value: true
34
+ });
35
+ };
36
+ })();
37
+ var __webpack_exports__ = {};
38
+ __webpack_require__.r(__webpack_exports__);
39
+ __webpack_require__.d(__webpack_exports__, {
40
+ createModuleGraph: ()=>createModuleGraph,
41
+ exportedConst: ()=>exportedConst,
42
+ localConst: ()=>localConst,
43
+ parseConsumer: ()=>parseConsumer,
44
+ propertyName: ()=>propertyName
45
+ });
46
+ const external_node_fs_namespaceObject = require("node:fs");
47
+ var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
48
+ const external_node_module_namespaceObject = require("node:module");
49
+ const external_node_path_namespaceObject = require("node:path");
50
+ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
51
+ const types_namespaceObject = require("@babel/types");
52
+ const external_resolve_exports_namespaceObject = require("resolve.exports");
53
+ const external_source_analysis_cjs_namespaceObject = require("./source-analysis.cjs");
54
+ const MAX_MODULES = 256;
55
+ const MAX_LOOKUPS = 512;
56
+ function parseConsumer(filePath) {
57
+ if (external_node_fs_default().statSync(filePath).size > 1000000) throw new Error(`${filePath}: consumer source exceeds 1 MB analysis budget`);
58
+ const file = (0, external_source_analysis_cjs_namespaceObject.parseSource)(external_node_fs_default().readFileSync(filePath, 'utf8'), filePath);
59
+ (0, external_source_analysis_cjs_namespaceObject.traverseSource)(file, {
60
+ AssignmentExpression (p) {
61
+ throw new external_source_analysis_cjs_namespaceObject.SourceSyntaxError(`contract bindings must be immutable at ${p.node.start}`);
62
+ },
63
+ UpdateExpression (p) {
64
+ throw new external_source_analysis_cjs_namespaceObject.SourceSyntaxError(`contract bindings must be immutable at ${p.node.start}`);
65
+ },
66
+ TSModuleDeclaration () {
67
+ throw new external_source_analysis_cjs_namespaceObject.SourceSyntaxError('contract bindings must not be merged with namespaces');
68
+ }
69
+ });
70
+ return file;
71
+ }
72
+ const propertyName = (node)=>{
73
+ 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);
74
+ };
75
+ const localConst = (sourceFile, name)=>{
76
+ for (const item of sourceFile.program.body){
77
+ const statement = types_namespaceObject.isExportNamedDeclaration(item) ? item.declaration : item;
78
+ if (!types_namespaceObject.isVariableDeclaration(statement) || 'const' !== statement.kind) continue;
79
+ const matches = statement.declarations.filter((declaration)=>types_namespaceObject.isIdentifier(declaration.id, {
80
+ name
81
+ }));
82
+ if (1 === matches.length) return matches[0];
83
+ }
84
+ };
85
+ const exportedConst = (sourceFile, name)=>{
86
+ for (const statement of sourceFile.program.body)if (types_namespaceObject.isExportNamedDeclaration(statement) && 'type' !== statement.exportKind) {
87
+ if (types_namespaceObject.isVariableDeclaration(statement.declaration) && 'const' === statement.declaration.kind) {
88
+ const declaration = statement.declaration.declarations.find((value)=>types_namespaceObject.isIdentifier(value.id, {
89
+ name
90
+ }));
91
+ if (declaration) return declaration;
92
+ }
93
+ if (!statement.source && statement.specifiers.some((value)=>types_namespaceObject.isExportSpecifier(value) && 'type' !== value.exportKind && types_namespaceObject.isIdentifier(value.local, {
94
+ name
95
+ }) && types_namespaceObject.isIdentifier(value.exported, {
96
+ name
97
+ }))) return localConst(sourceFile, name);
98
+ }
99
+ };
100
+ const inside = (file, boundary)=>file === boundary || file.startsWith(`${boundary}${external_node_path_default().sep}`);
101
+ const containingWorkspace = (file)=>{
102
+ for(let directory = external_node_path_default().dirname(file);; directory = external_node_path_default().dirname(directory)){
103
+ if (external_node_fs_default().existsSync(external_node_path_default().join(directory, 'pnpm-workspace.yaml'))) return external_node_fs_default().realpathSync(directory);
104
+ if (directory === external_node_path_default().dirname(directory)) return;
105
+ }
106
+ };
107
+ const sourceBoundary = (file, workspace)=>{
108
+ for(let directory = external_node_path_default().dirname(file);; directory = external_node_path_default().dirname(directory)){
109
+ if (external_node_fs_default().existsSync(external_node_path_default().join(directory, 'package.json')) && directory !== workspace) return external_node_fs_default().realpathSync(directory);
110
+ if (directory === workspace || directory === external_node_path_default().dirname(directory)) return external_node_fs_default().realpathSync(external_node_path_default().dirname(file));
111
+ }
112
+ };
113
+ const sourceFileAt = (target, boundary)=>{
114
+ const stem = target.replace(/\.(?:[cm]?[jt]sx?)$/u, '');
115
+ for (const candidate of [
116
+ `${stem}.ts`,
117
+ `${stem}.tsx`,
118
+ `${stem}.mts`,
119
+ `${stem}.cts`,
120
+ target,
121
+ external_node_path_default().join(target, 'index.ts'),
122
+ external_node_path_default().join(target, 'index.tsx')
123
+ ])try {
124
+ const real = external_node_fs_default().realpathSync(candidate);
125
+ if (inside(real, boundary) && external_node_fs_default().statSync(real).isFile()) return real;
126
+ } catch {}
127
+ };
128
+ const packageEntry = (specifier)=>{
129
+ if (specifier.startsWith('.') || specifier.startsWith('/') || specifier.startsWith('#')) return;
130
+ const parts = specifier.split('/');
131
+ const count = specifier.startsWith('@') ? 2 : 1;
132
+ if (parts.length < count || parts.slice(0, count).some((part)=>!part)) return;
133
+ return {
134
+ name: parts.slice(0, count).join('/'),
135
+ exportKey: parts.length === count ? '.' : `./${parts.slice(count).join('/')}`
136
+ };
137
+ };
138
+ const resolveModulePath = (module, specifier, workspace)=>{
139
+ if (/^\.\.?\//u.test(specifier)) {
140
+ const file = sourceFileAt(external_node_path_default().resolve(external_node_path_default().dirname(module.path), specifier), module.boundary);
141
+ return void 0 === file ? void 0 : {
142
+ kind: 'module',
143
+ path: file,
144
+ boundary: module.boundary
145
+ };
146
+ }
147
+ const entry = packageEntry(specifier);
148
+ if (!entry) return;
149
+ if (!workspace) return {
150
+ kind: 'external'
151
+ };
152
+ const paths = (0, external_node_module_namespaceObject.createRequire)(module.path).resolve.paths(entry.name) ?? [];
153
+ for (const lookup of paths){
154
+ const directory = external_node_path_default().join(lookup, entry.name);
155
+ const manifest = external_node_path_default().join(directory, 'package.json');
156
+ if (!external_node_fs_default().existsSync(manifest)) continue;
157
+ const boundary = external_node_fs_default().realpathSync(directory);
158
+ if (!inside(boundary, workspace) || boundary.split(external_node_path_default().sep).includes('node_modules')) break;
159
+ const pkg = JSON.parse(external_node_fs_default().readFileSync(manifest, 'utf8'));
160
+ if (pkg.name !== entry.name || void 0 === pkg.exports) return;
161
+ let target;
162
+ try {
163
+ const targets = (0, external_resolve_exports_namespaceObject.exports)(pkg, entry.exportKey, {
164
+ conditions: [
165
+ 'modern:source'
166
+ ]
167
+ });
168
+ target = Array.isArray(targets) ? targets[0] : void 0;
169
+ } catch {
170
+ return;
171
+ }
172
+ if (!target || !target.startsWith('./')) return;
173
+ const file = sourceFileAt(external_node_path_default().resolve(boundary, target), boundary);
174
+ return void 0 === file ? void 0 : {
175
+ kind: 'module',
176
+ path: file,
177
+ boundary
178
+ };
179
+ }
180
+ return {
181
+ kind: 'external'
182
+ };
183
+ };
184
+ const importedBinding = (module, name)=>{
185
+ for (const statement of module.file.program.body)if (types_namespaceObject.isImportDeclaration(statement) && 'type' !== statement.importKind) {
186
+ for (const specifier of statement.specifiers)if (types_namespaceObject.isIdentifier(specifier.local, {
187
+ name
188
+ })) {
189
+ if (types_namespaceObject.isImportSpecifier(specifier) && 'type' !== specifier.importKind) return {
190
+ imported: propertyName(specifier.imported) ?? name,
191
+ specifier: statement.source.value
192
+ };
193
+ if (types_namespaceObject.isImportDefaultSpecifier(specifier)) return {
194
+ imported: 'default',
195
+ specifier: statement.source.value
196
+ };
197
+ }
198
+ }
199
+ };
200
+ const reexportedBinding = (module, name)=>{
201
+ for (const statement of module.file.program.body){
202
+ if (!types_namespaceObject.isExportNamedDeclaration(statement) || 'type' === statement.exportKind) continue;
203
+ const specifier = statement.specifiers.find((value)=>types_namespaceObject.isExportSpecifier(value) && 'type' !== value.exportKind && propertyName(value.exported) === name);
204
+ if (void 0 !== specifier && types_namespaceObject.isExportSpecifier(specifier)) return {
205
+ local: types_namespaceObject.isIdentifier(specifier.local) ? specifier.local.name : specifier.local.value,
206
+ ...statement.source ? {
207
+ specifier: statement.source.value
208
+ } : {}
209
+ };
210
+ }
211
+ };
212
+ const defaultExport = (module)=>{
213
+ for (const statement of module.file.program.body){
214
+ if (!types_namespaceObject.isExportDefaultDeclaration(statement)) continue;
215
+ const declaration = statement.declaration;
216
+ if (types_namespaceObject.isIdentifier(declaration)) return declaration.name;
217
+ return types_namespaceObject.isExpression(declaration) ? declaration : void 0;
218
+ }
219
+ };
220
+ function createModuleGraph(filePath) {
221
+ const realPath = external_node_fs_default().realpathSync(filePath);
222
+ const workspace = containingWorkspace(realPath);
223
+ const root = {
224
+ file: parseConsumer(realPath),
225
+ path: realPath,
226
+ boundary: sourceBoundary(realPath, workspace)
227
+ };
228
+ const modules = new Map([
229
+ [
230
+ root.path,
231
+ root
232
+ ]
233
+ ]);
234
+ const readModule = (modulePath, boundary)=>{
235
+ if (modules.has(modulePath)) return modules.get(modulePath);
236
+ if (modules.size >= MAX_MODULES) return;
237
+ let module;
238
+ try {
239
+ module = {
240
+ file: parseConsumer(modulePath),
241
+ path: modulePath,
242
+ boundary
243
+ };
244
+ } catch {
245
+ module = void 0;
246
+ }
247
+ modules.set(modulePath, module);
248
+ return module;
249
+ };
250
+ const resolveBinding = (module, name, scope, chain, seen)=>{
251
+ const key = `${scope}:${module.path}#${name}`;
252
+ if (seen.has(key) || seen.size >= MAX_LOOKUPS) return;
253
+ seen.add(key);
254
+ const last = chain.at(-1);
255
+ const hops = last?.path === module.path && last.name === name ? chain : [
256
+ ...chain,
257
+ {
258
+ path: module.path,
259
+ name
260
+ }
261
+ ];
262
+ const declaration = 'export' === scope ? exportedConst(module.file, name) : localConst(module.file, name);
263
+ if (declaration?.init) return {
264
+ kind: 'declaration',
265
+ expression: declaration.init,
266
+ module,
267
+ chain: hops
268
+ };
269
+ const throughModule = (specifier, imported, allowExternal)=>{
270
+ const target = resolveModulePath(module, specifier, workspace);
271
+ if (target?.kind === 'external') return allowExternal ? {
272
+ kind: 'external',
273
+ specifier,
274
+ name: imported,
275
+ chain: hops
276
+ } : void 0;
277
+ const next = target && readModule(target.path, target.boundary);
278
+ return void 0 === next ? void 0 : resolveBinding(next, imported, 'export', hops, seen);
279
+ };
280
+ if ('local' === scope) {
281
+ const imported = importedBinding(module, name);
282
+ return void 0 === imported ? void 0 : throughModule(imported.specifier, imported.imported, true);
283
+ }
284
+ if ('default' === name) {
285
+ const exported = defaultExport(module);
286
+ if ('string' == typeof exported) return resolveBinding(module, exported, 'local', hops, seen);
287
+ return void 0 === exported ? void 0 : {
288
+ kind: 'declaration',
289
+ expression: exported,
290
+ module,
291
+ chain: hops
292
+ };
293
+ }
294
+ const reexported = reexportedBinding(module, name);
295
+ if (void 0 !== reexported) return void 0 === reexported.specifier ? resolveBinding(module, reexported.local, 'local', hops, seen) : throughModule(reexported.specifier, reexported.local, true);
296
+ for (const statement of module.file.program.body){
297
+ if (!types_namespaceObject.isExportAllDeclaration(statement) || 'type' === statement.exportKind) continue;
298
+ const resolved = throughModule(statement.source.value, name, false);
299
+ if (void 0 !== resolved) return resolved;
300
+ }
301
+ };
302
+ return {
303
+ root,
304
+ resolve: (module, name, scope)=>resolveBinding(module, name, scope, [], new Set())
305
+ };
306
+ }
307
+ exports.createModuleGraph = __webpack_exports__.createModuleGraph;
308
+ exports.exportedConst = __webpack_exports__.exportedConst;
309
+ exports.localConst = __webpack_exports__.localConst;
310
+ exports.parseConsumer = __webpack_exports__.parseConsumer;
311
+ exports.propertyName = __webpack_exports__.propertyName;
312
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
313
+ "createModuleGraph",
314
+ "exportedConst",
315
+ "localConst",
316
+ "parseConsumer",
317
+ "propertyName"
318
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
319
+ Object.defineProperty(exports, '__esModule', {
320
+ value: true
321
+ });
@@ -30,6 +30,7 @@ __webpack_require__.r(__webpack_exports__);
30
30
  __webpack_require__.d(__webpack_exports__, {
31
31
  createStrictEffectApiBoundariesRule: ()=>createStrictEffectApiBoundariesRule
32
32
  });
33
+ const external_strict_effect_runtime_cjs_namespaceObject = require("../../strict-effect-runtime.cjs");
33
34
  const external_ast_cjs_namespaceObject = require("../ast.cjs");
34
35
  const createStrictEffectApiBoundariesRule = ()=>({
35
36
  meta: {
@@ -49,15 +50,16 @@ const createStrictEffectApiBoundariesRule = ()=>({
49
50
  node,
50
51
  message: 'Generated UltraModern workspaces use direct api/index.ts, shared/api.ts and src/api/* paths; api/effect, api/lambda, shared/effect and src/effect are forbidden.'
51
52
  });
52
- (0, external_ast_cjs_namespaceObject.reportProgramPattern)(context, node, source, /@modern-js\/plugin-bff\/hono-server/u, 'UltraModern API workspaces must not import Hono server helpers; use @modern-js/plugin-bff/effect-edge and HttpApi.');
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.');
53
54
  (0, external_ast_cjs_namespaceObject.reportProgramPattern)(context, node, source, /\bruntimeFramework\s*(?::|=)\s*['"]hono['"]/u, 'UltraModern API apps must use bff.runtimeFramework: "effect".');
54
- (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.');
55
56
  (0, external_ast_cjs_namespaceObject.reportProgramPattern)(context, node, source, /\bstrictEffectApproach\s*(?::|=)\s*false\b/u, 'UltraModern API apps must keep strictEffectApproach enabled.');
56
57
  if ((0, external_ast_cjs_namespaceObject.isApiEntryFile)(filename)) {
57
- (0, external_ast_cjs_namespaceObject.reportMissingProgramPattern)(context, node, source, /\bdefineEffectBff\b/u, 'Generated API entries must export defineEffectBff(...).');
58
- (0, external_ast_cjs_namespaceObject.reportMissingProgramPattern)(context, node, source, /\bHttpApiBuilder\b/u, 'Generated API entries must implement handlers through HttpApiBuilder.');
59
- (0, external_ast_cjs_namespaceObject.reportMissingProgramPattern)(context, node, source, /\bLayer\b/u, 'Generated API entries must compose dependencies with Effect Layer.');
60
- (0, external_ast_cjs_namespaceObject.reportMissingProgramPattern)(context, node, source, /from\s+['"]\.\.\/shared\/api\.ts['"]/u, 'Generated API entries must import the contract from ../shared/api.ts.');
58
+ const violation = (0, external_strict_effect_runtime_cjs_namespaceObject.strictEffectRuntimeTopologyViolation)(source, (0, external_strict_effect_runtime_cjs_namespaceObject.createEffectApiImportResolver)(filename));
59
+ if (violation) context.report({
60
+ node,
61
+ message: violation
62
+ });
61
63
  }
62
64
  if ((0, external_ast_cjs_namespaceObject.isSharedApiContractFile)(filename)) {
63
65
  (0, external_ast_cjs_namespaceObject.reportMissingProgramPattern)(context, node, source, /\bHttpApi\.make\b/u, 'Generated shared API contracts must declare an HttpApi contract.');
@@ -0,0 +1,104 @@
1
+ "use strict";
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
+ (()=>{
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
22
+ };
23
+ })();
24
+ (()=>{
25
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
26
+ })();
27
+ (()=>{
28
+ __webpack_require__.r = (exports1)=>{
29
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
30
+ value: 'Module'
31
+ });
32
+ Object.defineProperty(exports1, '__esModule', {
33
+ value: true
34
+ });
35
+ };
36
+ })();
37
+ var __webpack_exports__ = {};
38
+ __webpack_require__.r(__webpack_exports__);
39
+ __webpack_require__.d(__webpack_exports__, {
40
+ SourceSyntaxError: ()=>SourceSyntaxError,
41
+ consumerParserPlugins: ()=>consumerParserPlugins,
42
+ parseSource: ()=>parseSource,
43
+ traverseSource: ()=>traverseSource,
44
+ unwrapExpression: ()=>unwrapExpression
45
+ });
46
+ const parser_namespaceObject = require("@babel/parser");
47
+ const traverse_namespaceObject = require("@babel/traverse");
48
+ var traverse_default = /*#__PURE__*/ __webpack_require__.n(traverse_namespaceObject);
49
+ const types_namespaceObject = require("@babel/types");
50
+ const consumerParserPlugins = (filePath)=>/\.[jt]sx$/u.test(filePath) ? [
51
+ "typescript",
52
+ 'jsx'
53
+ ] : [
54
+ "typescript"
55
+ ];
56
+ class SourceSyntaxError extends Error {
57
+ }
58
+ class SourceValidationHub extends traverse_namespaceObject.Hub {
59
+ buildError(_node, message) {
60
+ return new SourceSyntaxError(message);
61
+ }
62
+ }
63
+ function parseSource(source, filename, syntaxMessage) {
64
+ try {
65
+ return (0, parser_namespaceObject.parse)(source, {
66
+ sourceType: 'module',
67
+ sourceFilename: filename,
68
+ plugins: consumerParserPlugins(filename)
69
+ });
70
+ } catch (cause) {
71
+ if ('object' == typeof cause && null !== cause && 'code' in cause && 'BABEL_PARSER_SYNTAX_ERROR' === cause.code && 'reasonCode' in cause && 'string' == typeof cause.reasonCode) throw new SourceSyntaxError(syntaxMessage ?? (cause instanceof Error ? cause.message : String(cause)));
72
+ throw cause;
73
+ }
74
+ }
75
+ function traverseSource(file, visitor) {
76
+ const program = traverse_namespaceObject.NodePath.get({
77
+ hub: new SourceValidationHub(),
78
+ parentPath: void 0,
79
+ parent: file,
80
+ container: file,
81
+ key: 'program'
82
+ });
83
+ program.setContext();
84
+ traverse_default()(file, visitor, program.scope, void 0, program);
85
+ }
86
+ function unwrapExpression(node, includeAssertions = false) {
87
+ while(types_namespaceObject.isTSAsExpression(node) || types_namespaceObject.isParenthesizedExpression(node) || types_namespaceObject.isTSSatisfiesExpression(node) || includeAssertions && (types_namespaceObject.isTSTypeAssertion(node) || types_namespaceObject.isTSNonNullExpression(node)))node = node.expression;
88
+ return node;
89
+ }
90
+ exports.SourceSyntaxError = __webpack_exports__.SourceSyntaxError;
91
+ exports.consumerParserPlugins = __webpack_exports__.consumerParserPlugins;
92
+ exports.parseSource = __webpack_exports__.parseSource;
93
+ exports.traverseSource = __webpack_exports__.traverseSource;
94
+ exports.unwrapExpression = __webpack_exports__.unwrapExpression;
95
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
96
+ "SourceSyntaxError",
97
+ "consumerParserPlugins",
98
+ "parseSource",
99
+ "traverseSource",
100
+ "unwrapExpression"
101
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
102
+ Object.defineProperty(exports, '__esModule', {
103
+ value: true
104
+ });