aact 2.1.4 → 3.0.0-beta.2
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/README.md +50 -18
- package/dist/chunks/index.mjs +422 -0
- package/dist/chunks/index2.mjs +248 -0
- package/dist/chunks/index3.mjs +72 -0
- package/dist/cli/index.mjs +312 -542
- package/dist/index.d.mts +520 -229
- package/dist/index.d.ts +520 -229
- package/dist/index.mjs +5 -89
- package/dist/shared/aact.BpV1UCZJ.mjs +3 -0
- package/dist/shared/aact.CfImn7en.mjs +138 -0
- package/dist/shared/aact.CxegP3pU.mjs +900 -0
- package/package.json +44 -14
- package/dist/shared/aact.BzhD7c9t.mjs +0 -884
package/dist/index.mjs
CHANGED
|
@@ -1,92 +1,8 @@
|
|
|
1
|
-
export { A as AactConfigSchema,
|
|
2
|
-
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import YAML from 'yaml';
|
|
1
|
+
export { A as AactConfigSchema, a as aclRule, b as acyclicRule, c as allBoundaries, d as allContainers, e as analyzeArchitecture, f as apiGatewayRule, g as applyEdits, h as canFix, i as canGenerate, j as canLoad, k as cohesionRule, l as commonReuseRule, m as crudRule, n as dbPerServiceRule, o as defineConfig, p as getBoundary, q as getContainer, r as knownFormatNames, s as loadFormat, t as ruleRegistry, u as stableDependenciesRule, v as targetOf, w as walkBoundaries } from './shared/aact.CxegP3pU.mjs';
|
|
2
|
+
export { b as buildModel, i as isDuplicateContainer, v as validateModel } from './shared/aact.CfImn7en.mjs';
|
|
5
3
|
import 'valibot';
|
|
6
|
-
import '
|
|
4
|
+
import 'consola';
|
|
7
5
|
|
|
8
|
-
const
|
|
9
|
-
const DEFAULT_EXCLUDE = ["migrator", "platform", "citest", "tests"];
|
|
10
|
-
const getMicroserviceFilepaths = async (options) => {
|
|
11
|
-
const exclude = options?.exclude ?? DEFAULT_EXCLUDE;
|
|
12
|
-
const resolvedPath = path.resolve(
|
|
13
|
-
process.cwd(),
|
|
14
|
-
options?.path ?? DEFAULT_DEPLOYS_PATH
|
|
15
|
-
);
|
|
16
|
-
const filenames = (await fs.readdir(resolvedPath, "utf8")).filter(
|
|
17
|
-
(filename) => (/* @__PURE__ */ new Set([".yml", ".yaml"])).has(path.extname(filename))
|
|
18
|
-
).filter(
|
|
19
|
-
(filename) => exclude.every((toExclude) => !filename.includes(toExclude))
|
|
20
|
-
);
|
|
21
|
-
return filenames.map((filename) => path.join(resolvedPath, filename));
|
|
22
|
-
};
|
|
23
|
-
const loadMicroserviceDeployConfigs = async (options) => {
|
|
24
|
-
const filepaths = await getMicroserviceFilepaths(options);
|
|
25
|
-
return Promise.all(
|
|
26
|
-
filepaths.map(async (filePath) => {
|
|
27
|
-
const content = await fs.readFile(filePath, "utf8");
|
|
28
|
-
let parsed = YAML.parse(
|
|
29
|
-
content.replaceAll("env:", "environment:")
|
|
30
|
-
);
|
|
31
|
-
if (parsed.microservice) parsed = parsed.microservice;
|
|
32
|
-
parsed.fileName = path.parse(filePath).name;
|
|
33
|
-
return parsed;
|
|
34
|
-
})
|
|
35
|
-
);
|
|
36
|
-
};
|
|
6
|
+
const defineRule = (rule) => rule;
|
|
37
7
|
|
|
38
|
-
|
|
39
|
-
"BASE_URL",
|
|
40
|
-
"PROTOCOL",
|
|
41
|
-
"_TOPIC",
|
|
42
|
-
"__BaseAddress",
|
|
43
|
-
"__Endpoint",
|
|
44
|
-
"__SmtpServer",
|
|
45
|
-
"QueueName"
|
|
46
|
-
];
|
|
47
|
-
const DEFAULT_ENV_CLEANUP = [
|
|
48
|
-
"_BASE_URL",
|
|
49
|
-
"_API",
|
|
50
|
-
"_CLIENT",
|
|
51
|
-
"_PROTOCOL",
|
|
52
|
-
/_KAFKA_(?:[A-Z]+_)+TOPIC/
|
|
53
|
-
];
|
|
54
|
-
const mapFromConfig = (deployConfig, options) => {
|
|
55
|
-
const envWhitelist = options?.envWhitelist ?? DEFAULT_ENV_WHITELIST;
|
|
56
|
-
const envNamePartsToCleanup = options?.envNamePartsToCleanup ?? DEFAULT_ENV_CLEANUP;
|
|
57
|
-
const synonymes = /* @__PURE__ */ new Map([]);
|
|
58
|
-
const environment = deployConfig?.environment ?? {};
|
|
59
|
-
const envKeys = Object.keys(environment);
|
|
60
|
-
const filteredEnvKeys = envKeys.filter(
|
|
61
|
-
(envName) => envWhitelist.some(
|
|
62
|
-
(white) => typeof white === "string" ? envName.includes(white) : white.exec(envName) !== null
|
|
63
|
-
)
|
|
64
|
-
);
|
|
65
|
-
const sections = filteredEnvKeys.map((envName) => {
|
|
66
|
-
const value = environment[envName];
|
|
67
|
-
return {
|
|
68
|
-
prod_value: value?.prod ?? value?.default ?? "",
|
|
69
|
-
name: envNamePartsToCleanup.reduce(
|
|
70
|
-
(acc, partToCleanup) => acc.replace(partToCleanup, ""),
|
|
71
|
-
envName
|
|
72
|
-
)
|
|
73
|
-
};
|
|
74
|
-
}).map((relation) => {
|
|
75
|
-
relation.name = relation.name.toLowerCase();
|
|
76
|
-
for (const entry of synonymes.entries()) {
|
|
77
|
-
if (entry[1].includes(relation.name)) relation.name = entry[0];
|
|
78
|
-
}
|
|
79
|
-
return relation;
|
|
80
|
-
});
|
|
81
|
-
deployConfig.name = (deployConfig.name ?? deployConfig.fileName).replaceAll(
|
|
82
|
-
/[\s\-()]/g,
|
|
83
|
-
"_"
|
|
84
|
-
);
|
|
85
|
-
deployConfig.sections = sections;
|
|
86
|
-
return deployConfig;
|
|
87
|
-
};
|
|
88
|
-
const mapFromConfigs = (deployConfigs, options) => {
|
|
89
|
-
return deployConfigs.map((c) => mapFromConfig(c, options)).sort((a, b) => a.name.localeCompare(b.name));
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
export { loadMicroserviceDeployConfigs, mapFromConfigs };
|
|
8
|
+
export { defineRule };
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
const KNOWN_KINDS = /* @__PURE__ */ new Set([
|
|
2
|
+
"Person",
|
|
3
|
+
"System",
|
|
4
|
+
"Container",
|
|
5
|
+
"ContainerDb",
|
|
6
|
+
"ContainerQueue",
|
|
7
|
+
"Component",
|
|
8
|
+
"ComponentDb",
|
|
9
|
+
"ComponentQueue"
|
|
10
|
+
]);
|
|
11
|
+
const validateModel = (model) => {
|
|
12
|
+
const issues = [];
|
|
13
|
+
for (const container of Object.values(model.containers)) {
|
|
14
|
+
if (!KNOWN_KINDS.has(container.kind)) {
|
|
15
|
+
issues.push({
|
|
16
|
+
kind: "unknown-kind",
|
|
17
|
+
container: container.name,
|
|
18
|
+
raw: container.kind
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
for (const rel of container.relations) {
|
|
22
|
+
if (rel.to === container.name) {
|
|
23
|
+
issues.push({ kind: "self-relation", container: container.name });
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (!(rel.to in model.containers)) {
|
|
27
|
+
issues.push({
|
|
28
|
+
kind: "dangling-relation",
|
|
29
|
+
from: container.name,
|
|
30
|
+
to: rel.to
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
for (const boundary of Object.values(model.boundaries)) {
|
|
36
|
+
for (const containerName of boundary.containerNames) {
|
|
37
|
+
if (!(containerName in model.containers)) {
|
|
38
|
+
issues.push({
|
|
39
|
+
kind: "container-in-boundary-not-in-model",
|
|
40
|
+
container: containerName,
|
|
41
|
+
boundary: boundary.name
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
for (const childName of boundary.boundaryNames) {
|
|
46
|
+
if (!(childName in model.boundaries)) {
|
|
47
|
+
issues.push({
|
|
48
|
+
kind: "boundary-not-in-model",
|
|
49
|
+
parent: boundary.name,
|
|
50
|
+
child: childName
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
detectBoundaryCycles(model, issues);
|
|
56
|
+
return issues;
|
|
57
|
+
};
|
|
58
|
+
const detectBoundaryCycles = (model, issues) => {
|
|
59
|
+
const WHITE = 0;
|
|
60
|
+
const GRAY = 1;
|
|
61
|
+
const BLACK = 2;
|
|
62
|
+
const color = /* @__PURE__ */ new Map();
|
|
63
|
+
const parent = /* @__PURE__ */ new Map();
|
|
64
|
+
const visit = (name) => {
|
|
65
|
+
color.set(name, GRAY);
|
|
66
|
+
const b = model.boundaries[name];
|
|
67
|
+
if (b) {
|
|
68
|
+
for (const child of b.boundaryNames) {
|
|
69
|
+
const c = color.get(child) ?? WHITE;
|
|
70
|
+
if (c === GRAY) {
|
|
71
|
+
const path = [child];
|
|
72
|
+
let cursor = name;
|
|
73
|
+
while (cursor !== void 0 && cursor !== child) {
|
|
74
|
+
path.unshift(cursor);
|
|
75
|
+
cursor = parent.get(cursor);
|
|
76
|
+
}
|
|
77
|
+
if (cursor === child) path.unshift(child);
|
|
78
|
+
return path;
|
|
79
|
+
}
|
|
80
|
+
if (c === WHITE) {
|
|
81
|
+
parent.set(child, name);
|
|
82
|
+
const cyclePath = visit(child);
|
|
83
|
+
if (cyclePath) return cyclePath;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
color.set(name, BLACK);
|
|
88
|
+
return void 0;
|
|
89
|
+
};
|
|
90
|
+
const seenCycles = /* @__PURE__ */ new Set();
|
|
91
|
+
for (const root of Object.keys(model.boundaries)) {
|
|
92
|
+
if ((color.get(root) ?? WHITE) !== WHITE) continue;
|
|
93
|
+
const cyclePath = visit(root);
|
|
94
|
+
if (cyclePath) {
|
|
95
|
+
const sig = [...cyclePath].toSorted((a, b) => a.localeCompare(b)).join(",");
|
|
96
|
+
if (!seenCycles.has(sig)) {
|
|
97
|
+
seenCycles.add(sig);
|
|
98
|
+
issues.push({ kind: "boundary-cycle", path: cyclePath });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
const isDuplicateContainer = (containers, name) => name in containers;
|
|
104
|
+
|
|
105
|
+
const buildModel = (input) => {
|
|
106
|
+
const issues = [...input.preIssues ?? []];
|
|
107
|
+
const containerMap = /* @__PURE__ */ Object.create(null);
|
|
108
|
+
for (const c of [...input.containers].toSorted(
|
|
109
|
+
(a, b) => a.name.localeCompare(b.name)
|
|
110
|
+
)) {
|
|
111
|
+
if (c.name in containerMap) {
|
|
112
|
+
issues.push({ kind: "duplicate-container-name", name: c.name });
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
containerMap[c.name] = c;
|
|
116
|
+
}
|
|
117
|
+
const boundaryMap = /* @__PURE__ */ Object.create(null);
|
|
118
|
+
for (const b of [...input.boundaries].toSorted(
|
|
119
|
+
(x, y) => x.name.localeCompare(y.name)
|
|
120
|
+
)) {
|
|
121
|
+
if (b.name in boundaryMap) {
|
|
122
|
+
issues.push({ kind: "duplicate-boundary-name", name: b.name });
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
boundaryMap[b.name] = b;
|
|
126
|
+
}
|
|
127
|
+
const model = Object.freeze({
|
|
128
|
+
containers: Object.freeze(containerMap),
|
|
129
|
+
boundaries: Object.freeze(boundaryMap),
|
|
130
|
+
rootBoundaryNames: Object.freeze([...input.rootBoundaryNames])
|
|
131
|
+
});
|
|
132
|
+
return {
|
|
133
|
+
model,
|
|
134
|
+
issues: Object.freeze([...issues, ...validateModel(model)])
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export { buildModel as b, isDuplicateContainer as i, validateModel as v };
|