@eggjs/tegg-common-util 3.62.0 → 4.0.0-beta.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/README.md +13 -136
  2. package/dist/FSUtil.js +13 -0
  3. package/dist/Graph.js +159 -0
  4. package/dist/MapUtil.js +9 -0
  5. package/dist/{src/ModuleConfig.d.ts → ModuleConfig.d.ts} +0 -6
  6. package/dist/ModuleConfig.js +282 -0
  7. package/dist/{src/ModuleConfigs.d.ts → ModuleConfigs.d.ts} +1 -0
  8. package/dist/ModuleConfigs.js +10 -0
  9. package/dist/NameUtil.js +6 -0
  10. package/dist/{src/ObjectUtils.d.ts → ObjectUtils.d.ts} +1 -1
  11. package/dist/ObjectUtils.js +51 -0
  12. package/dist/ProxyUtil.js +14 -0
  13. package/dist/StackUtil.d.ts +3 -0
  14. package/dist/StackUtil.js +49 -0
  15. package/dist/TimerUtil.d.ts +3 -0
  16. package/dist/TimerUtil.js +6 -0
  17. package/dist/index.d.ts +11 -11
  18. package/dist/index.js +13 -29
  19. package/package.json +29 -26
  20. package/dist/src/FSUtil.js +0 -17
  21. package/dist/src/Graph.js +0 -168
  22. package/dist/src/MapUtil.js +0 -13
  23. package/dist/src/ModuleConfig.js +0 -386
  24. package/dist/src/ModuleConfigs.js +0 -14
  25. package/dist/src/NameUtil.js +0 -10
  26. package/dist/src/ObjectUtils.js +0 -55
  27. package/dist/src/ProxyUtil.js +0 -17
  28. package/dist/src/StackUtil.d.ts +0 -7
  29. package/dist/src/StackUtil.js +0 -44
  30. package/dist/src/StreamUtil.d.ts +0 -3
  31. package/dist/src/StreamUtil.js +0 -11
  32. package/dist/src/TimerUtil.d.ts +0 -9
  33. package/dist/src/TimerUtil.js +0 -32
  34. /package/dist/{src/FSUtil.d.ts → FSUtil.d.ts} +0 -0
  35. /package/dist/{src/Graph.d.ts → Graph.d.ts} +0 -0
  36. /package/dist/{src/MapUtil.d.ts → MapUtil.d.ts} +0 -0
  37. /package/dist/{src/NameUtil.d.ts → NameUtil.d.ts} +0 -0
  38. /package/dist/{src/ProxyUtil.d.ts → ProxyUtil.d.ts} +0 -0
package/README.md CHANGED
@@ -1,140 +1,17 @@
1
- # @eggjs/tegg-common-util
1
+ # `@eggjs/tegg-common-util`
2
2
 
3
- Common utility functions for tegg framework.
3
+ [![NPM version][npm-image]][npm-url]
4
+ [![Known Vulnerabilities][snyk-image]][snyk-url]
5
+ [![npm download][download-image]][download-url]
6
+ [![Node.js Version](https://img.shields.io/node/v/@eggjs/tegg-common-util.svg?style=flat)](https://nodejs.org/en/download/)
4
7
 
5
- ## ModuleConfigUtil.deduplicateModules
8
+ [npm-image]: https://img.shields.io/npm/v/@eggjs/tegg-common-util.svg?style=flat-square
9
+ [npm-url]: https://npmjs.org/package/@eggjs/tegg-common-util
10
+ [snyk-image]: https://snyk.io/test/npm/@eggjs/tegg-common-util/badge.svg?style=flat-square
11
+ [snyk-url]: https://snyk.io/test/npm/@eggjs/tegg-common-util
12
+ [download-image]: https://img.shields.io/npm/dm/@eggjs/tegg-common-util.svg?style=flat-square
13
+ [download-url]: https://npmjs.org/package/@eggjs/tegg-common-util
6
14
 
7
- A utility method for deduplicating module references to avoid adding duplicate modules.
15
+ # Usage
8
16
 
9
- ### Features
10
-
11
- - **Path-based deduplication**: Removes modules with duplicate paths
12
- - **Name-based deduplication**: Removes modules with duplicate names (throws error if found)
13
- - **Priority handling**: Prioritizes non-optional modules over optional ones
14
- - **Error handling**: Throws error for duplicate module names with different paths
15
- - **Simple API**: No complex options, straightforward behavior
16
-
17
- ### API
18
-
19
- ```typescript
20
- public static deduplicateModules(
21
- moduleReferences: readonly ModuleReference[]
22
- ): readonly ModuleReference[]
23
- ```
24
-
25
- **Note**: This method does not accept options parameters. The behavior is fixed and optimized for common use cases.
26
-
27
- ### Behavior
28
-
29
- 1. **Path Deduplication**: If multiple modules have the same path, only one is kept
30
- 2. **Optional Priority**: When paths are the same, non-optional modules are prioritized over optional ones
31
- 3. **Name Validation**: If modules have the same name but different paths, an error is thrown
32
- 4. **First Occurrence**: When both modules have the same optional status, the first occurrence is kept
33
-
34
- ### Usage Examples
35
-
36
- #### Basic Usage
37
-
38
- ```typescript
39
- import { ModuleConfigUtil } from '@eggjs/tegg-common-util';
40
-
41
- const modules = [
42
- { name: 'module1', path: '/path/to/module1' },
43
- { name: 'module2', path: '/path/to/module2' },
44
- { name: 'module1', path: '/different/path/to/module1' }, // Will throw error
45
- ];
46
-
47
- const result = ModuleConfigUtil.deduplicateModules(modules);
48
- // Throws Error: Duplicate module name "module1" found
49
- ```
50
-
51
- #### With Optional Modules
52
-
53
- ```typescript
54
- const modules = [
55
- { name: 'module1', path: '/path/to/module1', optional: true },
56
- { name: 'module1', path: '/path/to/module1' }, // Non-optional version
57
- ];
58
-
59
- const result = ModuleConfigUtil.deduplicateModules(modules);
60
- // Result: 1 module, non-optional version kept
61
- ```
62
-
63
- #### Path Deduplication
64
-
65
- ```typescript
66
- const modules = [
67
- { name: 'module1', path: '/path/to/module1' },
68
- { name: 'module2', path: '/path/to/module1' }, // Same path, different name
69
- ];
70
-
71
- const result = ModuleConfigUtil.deduplicateModules(modules);
72
- // Result: 1 module, first occurrence kept
73
- ```
74
-
75
- ### Use Cases
76
-
77
- #### 1. Plugin/Config Module Scanner
78
-
79
- ```typescript
80
- // In ModuleScanner.loadModuleReferences()
81
- return ModuleConfigUtil.deduplicateModules(allModuleReferences);
82
- // Automatically handles deduplication with optimal defaults
83
- ```
84
-
85
- #### 2. Standalone Runner
86
-
87
- ```typescript
88
- // In Runner.getModuleReferences()
89
- return ModuleConfigUtil.deduplicateModules(allModuleReferences);
90
- // Simple and reliable deduplication
91
- ```
92
-
93
- #### 3. Error Handling
94
-
95
- ```typescript
96
- try {
97
- const result = ModuleConfigUtil.deduplicateModules(modules);
98
- } catch (error) {
99
- if (error.message.includes('Duplicate module name')) {
100
- // Handle duplicate module name error
101
- console.error('Configuration error:', error.message);
102
- }
103
- throw error;
104
- }
105
- ```
106
-
107
- ### Benefits
108
-
109
- 1. **Simplicity**: No complex configuration needed, works out of the box
110
- 2. **Reliability**: Consistent behavior across different use cases
111
- 3. **Performance**: Optimized for common scenarios
112
- 4. **Error Prevention**: Catches configuration errors early
113
- 5. **Maintainability**: Simple API reduces complexity
114
-
115
- ### Migration from Options-based API
116
-
117
- #### Before (Options-based - Not Available)
118
- ```typescript
119
- // This API never existed in the actual implementation
120
- const result = ModuleConfigUtil.deduplicateModules(modules, {
121
- prioritizeNonOptional: true,
122
- allowNameDuplicates: false,
123
- logPrefix: '[tegg/config]',
124
- logger: customLogger,
125
- });
126
- ```
127
-
128
- #### After (Current Implementation)
129
- ```typescript
130
- // Current implementation - simple and direct
131
- const result = ModuleConfigUtil.deduplicateModules(modules);
132
- // Automatically handles all deduplication logic
133
- ```
134
-
135
- ### Important Notes
136
-
137
- - **No Options**: The method signature is fixed and does not accept configuration options
138
- - **Error on Name Duplicates**: Duplicate names with different paths will cause an error
139
- - **Automatic Priority**: Non-optional modules are automatically prioritized over optional ones
140
- - **Path-based Deduplication**: Same path modules are deduplicated with smart priority handling
17
+ This is an internal tegg library, you probably shouldn't use it directly.
package/dist/FSUtil.js ADDED
@@ -0,0 +1,13 @@
1
+ import fs from 'node:fs/promises';
2
+ export class FSUtil {
3
+ static async fileExists(filePath) {
4
+ try {
5
+ await fs.access(filePath);
6
+ }
7
+ catch {
8
+ return false;
9
+ }
10
+ return true;
11
+ }
12
+ }
13
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRlNVdGlsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0ZTVXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUVsQyxNQUFNLE9BQU8sTUFBTTtJQUNqQixNQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxRQUFnQjtRQUN0QyxJQUFJLENBQUM7WUFDSCxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDNUIsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztDQUNGIn0=
package/dist/Graph.js ADDED
@@ -0,0 +1,159 @@
1
+ const inspect = Symbol.for('nodejs.util.inspect.custom');
2
+ export class GraphNode {
3
+ val;
4
+ toNodeMap = new Map();
5
+ fromNodeMap = new Map();
6
+ constructor(val) {
7
+ this.val = val;
8
+ }
9
+ get id() {
10
+ return this.val.id;
11
+ }
12
+ addToVertex(node, meta) {
13
+ if (this.toNodeMap.has(node.id)) {
14
+ return false;
15
+ }
16
+ this.toNodeMap.set(node.id, { node, meta });
17
+ return true;
18
+ }
19
+ addFromVertex(node, meta) {
20
+ if (this.fromNodeMap.has(node.id)) {
21
+ return false;
22
+ }
23
+ this.fromNodeMap.set(node.id, { node, meta });
24
+ return true;
25
+ }
26
+ [inspect]() {
27
+ return this.toJSON();
28
+ }
29
+ toJSON() {
30
+ return {
31
+ val: this.val,
32
+ toNodes: Array.from(this.toNodeMap.values()),
33
+ fromNodes: Array.from(this.fromNodeMap.values()),
34
+ };
35
+ }
36
+ toString() {
37
+ return this.val.toString();
38
+ }
39
+ }
40
+ export class GraphPath {
41
+ nodeIdMap = new Map();
42
+ nodes = [];
43
+ pushVertex(node, meta) {
44
+ const val = this.nodeIdMap.get(node.id) || 0;
45
+ this.nodeIdMap.set(node.id, val + 1);
46
+ this.nodes.push({ node, meta });
47
+ return val === 0;
48
+ }
49
+ popVertex() {
50
+ const nodeHandler = this.nodes.pop();
51
+ if (nodeHandler) {
52
+ const val = this.nodeIdMap.get(nodeHandler.node.id);
53
+ this.nodeIdMap.set(nodeHandler.node.id, val - 1);
54
+ }
55
+ }
56
+ toString() {
57
+ const res = this.nodes.reduce((p, c) => {
58
+ let msg = '';
59
+ if (c.meta) {
60
+ msg += ` ${c.meta.toString()} -> `;
61
+ }
62
+ else if (p.length) {
63
+ msg += ' -> ';
64
+ }
65
+ msg += c.node.val.toString();
66
+ p.push(msg);
67
+ return p;
68
+ }, new Array());
69
+ return res.join('');
70
+ }
71
+ [inspect]() {
72
+ return this.toString();
73
+ }
74
+ }
75
+ export class Graph {
76
+ nodes = new Map();
77
+ addVertex(node) {
78
+ if (this.nodes.has(node.id)) {
79
+ return false;
80
+ }
81
+ this.nodes.set(node.id, node);
82
+ return true;
83
+ }
84
+ addEdge(from, to, meta) {
85
+ to.addFromVertex(from, meta);
86
+ return from.addToVertex(to, meta);
87
+ }
88
+ findToNode(id, meta) {
89
+ const node = this.nodes.get(id);
90
+ if (!node)
91
+ return undefined;
92
+ for (const { node: toNode, meta: edgeMeta } of node.toNodeMap.values()) {
93
+ if (edgeMeta && meta.equal(edgeMeta)) {
94
+ return toNode;
95
+ }
96
+ }
97
+ return undefined;
98
+ }
99
+ appendVertexToPath(node, accessPath, meta) {
100
+ if (!accessPath.pushVertex(node, meta)) {
101
+ return false;
102
+ }
103
+ for (const toNode of node.toNodeMap.values()) {
104
+ if (!this.appendVertexToPath(toNode.node, accessPath, toNode.meta)) {
105
+ return false;
106
+ }
107
+ }
108
+ accessPath.popVertex();
109
+ return true;
110
+ }
111
+ loopPath() {
112
+ const accessPath = new GraphPath();
113
+ const nodes = Array.from(this.nodes.values());
114
+ for (const node of nodes) {
115
+ if (!this.appendVertexToPath(node, accessPath)) {
116
+ return accessPath;
117
+ }
118
+ }
119
+ return;
120
+ }
121
+ accessNode(node, nodes, accessed, res) {
122
+ const index = nodes.indexOf(node);
123
+ if (accessed[index]) {
124
+ return;
125
+ }
126
+ if (!node.toNodeMap.size) {
127
+ accessed[nodes.indexOf(node)] = true;
128
+ res.push(node);
129
+ return;
130
+ }
131
+ for (const toNode of node.toNodeMap.values()) {
132
+ this.accessNode(toNode.node, nodes, accessed, res);
133
+ }
134
+ accessed[nodes.indexOf(node)] = true;
135
+ res.push(node);
136
+ }
137
+ // sort by direct
138
+ // priority:
139
+ // 1. vertex can not be access
140
+ // 2. reverse by access direct
141
+ //
142
+ // notice:
143
+ // 1. sort result is not stable
144
+ // 2. graph with loop can not be sort
145
+ sort() {
146
+ const res = [];
147
+ const nodes = Array.from(this.nodes.values());
148
+ const accessed = [];
149
+ for (let i = 0; i < nodes.length; ++i) {
150
+ accessed.push(false);
151
+ }
152
+ for (let i = 0; i < nodes.length; ++i) {
153
+ const node = nodes[i];
154
+ this.accessNode(node, nodes, accessed, res);
155
+ }
156
+ return res;
157
+ }
158
+ }
159
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiR3JhcGguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvR3JhcGgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0FBT3pELE1BQU0sT0FBTyxTQUFTO0lBQ3BCLEdBQUcsQ0FBSTtJQUNQLFNBQVMsR0FBbUQsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUN0RSxXQUFXLEdBQW1ELElBQUksR0FBRyxFQUFFLENBQUM7SUFFeEUsWUFBWSxHQUFNO1FBQ2hCLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO0lBQ2pCLENBQUM7SUFFRCxJQUFJLEVBQUU7UUFDSixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxXQUFXLENBQUMsSUFBcUIsRUFBRSxJQUFRO1FBQ3pDLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDaEMsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBQ0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzVDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELGFBQWEsQ0FBQyxJQUFxQixFQUFFLElBQVE7UUFDM0MsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUNsQyxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFDRCxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDOUMsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsQ0FBQyxPQUFPLENBQUM7UUFDUCxPQUFPLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRUQsTUFBTTtRQUNKLE9BQU87WUFDTCxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUc7WUFDYixPQUFPLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzVDLFNBQVMsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7U0FDakQsQ0FBQztJQUNKLENBQUM7SUFFRCxRQUFRO1FBQ04sT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQzdCLENBQUM7Q0FDRjtBQUVELE1BQU0sT0FBTyxTQUFTO0lBQ3BCLFNBQVMsR0FBd0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUMzQyxLQUFLLEdBQStDLEVBQUUsQ0FBQztJQUV2RCxVQUFVLENBQUMsSUFBcUIsRUFBRSxJQUFRO1FBQ3hDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDN0MsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDckMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNoQyxPQUFPLEdBQUcsS0FBSyxDQUFDLENBQUM7SUFDbkIsQ0FBQztJQUVELFNBQVM7UUFDUCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3JDLElBQUksV0FBVyxFQUFFLENBQUM7WUFDaEIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUUsQ0FBQztZQUNyRCxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDbkQsQ0FBQztJQUNILENBQUM7SUFFRCxRQUFRO1FBQ04sTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDckMsSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFDO1lBQ2IsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ1gsR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDO1lBQ3JDLENBQUM7aUJBQU0sSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ3BCLEdBQUcsSUFBSSxNQUFNLENBQUM7WUFDaEIsQ0FBQztZQUNELEdBQUcsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUM3QixDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ1osT0FBTyxDQUFDLENBQUM7UUFDWCxDQUFDLEVBQUUsSUFBSSxLQUFLLEVBQVUsQ0FBQyxDQUFDO1FBQ3hCLE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN0QixDQUFDO0lBRUQsQ0FBQyxPQUFPLENBQUM7UUFDUCxPQUFPLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUN6QixDQUFDO0NBQ0Y7QUFFRCxNQUFNLE9BQU8sS0FBSztJQUNoQixLQUFLLEdBQWlDLElBQUksR0FBRyxFQUFFLENBQUM7SUFFaEQsU0FBUyxDQUFDLElBQXFCO1FBQzdCLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDNUIsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUM5QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxPQUFPLENBQUMsSUFBcUIsRUFBRSxFQUFtQixFQUFFLElBQVE7UUFDMUQsRUFBRSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDN0IsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQsVUFBVSxDQUFDLEVBQVUsRUFBRSxJQUFPO1FBQzVCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTyxTQUFTLENBQUM7UUFDNUIsS0FBSyxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO1lBQ3ZFLElBQUksUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDckMsT0FBTyxNQUFNLENBQUM7WUFDaEIsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQsa0JBQWtCLENBQUMsSUFBcUIsRUFBRSxVQUEyQixFQUFFLElBQVE7UUFDN0UsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDdkMsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBQ0QsS0FBSyxNQUFNLE1BQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7WUFDN0MsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDbkUsT0FBTyxLQUFLLENBQUM7WUFDZixDQUFDO1FBQ0gsQ0FBQztRQUNELFVBQVUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUN2QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxRQUFRO1FBQ04sTUFBTSxVQUFVLEdBQUcsSUFBSSxTQUFTLEVBQVEsQ0FBQztRQUN6QyxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUM5QyxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUM7Z0JBQy9DLE9BQU8sVUFBVSxDQUFDO1lBQ3BCLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTztJQUNULENBQUM7SUFFRCxVQUFVLENBQUMsSUFBcUIsRUFBRSxLQUE2QixFQUFFLFFBQW1CLEVBQUUsR0FBMkI7UUFDL0csTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsQyxJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3BCLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDekIsUUFBUSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDckMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNmLE9BQU87UUFDVCxDQUFDO1FBQ0QsS0FBSyxNQUFNLE1BQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7WUFDN0MsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDckQsQ0FBQztRQUNELFFBQVEsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQ3JDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakIsQ0FBQztJQUVELGlCQUFpQjtJQUNqQixZQUFZO0lBQ1osOEJBQThCO0lBQzlCLDhCQUE4QjtJQUM5QixFQUFFO0lBQ0YsVUFBVTtJQUNWLCtCQUErQjtJQUMvQixxQ0FBcUM7SUFDckMsSUFBSTtRQUNGLE1BQU0sR0FBRyxHQUEyQixFQUFFLENBQUM7UUFDdkMsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDOUMsTUFBTSxRQUFRLEdBQWMsRUFBRSxDQUFDO1FBQy9CLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDdEMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN2QixDQUFDO1FBQ0QsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUN0QyxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUM5QyxDQUFDO1FBQ0QsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0NBQ0YifQ==
@@ -0,0 +1,9 @@
1
+ export class MapUtil {
2
+ static getOrStore(map, key, value) {
3
+ if (!map.has(key)) {
4
+ map.set(key, value);
5
+ }
6
+ return map.get(key);
7
+ }
8
+ }
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWFwVXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9NYXBVdGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sT0FBTyxPQUFPO0lBQ2xCLE1BQU0sQ0FBQyxVQUFVLENBQU8sR0FBYyxFQUFFLEdBQU0sRUFBRSxLQUFRO1FBQ3RELElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDbEIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdEIsQ0FBQztRQUNELE9BQU8sR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUUsQ0FBQztJQUN2QixDQUFDO0NBQ0YifQ==
@@ -17,10 +17,4 @@ export declare class ModuleConfigUtil {
17
17
  static readModuleNameSync(moduleDir: string, baseDir?: string): string;
18
18
  static loadModuleConfig(moduleDir: string, baseDir?: string, env?: string): Promise<ModuleConfig>;
19
19
  static loadModuleConfigSync(moduleDir: string, baseDir?: string, env?: string): ModuleConfig;
20
- /**
21
- * 去重模块引用,避免重复添加相同的模块
22
- * @param moduleReferences 模块引用数组
23
- * @return 去重后的模块引用数组
24
- */
25
- static deduplicateModules(moduleReferences: readonly ModuleReference[]): readonly ModuleReference[];
26
20
  }
@@ -0,0 +1,282 @@
1
+ import assert from 'node:assert';
2
+ import fs, { promises as fsPromise } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { extend } from 'extend2';
5
+ import { globbySync } from 'globby';
6
+ import { load as yamlLoad } from 'js-yaml';
7
+ import { importResolve } from '@eggjs/utils';
8
+ import { FSUtil } from "./FSUtil.js";
9
+ export class ModuleReferenceConfigHelp {
10
+ static isInlineModuleReference(moduleReference) {
11
+ return !!moduleReference.path;
12
+ }
13
+ static isNpmModuleReference(moduleReference) {
14
+ return !!moduleReference.package;
15
+ }
16
+ }
17
+ const DEFAULT_READ_MODULE_REF_OPTS = {
18
+ deep: 10,
19
+ };
20
+ export class ModuleConfigUtil {
21
+ static configNames;
22
+ static setConfigNames(configNames) {
23
+ ModuleConfigUtil.configNames = configNames;
24
+ }
25
+ static readModuleReference(baseDir, options) {
26
+ // 1. module.json exits use module.json as module reference
27
+ // 1. module.json not exits scan baseDir get package.json to find modules
28
+ const configDir = path.join(baseDir, 'config');
29
+ const moduleJsonPath = path.join(configDir, 'module.json');
30
+ if (fs.existsSync(moduleJsonPath)) {
31
+ return this.readModuleReferenceFromModuleJson(configDir, moduleJsonPath, options?.cwd || baseDir);
32
+ }
33
+ return this.readModuleReferenceFromScan(baseDir, options);
34
+ }
35
+ static readModuleReferenceFromModuleJson(configDir, moduleJsonPath, cwd) {
36
+ const moduleJsonContent = fs.readFileSync(moduleJsonPath, 'utf8');
37
+ const moduleJson = JSON.parse(moduleJsonContent);
38
+ const moduleReferenceList = [];
39
+ for (const moduleReferenceConfig of moduleJson) {
40
+ let moduleReference;
41
+ if (ModuleReferenceConfigHelp.isNpmModuleReference(moduleReferenceConfig)) {
42
+ const options = cwd ? { paths: [cwd] } : {};
43
+ // path.posix for windows keep path as foo/package.json
44
+ const pkgJson = path.posix.join(moduleReferenceConfig.package, 'package.json');
45
+ const file = importResolve(pkgJson, options);
46
+ const modulePath = path.dirname(file);
47
+ moduleReference = {
48
+ path: modulePath,
49
+ name: ModuleConfigUtil.readModuleNameSync(modulePath),
50
+ };
51
+ }
52
+ else if (ModuleReferenceConfigHelp.isInlineModuleReference(moduleReferenceConfig)) {
53
+ const modulePath = path.join(configDir, moduleReferenceConfig.path);
54
+ moduleReference = {
55
+ path: modulePath,
56
+ name: ModuleConfigUtil.readModuleNameSync(modulePath),
57
+ };
58
+ }
59
+ else {
60
+ throw new Error('unknown type of module reference config: ' + JSON.stringify(moduleReferenceConfig));
61
+ }
62
+ moduleReferenceList.push(moduleReference);
63
+ }
64
+ return moduleReferenceList;
65
+ }
66
+ static readModuleReferenceFromScan(baseDir, options) {
67
+ const ref = [];
68
+ const realOptions = Object.assign({}, DEFAULT_READ_MODULE_REF_OPTS, options);
69
+ const packagePaths = globbySync([
70
+ '**/package.json',
71
+ // not load node_modules
72
+ '!**/node_modules',
73
+ // not load files in .xxx/
74
+ '!**/+(.*)/**',
75
+ // not load coverage
76
+ '!**/coverage',
77
+ ...(realOptions.extraFilePattern || []),
78
+ ], {
79
+ cwd: baseDir,
80
+ deep: realOptions.deep,
81
+ });
82
+ const moduleDirSet = new Set();
83
+ for (const packagePath of packagePaths) {
84
+ const absolutePkgPath = path.join(baseDir, packagePath);
85
+ let realPkgPath;
86
+ try {
87
+ realPkgPath = fs.realpathSync(absolutePkgPath);
88
+ }
89
+ catch {
90
+ continue;
91
+ }
92
+ const moduleDir = path.dirname(realPkgPath);
93
+ // skip the symbolic link
94
+ if (moduleDirSet.has(moduleDir)) {
95
+ continue;
96
+ }
97
+ moduleDirSet.add(moduleDir);
98
+ let name;
99
+ try {
100
+ name = this.readModuleNameSync(moduleDir);
101
+ }
102
+ catch {
103
+ continue;
104
+ }
105
+ ref.push({
106
+ path: moduleDir,
107
+ name,
108
+ });
109
+ }
110
+ const moduleReferences = this.readModuleFromNodeModules(baseDir);
111
+ for (const moduleReference of moduleReferences) {
112
+ const moduleBasePath = path.basename(moduleReference.path);
113
+ moduleDirSet.forEach(modulePath => {
114
+ if (path.basename(modulePath) === moduleBasePath) {
115
+ throw new Error('duplicate import of module reference: ' + moduleBasePath);
116
+ }
117
+ });
118
+ ref.push({
119
+ path: moduleReference.path,
120
+ name: moduleReference.name,
121
+ });
122
+ }
123
+ return ref;
124
+ }
125
+ static readModuleFromNodeModules(baseDir) {
126
+ const ref = [];
127
+ let pkgContent;
128
+ try {
129
+ pkgContent = fs.readFileSync(path.join(baseDir, 'package.json'), 'utf8');
130
+ }
131
+ catch {
132
+ return [];
133
+ }
134
+ const pkg = JSON.parse(pkgContent);
135
+ for (const dependencyKey of Object.keys(pkg.dependencies || {})) {
136
+ let packageJsonPath;
137
+ try {
138
+ // https://nodejs.org/api/packages.html#package-entry-points
139
+ // ignore cases where the package entry is exports but package.json is not exported
140
+ packageJsonPath = importResolve(`${dependencyKey}/package.json`, { paths: [baseDir] });
141
+ }
142
+ catch {
143
+ continue;
144
+ }
145
+ const absolutePkgPath = path.dirname(packageJsonPath);
146
+ const realPkgPath = fs.realpathSync(absolutePkgPath);
147
+ try {
148
+ const name = this.readModuleNameSync(realPkgPath);
149
+ ref.push({
150
+ path: realPkgPath,
151
+ name,
152
+ });
153
+ }
154
+ catch {
155
+ continue;
156
+ }
157
+ }
158
+ return ref;
159
+ }
160
+ static resolveModuleDir(moduleDir, baseDir) {
161
+ if (path.isAbsolute(moduleDir)) {
162
+ return moduleDir;
163
+ }
164
+ assert(baseDir, 'baseDir is required');
165
+ return path.join(baseDir, 'config', moduleDir);
166
+ }
167
+ static getModuleName(pkg) {
168
+ assert(pkg.eggModule && pkg.eggModule.name, 'eggModule.name not found in package.json');
169
+ return pkg.eggModule.name;
170
+ }
171
+ static async readModuleName(baseDir, moduleDir) {
172
+ moduleDir = ModuleConfigUtil.resolveModuleDir(moduleDir, baseDir);
173
+ const pkgContent = await fsPromise.readFile(path.join(moduleDir, 'package.json'), 'utf8');
174
+ const pkg = JSON.parse(pkgContent);
175
+ return ModuleConfigUtil.getModuleName(pkg);
176
+ }
177
+ static readModuleNameSync(moduleDir, baseDir) {
178
+ moduleDir = ModuleConfigUtil.resolveModuleDir(moduleDir, baseDir);
179
+ const pkgContent = fs.readFileSync(path.join(moduleDir, 'package.json'), 'utf8');
180
+ const pkg = JSON.parse(pkgContent);
181
+ return ModuleConfigUtil.getModuleName(pkg);
182
+ }
183
+ static async loadModuleConfig(moduleDir, baseDir, env) {
184
+ const modulePath = ModuleConfigUtil.resolveModuleDir(moduleDir, baseDir);
185
+ let configNames;
186
+ if (env) {
187
+ configNames = ['module', `module.${env}`];
188
+ }
189
+ else {
190
+ // assert(ModuleConfigUtil.configNames, 'should setConfigNames before load module config');
191
+ configNames = ModuleConfigUtil.configNames || ['module'];
192
+ }
193
+ const target = {};
194
+ for (const configName of configNames) {
195
+ let config = await ModuleConfigUtil.#loadOne(modulePath, configName);
196
+ // both module.yml and module.default.yml are ok for default config
197
+ if (configName === 'module.default' && !config) {
198
+ config = await ModuleConfigUtil.#loadOne(modulePath, 'module');
199
+ }
200
+ if (config) {
201
+ extend(true, target, config);
202
+ }
203
+ }
204
+ return target;
205
+ }
206
+ static async #loadOne(moduleDir, configName) {
207
+ const yamlConfigPath = path.join(moduleDir, `${configName}.yml`);
208
+ let config = await ModuleConfigUtil.#loadYaml(yamlConfigPath);
209
+ if (!config) {
210
+ const jsonConfigPath = path.join(moduleDir, `${configName}.json`);
211
+ config = await ModuleConfigUtil.#loadJson(jsonConfigPath);
212
+ }
213
+ return config;
214
+ }
215
+ static async #loadJson(moduleJsonPath) {
216
+ const moduleJsonPathExists = await FSUtil.fileExists(moduleJsonPath);
217
+ if (!moduleJsonPathExists) {
218
+ return;
219
+ }
220
+ const moduleJsonContent = await fsPromise.readFile(moduleJsonPath, 'utf8');
221
+ const moduleJson = JSON.parse(moduleJsonContent);
222
+ return moduleJson.config;
223
+ }
224
+ static async #loadYaml(moduleYamlPath) {
225
+ const moduleYamlPathExists = await FSUtil.fileExists(moduleYamlPath);
226
+ if (!moduleYamlPathExists) {
227
+ return;
228
+ }
229
+ const moduleYamlContent = await fsPromise.readFile(moduleYamlPath, 'utf8');
230
+ return yamlLoad(moduleYamlContent);
231
+ }
232
+ static loadModuleConfigSync(moduleDir, baseDir, env) {
233
+ const modulePath = ModuleConfigUtil.resolveModuleDir(moduleDir, baseDir);
234
+ let configNames;
235
+ if (env) {
236
+ configNames = ['module', `module.${env}`];
237
+ }
238
+ else {
239
+ // assert(ModuleConfigUtil.configNames, 'should setConfigNames before load module config');
240
+ configNames = ModuleConfigUtil.configNames || ['module'];
241
+ }
242
+ const target = {};
243
+ for (const configName of configNames) {
244
+ let config = ModuleConfigUtil.#loadOneSync(modulePath, configName);
245
+ // both module.yml and module.default.yml are ok for default config
246
+ if (configName === 'module.default' && !config) {
247
+ config = ModuleConfigUtil.#loadOneSync(modulePath, 'module');
248
+ }
249
+ if (config) {
250
+ extend(true, target, config);
251
+ }
252
+ }
253
+ return target;
254
+ }
255
+ static #loadOneSync(moduleDir, configName) {
256
+ const yamlConfigPath = path.join(moduleDir, `${configName}.yml`);
257
+ let config = ModuleConfigUtil.#loadYamlSync(yamlConfigPath);
258
+ if (!config) {
259
+ const jsonConfigPath = path.join(moduleDir, `${configName}.json`);
260
+ config = ModuleConfigUtil.#loadJsonSync(jsonConfigPath);
261
+ }
262
+ return config;
263
+ }
264
+ static #loadJsonSync(moduleJsonPath) {
265
+ const moduleJsonPathExists = fs.existsSync(moduleJsonPath);
266
+ if (!moduleJsonPathExists) {
267
+ return;
268
+ }
269
+ const moduleJsonContent = fs.readFileSync(moduleJsonPath, 'utf8');
270
+ const moduleJson = JSON.parse(moduleJsonContent);
271
+ return moduleJson.config;
272
+ }
273
+ static #loadYamlSync(moduleYamlPath) {
274
+ const moduleYamlPathExists = fs.existsSync(moduleYamlPath);
275
+ if (!moduleYamlPathExists) {
276
+ return;
277
+ }
278
+ const moduleYamlContent = fs.readFileSync(moduleYamlPath, 'utf8');
279
+ return yamlLoad(moduleYamlContent);
280
+ }
281
+ }
282
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTW9kdWxlQ29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL01vZHVsZUNvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFDakMsT0FBTyxFQUFFLEVBQUUsRUFBRSxRQUFRLElBQUksU0FBUyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ3BELE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUU3QixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDcEMsT0FBTyxFQUFFLElBQUksSUFBSSxRQUFRLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFTM0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUU3QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRXJDLE1BQU0sT0FBTyx5QkFBeUI7SUFDcEMsTUFBTSxDQUFDLHVCQUF1QixDQUFDLGVBQXNDO1FBQ25FLE9BQU8sQ0FBQyxDQUFFLGVBQStDLENBQUMsSUFBSSxDQUFDO0lBQ2pFLENBQUM7SUFFRCxNQUFNLENBQUMsb0JBQW9CLENBQUMsZUFBc0M7UUFDaEUsT0FBTyxDQUFDLENBQUUsZUFBNEMsQ0FBQyxPQUFPLENBQUM7SUFDakUsQ0FBQztDQUNGO0FBRUQsTUFBTSw0QkFBNEIsR0FBRztJQUNuQyxJQUFJLEVBQUUsRUFBRTtDQUNULENBQUM7QUFFRixNQUFNLE9BQU8sZ0JBQWdCO0lBQzNCLE1BQU0sQ0FBQyxXQUFXLENBQXVCO0lBRWxDLE1BQU0sQ0FBQyxjQUFjLENBQUMsV0FBaUM7UUFDNUQsZ0JBQWdCLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztJQUM3QyxDQUFDO0lBRU0sTUFBTSxDQUFDLG1CQUFtQixDQUFDLE9BQWUsRUFBRSxPQUFvQztRQUNyRiwyREFBMkQ7UUFDM0QseUVB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
@@ -4,3 +4,4 @@ export declare class ModuleConfigs {
4
4
  constructor(inner: Record<string, ModuleConfigHolder>);
5
5
  get(moduleName: string): ModuleConfig | undefined;
6
6
  }
7
+ export type { ModuleConfig };