openlore 2.0.3 → 2.0.5
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 +20 -9
- package/dist/cli/commands/analyze.d.ts.map +1 -1
- package/dist/cli/commands/analyze.js +68 -54
- package/dist/cli/commands/analyze.js.map +1 -1
- package/dist/cli/commands/mcp.d.ts.map +1 -1
- package/dist/cli/commands/mcp.js +1 -0
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/orient.d.ts +15 -0
- package/dist/cli/commands/orient.d.ts.map +1 -0
- package/dist/cli/commands/orient.js +156 -0
- package/dist/cli/commands/orient.js.map +1 -0
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/install/index.d.ts +6 -0
- package/dist/cli/install/index.d.ts.map +1 -1
- package/dist/cli/install/index.js +71 -1
- package/dist/cli/install/index.js.map +1 -1
- package/dist/core/analyzer/artifact-generator.d.ts.map +1 -1
- package/dist/core/analyzer/artifact-generator.js +37 -3
- package/dist/core/analyzer/artifact-generator.js.map +1 -1
- package/dist/core/analyzer/call-graph.d.ts +9 -2
- package/dist/core/analyzer/call-graph.d.ts.map +1 -1
- package/dist/core/analyzer/call-graph.js +534 -1
- package/dist/core/analyzer/call-graph.js.map +1 -1
- package/dist/core/analyzer/embedding-service.d.ts +2 -0
- package/dist/core/analyzer/embedding-service.d.ts.map +1 -1
- package/dist/core/analyzer/embedding-service.js +4 -0
- package/dist/core/analyzer/embedding-service.js.map +1 -1
- package/dist/core/analyzer/fixtures/regression/sample.d.ts +9 -0
- package/dist/core/analyzer/fixtures/regression/sample.d.ts.map +1 -0
- package/dist/core/analyzer/fixtures/regression/sample.js +26 -0
- package/dist/core/analyzer/fixtures/regression/sample.js.map +1 -0
- package/dist/core/analyzer/iac/ansible.d.ts +18 -0
- package/dist/core/analyzer/iac/ansible.d.ts.map +1 -0
- package/dist/core/analyzer/iac/ansible.js +219 -0
- package/dist/core/analyzer/iac/ansible.js.map +1 -0
- package/dist/core/analyzer/iac/cdk.d.ts +26 -0
- package/dist/core/analyzer/iac/cdk.d.ts.map +1 -0
- package/dist/core/analyzer/iac/cdk.js +204 -0
- package/dist/core/analyzer/iac/cdk.js.map +1 -0
- package/dist/core/analyzer/iac/classify-yaml.d.ts +20 -0
- package/dist/core/analyzer/iac/classify-yaml.d.ts.map +1 -0
- package/dist/core/analyzer/iac/classify-yaml.js +81 -0
- package/dist/core/analyzer/iac/classify-yaml.js.map +1 -0
- package/dist/core/analyzer/iac/cloudformation.d.ts +15 -0
- package/dist/core/analyzer/iac/cloudformation.d.ts.map +1 -0
- package/dist/core/analyzer/iac/cloudformation.js +189 -0
- package/dist/core/analyzer/iac/cloudformation.js.map +1 -0
- package/dist/core/analyzer/iac/helm.d.ts +20 -0
- package/dist/core/analyzer/iac/helm.d.ts.map +1 -0
- package/dist/core/analyzer/iac/helm.js +229 -0
- package/dist/core/analyzer/iac/helm.js.map +1 -0
- package/dist/core/analyzer/iac/index.d.ts +23 -0
- package/dist/core/analyzer/iac/index.d.ts.map +1 -0
- package/dist/core/analyzer/iac/index.js +40 -0
- package/dist/core/analyzer/iac/index.js.map +1 -0
- package/dist/core/analyzer/iac/kubernetes.d.ts +14 -0
- package/dist/core/analyzer/iac/kubernetes.d.ts.map +1 -0
- package/dist/core/analyzer/iac/kubernetes.js +226 -0
- package/dist/core/analyzer/iac/kubernetes.js.map +1 -0
- package/dist/core/analyzer/iac/project.d.ts +16 -0
- package/dist/core/analyzer/iac/project.d.ts.map +1 -0
- package/dist/core/analyzer/iac/project.js +97 -0
- package/dist/core/analyzer/iac/project.js.map +1 -0
- package/dist/core/analyzer/iac/pulumi.d.ts +21 -0
- package/dist/core/analyzer/iac/pulumi.d.ts.map +1 -0
- package/dist/core/analyzer/iac/pulumi.js +190 -0
- package/dist/core/analyzer/iac/pulumi.js.map +1 -0
- package/dist/core/analyzer/iac/terraform.d.ts +19 -0
- package/dist/core/analyzer/iac/terraform.d.ts.map +1 -0
- package/dist/core/analyzer/iac/terraform.js +546 -0
- package/dist/core/analyzer/iac/terraform.js.map +1 -0
- package/dist/core/analyzer/iac/types.d.ts +67 -0
- package/dist/core/analyzer/iac/types.d.ts.map +1 -0
- package/dist/core/analyzer/iac/types.js +39 -0
- package/dist/core/analyzer/iac/types.js.map +1 -0
- package/dist/core/analyzer/signature-extractor.d.ts +6 -0
- package/dist/core/analyzer/signature-extractor.d.ts.map +1 -1
- package/dist/core/analyzer/signature-extractor.js +112 -2
- package/dist/core/analyzer/signature-extractor.js.map +1 -1
- package/dist/core/analyzer/spec-vector-index.d.ts +9 -2
- package/dist/core/analyzer/spec-vector-index.d.ts.map +1 -1
- package/dist/core/analyzer/spec-vector-index.js +111 -10
- package/dist/core/analyzer/spec-vector-index.js.map +1 -1
- package/dist/core/analyzer/vector-index.d.ts +33 -1
- package/dist/core/analyzer/vector-index.d.ts.map +1 -1
- package/dist/core/analyzer/vector-index.js +99 -10
- package/dist/core/analyzer/vector-index.js.map +1 -1
- package/dist/core/services/edge-store.d.ts +6 -0
- package/dist/core/services/edge-store.d.ts.map +1 -1
- package/dist/core/services/edge-store.js +8 -0
- package/dist/core/services/edge-store.js.map +1 -1
- package/dist/core/services/mcp-handlers/graph.d.ts.map +1 -1
- package/dist/core/services/mcp-handlers/graph.js +12 -0
- package/dist/core/services/mcp-handlers/graph.js.map +1 -1
- package/dist/core/services/mcp-handlers/orient.js +2 -2
- package/dist/core/services/mcp-handlers/orient.js.map +1 -1
- package/dist/core/services/mcp-handlers/semantic.d.ts.map +1 -1
- package/dist/core/services/mcp-handlers/semantic.js +23 -30
- package/dist/core/services/mcp-handlers/semantic.js.map +1 -1
- package/dist/core/services/mcp-watcher.d.ts +9 -0
- package/dist/core/services/mcp-watcher.d.ts.map +1 -1
- package/dist/core/services/mcp-watcher.js +72 -20
- package/dist/core/services/mcp-watcher.js.map +1 -1
- package/package.json +10 -1
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ansible extraction (spec-07).
|
|
3
|
+
*
|
|
4
|
+
* Nodes: plays, named tasks, handlers, roles, role vars/defaults.
|
|
5
|
+
* Edges: notify (task → handler), include_/import_ (tasks/role/playbook → target),
|
|
6
|
+
* play `roles:` (play → role), role meta dependencies (role → role).
|
|
7
|
+
* Jinja2 `{{ }}` in values is tolerated. A templated include target backed by
|
|
8
|
+
* a static `loop`/`with_items` list resolves to each literal item; fully
|
|
9
|
+
* dynamic targets (no static list) are dropped rather than guessed.
|
|
10
|
+
*/
|
|
11
|
+
import { dirname, posix as posixPath } from 'node:path';
|
|
12
|
+
import { parseDocument, LineCounter } from 'yaml';
|
|
13
|
+
import { emptyIacGraph } from './types.js';
|
|
14
|
+
const INCLUDE_TASK_KEYS = ['include_tasks', 'import_tasks', 'ansible.builtin.include_tasks', 'ansible.builtin.import_tasks'];
|
|
15
|
+
const INCLUDE_ROLE_KEYS = ['include_role', 'import_role', 'ansible.builtin.include_role', 'ansible.builtin.import_role'];
|
|
16
|
+
const INCLUDE_PB_KEYS = ['import_playbook', 'ansible.builtin.import_playbook'];
|
|
17
|
+
export function extractAnsible(files) {
|
|
18
|
+
const graph = emptyIacGraph();
|
|
19
|
+
const declared = new Set();
|
|
20
|
+
const pendingRefs = [];
|
|
21
|
+
const addResource = (r) => { declared.add(r.address); graph.resources.push(r); };
|
|
22
|
+
for (const file of files) {
|
|
23
|
+
const posix = file.path.replace(/\\/g, '/');
|
|
24
|
+
const lc = new LineCounter();
|
|
25
|
+
let js;
|
|
26
|
+
try {
|
|
27
|
+
js = parseDocument(file.content, { lineCounter: lc }).toJS();
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const roleMatch = /(^|\/)roles\/([^/]+)\/(tasks|handlers|defaults|vars|meta)\//.exec(posix);
|
|
33
|
+
if (roleMatch) {
|
|
34
|
+
const roleName = roleMatch[2];
|
|
35
|
+
const section = roleMatch[3];
|
|
36
|
+
const roleAddr = `role.${roleName}`;
|
|
37
|
+
if (!declared.has(roleAddr)) {
|
|
38
|
+
addResource({ address: roleAddr, type: 'role', kind: 'role', filePath: file.path, startLine: 1, signature: `role: ${roleName}`, language: 'Ansible' });
|
|
39
|
+
}
|
|
40
|
+
ingestRoleSection(roleName, roleAddr, section, js, file, graph, addResource, pendingRefs);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (isPlaybook(js)) {
|
|
44
|
+
ingestPlaybook(js, file, graph, addResource, pendingRefs);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
// Generic tasks file (included from elsewhere): scope = file path.
|
|
48
|
+
if (Array.isArray(js)) {
|
|
49
|
+
const scope = `tasks:${posix}`;
|
|
50
|
+
addResource({ address: scope, type: 'tasks', kind: 'task', filePath: file.path, startLine: 1, signature: `tasks: ${posix}`, language: 'Ansible' });
|
|
51
|
+
ingestTaskList(js, scope, scope, file, graph, addResource, pendingRefs);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Resolve pending references against declared addresses (drop unresolved).
|
|
55
|
+
for (const ref of pendingRefs) {
|
|
56
|
+
if (declared.has(ref.toAddress) && declared.has(ref.fromAddress)) {
|
|
57
|
+
graph.references.push(ref);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return graph;
|
|
61
|
+
}
|
|
62
|
+
function ingestPlaybook(plays, file, graph, addResource, refs) {
|
|
63
|
+
const posix = file.path.replace(/\\/g, '/');
|
|
64
|
+
plays.forEach((play, idx) => {
|
|
65
|
+
if (!play || typeof play !== 'object')
|
|
66
|
+
return;
|
|
67
|
+
const p = play;
|
|
68
|
+
if (INCLUDE_PB_KEYS.some((k) => k in p)) {
|
|
69
|
+
const target = String(p[INCLUDE_PB_KEYS.find((k) => k in p)]);
|
|
70
|
+
const resolved = resolveRel(file.path, target);
|
|
71
|
+
refs.push({ fromAddress: `playbook:${posix}`, toAddress: `playbook:${resolved}`, kind: 'references' });
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const name = typeof p.name === 'string' ? p.name : `play[${idx}]`;
|
|
75
|
+
const hosts = typeof p.hosts === 'string' ? p.hosts : Array.isArray(p.hosts) ? p.hosts.join(',') : '';
|
|
76
|
+
const playAddr = `play:${posix}#${idx}`;
|
|
77
|
+
addResource({ address: playAddr, type: 'play', kind: 'play', filePath: file.path, startLine: 1, signature: `play: ${name} (hosts: ${hosts})`, language: 'Ansible' });
|
|
78
|
+
// roles: list → role nodes + play→role edges.
|
|
79
|
+
const roles = p.roles;
|
|
80
|
+
if (Array.isArray(roles)) {
|
|
81
|
+
for (const r of roles) {
|
|
82
|
+
const roleName = typeof r === 'string' ? r : (r && typeof r === 'object' ? String(r.role ?? r.name ?? '') : '');
|
|
83
|
+
if (!roleName)
|
|
84
|
+
continue;
|
|
85
|
+
const roleAddr = `role.${roleName}`;
|
|
86
|
+
addResource({ address: roleAddr, type: 'role', kind: 'role', filePath: file.path, startLine: 1, signature: `role: ${roleName}`, language: 'Ansible' });
|
|
87
|
+
refs.push({ fromAddress: playAddr, toAddress: roleAddr, kind: 'references' });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// tasks / pre_tasks / post_tasks share the play scope.
|
|
91
|
+
for (const key of ['pre_tasks', 'tasks', 'post_tasks']) {
|
|
92
|
+
const list = p[key];
|
|
93
|
+
if (Array.isArray(list))
|
|
94
|
+
ingestTaskList(list, playAddr, posix, file, graph, addResource, refs);
|
|
95
|
+
}
|
|
96
|
+
// handlers declared in the play.
|
|
97
|
+
const handlers = p.handlers;
|
|
98
|
+
if (Array.isArray(handlers))
|
|
99
|
+
registerHandlers(handlers, posix, file, addResource);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
function ingestRoleSection(roleName, roleAddr, section, js, file, graph, addResource, refs) {
|
|
103
|
+
if (section === 'handlers' && Array.isArray(js)) {
|
|
104
|
+
registerHandlers(js, roleName, file, addResource);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (section === 'tasks' && Array.isArray(js)) {
|
|
108
|
+
ingestTaskList(js, roleAddr, roleName, file, graph, addResource, refs);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (section === 'meta' && js && typeof js === 'object') {
|
|
112
|
+
const deps = js.dependencies;
|
|
113
|
+
if (Array.isArray(deps)) {
|
|
114
|
+
for (const d of deps) {
|
|
115
|
+
const dep = typeof d === 'string' ? d : (d && typeof d === 'object' ? String(d.role ?? d.name ?? '') : '');
|
|
116
|
+
if (!dep)
|
|
117
|
+
continue;
|
|
118
|
+
const depAddr = `role.${dep}`;
|
|
119
|
+
addResource({ address: depAddr, type: 'role', kind: 'role', filePath: file.path, startLine: 1, signature: `role: ${dep}`, language: 'Ansible' });
|
|
120
|
+
refs.push({ fromAddress: roleAddr, toAddress: depAddr, kind: 'depends_on' });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if ((section === 'vars' || section === 'defaults') && js && typeof js === 'object') {
|
|
126
|
+
for (const key of Object.keys(js)) {
|
|
127
|
+
const addr = `var.${roleName}.${key}`;
|
|
128
|
+
addResource({ address: addr, type: section === 'vars' ? 'var' : 'default', kind: 'value', filePath: file.path, startLine: 1, signature: `${section}: ${key}`, language: 'Ansible' });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function registerHandlers(list, scope, file, addResource) {
|
|
133
|
+
for (const h of list) {
|
|
134
|
+
if (!h || typeof h !== 'object')
|
|
135
|
+
continue;
|
|
136
|
+
const name = h.name;
|
|
137
|
+
if (typeof name !== 'string')
|
|
138
|
+
continue;
|
|
139
|
+
addResource({ address: `handler:${scope}:${name}`, type: 'handler', kind: 'handler', filePath: file.path, startLine: 1, signature: `handler: ${name}`, language: 'Ansible' });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function ingestTaskList(list, fromScope, handlerScope, file, graph, addResource, refs) {
|
|
143
|
+
list.forEach((task, idx) => {
|
|
144
|
+
if (!task || typeof task !== 'object')
|
|
145
|
+
return;
|
|
146
|
+
const t = task;
|
|
147
|
+
// blocks: recurse into block/rescue/always.
|
|
148
|
+
for (const bk of ['block', 'rescue', 'always']) {
|
|
149
|
+
if (Array.isArray(t[bk]))
|
|
150
|
+
ingestTaskList(t[bk], fromScope, handlerScope, file, graph, addResource, refs);
|
|
151
|
+
}
|
|
152
|
+
const name = typeof t.name === 'string' ? t.name : '';
|
|
153
|
+
const taskAddr = name ? `task:${handlerScope}:${name}` : `task:${handlerScope}:#${idx}`;
|
|
154
|
+
if (name) {
|
|
155
|
+
addResource({ address: taskAddr, type: 'task', kind: 'task', filePath: file.path, startLine: 1, signature: `task: ${name}`, language: 'Ansible' });
|
|
156
|
+
}
|
|
157
|
+
const from = name ? taskAddr : fromScope;
|
|
158
|
+
// notify → handler(s) in the same scope.
|
|
159
|
+
const notify = t.notify;
|
|
160
|
+
const notifyList = typeof notify === 'string' ? [notify] : Array.isArray(notify) ? notify.filter((x) => typeof x === 'string') : [];
|
|
161
|
+
for (const handlerName of notifyList) {
|
|
162
|
+
refs.push({ fromAddress: from, toAddress: `handler:${handlerScope}:${handlerName}`, kind: 'references' });
|
|
163
|
+
}
|
|
164
|
+
// include_tasks / import_tasks → tasks file node.
|
|
165
|
+
for (const k of INCLUDE_TASK_KEYS) {
|
|
166
|
+
if (k in t) {
|
|
167
|
+
const target = includeTarget(t[k]);
|
|
168
|
+
if (target && !target.includes('{{')) {
|
|
169
|
+
const resolved = resolveRel(file.path, target);
|
|
170
|
+
refs.push({ fromAddress: from, toAddress: `tasks:${resolved}`, kind: 'references' });
|
|
171
|
+
}
|
|
172
|
+
else if (target && target.includes('{{')) {
|
|
173
|
+
// Templated target backed by a static loop list → resolve each literal.
|
|
174
|
+
for (const item of staticLoopItems(t)) {
|
|
175
|
+
const resolved = resolveRel(file.path, item);
|
|
176
|
+
refs.push({ fromAddress: from, toAddress: `tasks:${resolved}`, kind: 'references' });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// include_role / import_role → role node.
|
|
182
|
+
for (const k of INCLUDE_ROLE_KEYS) {
|
|
183
|
+
if (k in t) {
|
|
184
|
+
const v = t[k];
|
|
185
|
+
const roleName = v && typeof v === 'object' ? String(v.name ?? '') : '';
|
|
186
|
+
if (roleName) {
|
|
187
|
+
const roleAddr = `role.${roleName}`;
|
|
188
|
+
addResource({ address: roleAddr, type: 'role', kind: 'role', filePath: file.path, startLine: 1, signature: `role: ${roleName}`, language: 'Ansible' });
|
|
189
|
+
refs.push({ fromAddress: from, toAddress: roleAddr, kind: 'references' });
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
/** Literal string items from a task's `loop` / `with_items` (skip templated). */
|
|
196
|
+
function staticLoopItems(t) {
|
|
197
|
+
const list = t.loop ?? t.with_items;
|
|
198
|
+
if (!Array.isArray(list))
|
|
199
|
+
return [];
|
|
200
|
+
return list.filter((x) => typeof x === 'string' && !x.includes('{{'));
|
|
201
|
+
}
|
|
202
|
+
function includeTarget(v) {
|
|
203
|
+
if (typeof v === 'string')
|
|
204
|
+
return v;
|
|
205
|
+
if (v && typeof v === 'object') {
|
|
206
|
+
const f = v.file ?? v._raw_params;
|
|
207
|
+
if (typeof f === 'string')
|
|
208
|
+
return f;
|
|
209
|
+
}
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
function resolveRel(fromPath, target) {
|
|
213
|
+
const dir = dirname(fromPath.replace(/\\/g, '/'));
|
|
214
|
+
return posixPath.normalize(posixPath.join(dir, target));
|
|
215
|
+
}
|
|
216
|
+
function isPlaybook(js) {
|
|
217
|
+
return Array.isArray(js) && js.some((x) => x && typeof x === 'object' && ('hosts' in x || 'import_playbook' in x || 'ansible.builtin.import_playbook' in x));
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=ansible.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ansible.js","sourceRoot":"","sources":["../../../../src/core/analyzer/iac/ansible.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS CDK + CDKTF framework detector (spec-07).
|
|
3
|
+
*
|
|
4
|
+
* Like Pulumi, CDK and CDKTF programs are ordinary TS/JS/Python/Go that
|
|
5
|
+
* construct resources — already parsed for the call graph. We recognize the
|
|
6
|
+
* construct instantiations and emit extra `CDK` / `CDKTF` resource nodes +
|
|
7
|
+
* reference edges, leaving the normal call graph untouched.
|
|
8
|
+
*
|
|
9
|
+
* The distinguishing shape: a construct's **first** argument is the scope
|
|
10
|
+
* (`this`/`self`/an identifier) and the **second** argument is the logical id
|
|
11
|
+
* string — `new s3.Bucket(this, "MyBucket", { … })`. (Pulumi puts the name
|
|
12
|
+
* first.) We never synthesize CFN/Terraform; this is static detection only.
|
|
13
|
+
*
|
|
14
|
+
* Scope conservatively: a construction is only recognized when its root
|
|
15
|
+
* identifier is bound to a CDK (`aws-cdk-lib`, `@aws-cdk/*`, `aws_cdk`) or
|
|
16
|
+
* CDKTF (`cdktf`, `@cdktf/*`) import. Unknown roots → no nodes.
|
|
17
|
+
*/
|
|
18
|
+
import type { IacGraph } from './types.js';
|
|
19
|
+
interface InFile {
|
|
20
|
+
path: string;
|
|
21
|
+
content: string;
|
|
22
|
+
language: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function extractCdk(files: InFile[]): IacGraph;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=cdk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdk.d.ts","sourceRoot":"","sources":["../../../../src/core/analyzer/iac/cdk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAA4B,MAAM,YAAY,CAAC;AAGrE,UAAU,MAAM;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;AAcpE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,QAAQ,CAYpD"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS CDK + CDKTF framework detector (spec-07).
|
|
3
|
+
*
|
|
4
|
+
* Like Pulumi, CDK and CDKTF programs are ordinary TS/JS/Python/Go that
|
|
5
|
+
* construct resources — already parsed for the call graph. We recognize the
|
|
6
|
+
* construct instantiations and emit extra `CDK` / `CDKTF` resource nodes +
|
|
7
|
+
* reference edges, leaving the normal call graph untouched.
|
|
8
|
+
*
|
|
9
|
+
* The distinguishing shape: a construct's **first** argument is the scope
|
|
10
|
+
* (`this`/`self`/an identifier) and the **second** argument is the logical id
|
|
11
|
+
* string — `new s3.Bucket(this, "MyBucket", { … })`. (Pulumi puts the name
|
|
12
|
+
* first.) We never synthesize CFN/Terraform; this is static detection only.
|
|
13
|
+
*
|
|
14
|
+
* Scope conservatively: a construction is only recognized when its root
|
|
15
|
+
* identifier is bound to a CDK (`aws-cdk-lib`, `@aws-cdk/*`, `aws_cdk`) or
|
|
16
|
+
* CDKTF (`cdktf`, `@cdktf/*`) import. Unknown roots → no nodes.
|
|
17
|
+
*/
|
|
18
|
+
import { emptyIacGraph } from './types.js';
|
|
19
|
+
export function extractCdk(files) {
|
|
20
|
+
const graph = emptyIacGraph();
|
|
21
|
+
for (const file of files) {
|
|
22
|
+
if (file.language === 'TypeScript' || file.language === 'JavaScript') {
|
|
23
|
+
ingest(file, detectTsNames(file.content), 'ts', graph);
|
|
24
|
+
}
|
|
25
|
+
else if (file.language === 'Python') {
|
|
26
|
+
ingest(file, detectPyNames(file.content), 'py', graph);
|
|
27
|
+
}
|
|
28
|
+
else if (file.language === 'Go') {
|
|
29
|
+
ingest(file, detectGoNames(file.content), 'go', graph);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return graph;
|
|
33
|
+
}
|
|
34
|
+
function ingest(file, names, syntax, graph) {
|
|
35
|
+
if (names.size === 0)
|
|
36
|
+
return;
|
|
37
|
+
const constructions = findConstructions(file.content, names, syntax);
|
|
38
|
+
const byVar = new Map();
|
|
39
|
+
for (const c of constructions)
|
|
40
|
+
if (c.varName)
|
|
41
|
+
byVar.set(c.varName, c.address);
|
|
42
|
+
for (const c of constructions) {
|
|
43
|
+
const r = {
|
|
44
|
+
address: c.address, type: c.service, kind: 'resource', filePath: file.path,
|
|
45
|
+
startLine: c.line, signature: `${c.flavor}: ${c.service}("${c.id}")`, language: c.flavor,
|
|
46
|
+
};
|
|
47
|
+
graph.resources.push(r);
|
|
48
|
+
}
|
|
49
|
+
for (const c of constructions) {
|
|
50
|
+
const seen = new Set();
|
|
51
|
+
for (const tok of c.argsText.matchAll(/\b([A-Za-z_]\w*)\b/g)) {
|
|
52
|
+
const target = byVar.get(tok[1]);
|
|
53
|
+
if (target && target !== c.address && !seen.has(target)) {
|
|
54
|
+
seen.add(target);
|
|
55
|
+
graph.references.push({ fromAddress: c.address, toAddress: target, kind: 'references', line: c.line });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function findConstructions(content, names, syntax) {
|
|
61
|
+
const out = [];
|
|
62
|
+
// Second positional arg is the logical id. Go ids may be wrapped: jsii.String("id").
|
|
63
|
+
const idArg = syntax === 'go' ? `(?:jsii\\.String\\(\\s*)?["']([^"']+)["']` : `["']([^"']+)["']`;
|
|
64
|
+
const re = syntax === 'ts'
|
|
65
|
+
? new RegExp(`(?:(?:const|let|var)\\s+(\\w+)\\s*=\\s*)?new\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)\\s*\\(\\s*[^,()\\n]+?,\\s*${idArg}`, 'g')
|
|
66
|
+
: syntax === 'py'
|
|
67
|
+
? new RegExp(`(?:(\\w+)\\s*=\\s*)?([A-Za-z_]\\w*(?:\\.\\w+)*)\\s*\\(\\s*[^,()\\n]+?,\\s*${idArg}`, 'g')
|
|
68
|
+
: new RegExp(`(?:(\\w+)\\s*(?:,\\s*\\w+\\s*)?:?=\\s*)?([A-Za-z_]\\w*(?:\\.\\w+)*)\\s*\\(\\s*[^,()\\n]+?,\\s*${idArg}`, 'g');
|
|
69
|
+
for (const m of content.matchAll(re)) {
|
|
70
|
+
const varName = m[1];
|
|
71
|
+
let dotted = m[2];
|
|
72
|
+
const id = m[3];
|
|
73
|
+
// Go constructors are `pkg.NewService` → strip the `New` prefix.
|
|
74
|
+
const segs = dotted.split('.');
|
|
75
|
+
if (syntax === 'go') {
|
|
76
|
+
const last = segs[segs.length - 1];
|
|
77
|
+
if (!last.startsWith('New'))
|
|
78
|
+
continue;
|
|
79
|
+
segs[segs.length - 1] = last.slice(3);
|
|
80
|
+
dotted = segs.join('.');
|
|
81
|
+
}
|
|
82
|
+
const root = segs[0];
|
|
83
|
+
const service = segs[segs.length - 1];
|
|
84
|
+
const flavor = names.get(root);
|
|
85
|
+
if (!flavor)
|
|
86
|
+
continue;
|
|
87
|
+
if (!/^[A-Z]/.test(service))
|
|
88
|
+
continue;
|
|
89
|
+
const callParen = (m.index ?? 0) + m[0].indexOf('(');
|
|
90
|
+
out.push({
|
|
91
|
+
address: `${service}:${id}`, service, id, flavor,
|
|
92
|
+
line: lineOf(content, m.index ?? 0), varName, argsText: sliceArgs(content, callParen),
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
const CDK_TS = ['aws-cdk-lib', '@aws-cdk/'];
|
|
98
|
+
const CDKTF_TS = ['cdktf', '@cdktf/'];
|
|
99
|
+
/** Local names bound to a CDK/CDKTF import (TS/JS). */
|
|
100
|
+
function detectTsNames(content) {
|
|
101
|
+
const names = new Map();
|
|
102
|
+
const add = (n, f) => { if (n)
|
|
103
|
+
names.set(n.trim(), f); };
|
|
104
|
+
for (const m of content.matchAll(/import\s+(?:\*\s+as\s+)?(\w+)\s+from\s+["']([^"']+)["']/g)) {
|
|
105
|
+
const flavor = flavorOf(m[2]);
|
|
106
|
+
if (flavor)
|
|
107
|
+
add(m[1], flavor);
|
|
108
|
+
}
|
|
109
|
+
for (const m of content.matchAll(/import\s+\{([^}]+)\}\s+from\s+["']([^"']+)["']/g)) {
|
|
110
|
+
const flavor = flavorOf(m[2]);
|
|
111
|
+
if (!flavor)
|
|
112
|
+
continue;
|
|
113
|
+
for (const part of m[1].split(',')) {
|
|
114
|
+
const n = (part.match(/\bas\s+(\w+)/) ?? part.match(/(\w+)/))?.[1];
|
|
115
|
+
add(n, flavor);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
for (const m of content.matchAll(/(\w+)\s*=\s*require\(\s*["']([^"']+)["']/g)) {
|
|
119
|
+
const flavor = flavorOf(m[2]);
|
|
120
|
+
if (flavor)
|
|
121
|
+
add(m[1], flavor);
|
|
122
|
+
}
|
|
123
|
+
return names;
|
|
124
|
+
function flavorOf(src) {
|
|
125
|
+
if (CDKTF_TS.some((p) => src === p || src.startsWith(p)))
|
|
126
|
+
return 'CDKTF';
|
|
127
|
+
if (CDK_TS.some((p) => src === p || src.startsWith(p)))
|
|
128
|
+
return 'CDK';
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/** Local names bound to a CDK/CDKTF import (Python). */
|
|
133
|
+
function detectPyNames(content) {
|
|
134
|
+
const names = new Map();
|
|
135
|
+
const add = (n, f) => { if (n)
|
|
136
|
+
names.set(n.trim(), f); };
|
|
137
|
+
// import aws_cdk.aws_s3 as s3 / import cdktf as cdktf
|
|
138
|
+
for (const m of content.matchAll(/import\s+([\w.]+)(?:\s+as\s+(\w+))?/g)) {
|
|
139
|
+
const flavor = pyFlavor(m[1]);
|
|
140
|
+
if (!flavor)
|
|
141
|
+
continue;
|
|
142
|
+
add(m[2] ?? m[1].split('.').pop(), flavor);
|
|
143
|
+
}
|
|
144
|
+
// from aws_cdk import aws_s3 as s3, Stack
|
|
145
|
+
for (const m of content.matchAll(/from\s+([\w.]+)\s+import\s+([^\n#]+)/g)) {
|
|
146
|
+
const flavor = pyFlavor(m[1]);
|
|
147
|
+
if (!flavor)
|
|
148
|
+
continue;
|
|
149
|
+
for (const part of m[2].split(',')) {
|
|
150
|
+
const n = (part.match(/\bas\s+(\w+)/) ?? part.match(/(\w+)/))?.[1];
|
|
151
|
+
add(n, flavor);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return names;
|
|
155
|
+
function pyFlavor(mod) {
|
|
156
|
+
if (mod === 'cdktf' || mod.startsWith('cdktf_') || mod.startsWith('cdktf.'))
|
|
157
|
+
return 'CDKTF';
|
|
158
|
+
if (mod === 'aws_cdk' || mod.startsWith('aws_cdk.') || mod.startsWith('aws_cdk_'))
|
|
159
|
+
return 'CDK';
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/** Go package local names bound to a CDK/CDKTF import path. */
|
|
164
|
+
function detectGoNames(content) {
|
|
165
|
+
const names = new Map();
|
|
166
|
+
for (const m of content.matchAll(/(?:(\w+)\s+)?"([^"]+)"/g)) {
|
|
167
|
+
const alias = m[1];
|
|
168
|
+
const path = m[2];
|
|
169
|
+
let flavor = null;
|
|
170
|
+
if (path.includes('hashicorp/terraform-cdk-go/cdktf') || path.includes('cdktf/cdktf-provider'))
|
|
171
|
+
flavor = 'CDKTF';
|
|
172
|
+
else if (path.includes('aws/aws-cdk-go/awscdk') || path.includes('aws/constructs-go'))
|
|
173
|
+
flavor = 'CDK';
|
|
174
|
+
if (!flavor)
|
|
175
|
+
continue;
|
|
176
|
+
names.set(alias ?? path.split('/').pop(), flavor);
|
|
177
|
+
}
|
|
178
|
+
return names;
|
|
179
|
+
}
|
|
180
|
+
function sliceArgs(content, parenIndex) {
|
|
181
|
+
let depth = 0;
|
|
182
|
+
let i = parenIndex;
|
|
183
|
+
for (; i < content.length; i++) {
|
|
184
|
+
const c = content[i];
|
|
185
|
+
if (c === '(')
|
|
186
|
+
depth++;
|
|
187
|
+
else if (c === ')') {
|
|
188
|
+
depth--;
|
|
189
|
+
if (depth === 0) {
|
|
190
|
+
i++;
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return content.slice(parenIndex, i);
|
|
196
|
+
}
|
|
197
|
+
function lineOf(content, index) {
|
|
198
|
+
let n = 1;
|
|
199
|
+
for (let i = 0; i < index && i < content.length; i++)
|
|
200
|
+
if (content[i] === '\n')
|
|
201
|
+
n++;
|
|
202
|
+
return n;
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=cdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdk.js","sourceRoot":"","sources":["../../../../src/core/analyzer/iac/cdk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAgB3C,MAAM,UAAU,UAAU,CAAC,KAAe;IACxC,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,QAAQ,KAAK,YAAY,IAAI,IAAI,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;YACrE,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QACzD,CAAC;aAAM,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACtC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QACzD,CAAC;aAAM,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,MAAM,CAAC,IAAY,EAAE,KAA0B,EAAE,MAA0B,EAAE,KAAe;IACnG,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO;IAC7B,MAAM,aAAa,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACrE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,aAAa;QAAE,IAAI,CAAC,CAAC,OAAO;YAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IAE9E,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAgB;YACrB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI;YAC1E,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAqB;SACxG,CAAC;QACF,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;YAC7D,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACjC,IAAI,MAAM,IAAI,MAAM,KAAK,CAAC,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACjB,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACzG,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAe,EAAE,KAA0B,EAAE,MAA0B;IAChG,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,qFAAqF;IACrF,MAAM,KAAK,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,2CAA2C,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACjG,MAAM,EAAE,GAAG,MAAM,KAAK,IAAI;QACxB,CAAC,CAAC,IAAI,MAAM,CAAC,yGAAyG,KAAK,EAAE,EAAE,GAAG,CAAC;QACnI,CAAC,CAAC,MAAM,KAAK,IAAI;YACf,CAAC,CAAC,IAAI,MAAM,CAAC,6EAA6E,KAAK,EAAE,EAAE,GAAG,CAAC;YACvG,CAAC,CAAC,IAAI,MAAM,CAAC,iGAAiG,KAAK,EAAE,EAAE,GAAG,CAAC,CAAC;IAEhI,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClB,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAChB,iEAAiE;QACjE,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACnC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;gBAAE,SAAS;YACtC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACtC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,SAAS;QACtC,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACrD,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,GAAG,OAAO,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM;YAChD,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC;SACtF,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;AAC5C,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AAEtC,uDAAuD;AACvD,SAAS,aAAa,CAAC,OAAe;IACpC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,MAAM,GAAG,GAAG,CAAC,CAAqB,EAAE,CAAS,EAAE,EAAE,GAAG,IAAI,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrF,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,0DAA0D,CAAC,EAAE,CAAC;QAC7F,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,IAAI,MAAM;YAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,iDAAiD,CAAC,EAAE,CAAC;QACpF,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,IAAI,CAAC,MAAM;YAAE,SAAS;QACrD,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACnE,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,2CAA2C,CAAC,EAAE,CAAC;QAC9E,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,IAAI,MAAM;YAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,KAAK,CAAC;IAEb,SAAS,QAAQ,CAAC,GAAW;QAC3B,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,OAAO,CAAC;QACzE,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,wDAAwD;AACxD,SAAS,aAAa,CAAC,OAAe;IACpC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,MAAM,GAAG,GAAG,CAAC,CAAqB,EAAE,CAAS,EAAE,EAAE,GAAG,IAAI,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrF,wDAAwD;IACxD,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,sCAAsC,CAAC,EAAE,CAAC;QACzE,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,IAAI,CAAC,MAAM;YAAE,SAAS;QACrD,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IACD,0CAA0C;IAC1C,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,uCAAuC,CAAC,EAAE,CAAC;QAC1E,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,IAAI,CAAC,MAAM;YAAE,SAAS;QACrD,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACnE,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;IAEb,SAAS,QAAQ,CAAC,GAAW;QAC3B,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,OAAO,CAAC;QAC5F,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,OAAO,KAAK,CAAC;QAChG,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,+DAA+D;AAC/D,SAAS,aAAa,CAAC,OAAe;IACpC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,CAAC;QAC5D,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACnB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,MAAM,GAAkB,IAAI,CAAC;QACjC,IAAI,IAAI,CAAC,QAAQ,CAAC,kCAAkC,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,sBAAsB,CAAC;YAAE,MAAM,GAAG,OAAO,CAAC;aAC5G,IAAI,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YAAE,MAAM,GAAG,KAAK,CAAC;QACtG,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG,EAAE,MAAM,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,SAAS,CAAC,OAAe,EAAE,UAAkB;IACpD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,CAAC,GAAG,UAAU,CAAC;IACnB,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG;YAAE,KAAK,EAAE,CAAC;aAClB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YAAC,KAAK,EAAE,CAAC;YAAC,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBAAC,CAAC,EAAE,CAAC;gBAAC,MAAM;YAAC,CAAC;QAAC,CAAC;IACnE,CAAC;IACD,OAAO,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,MAAM,CAAC,OAAe,EAAE,KAAa;IAC5C,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI;YAAE,CAAC,EAAE,CAAC;IACnF,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content-based disambiguation for ambiguous IaC file extensions (spec-07).
|
|
3
|
+
*
|
|
4
|
+
* `.yaml`/`.yml`/`.json` are used by Kubernetes, CloudFormation, Helm, Ansible,
|
|
5
|
+
* and plain config alike. `detectLanguage` can only see the extension, so it
|
|
6
|
+
* routes these through `classifyYaml`, a small pure function that inspects path
|
|
7
|
+
* + content. When unsure, return `null` (→ `unknown`): never force a
|
|
8
|
+
* classification onto generic YAML (CI configs, docker-compose, app config).
|
|
9
|
+
*/
|
|
10
|
+
import type { IacLanguage } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Classify an ambiguous `.yaml`/`.yml`/`.json` file by its path + content.
|
|
13
|
+
* Returns the IaC language, or `null` when the file is not recognizably IaC.
|
|
14
|
+
*
|
|
15
|
+
* Note: Helm chart membership that depends on an ancestor `Chart.yaml` is
|
|
16
|
+
* resolved by the caller (it needs the file set); here we only catch the
|
|
17
|
+
* unambiguous Helm signal of a `{{ … }}` template under a `templates/` dir.
|
|
18
|
+
*/
|
|
19
|
+
export declare function classifyYaml(path: string, content: string): IacLanguage | null;
|
|
20
|
+
//# sourceMappingURL=classify-yaml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify-yaml.d.ts","sourceRoot":"","sources":["../../../../src/core/analyzer/iac/classify-yaml.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CA4B9E"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content-based disambiguation for ambiguous IaC file extensions (spec-07).
|
|
3
|
+
*
|
|
4
|
+
* `.yaml`/`.yml`/`.json` are used by Kubernetes, CloudFormation, Helm, Ansible,
|
|
5
|
+
* and plain config alike. `detectLanguage` can only see the extension, so it
|
|
6
|
+
* routes these through `classifyYaml`, a small pure function that inspects path
|
|
7
|
+
* + content. When unsure, return `null` (→ `unknown`): never force a
|
|
8
|
+
* classification onto generic YAML (CI configs, docker-compose, app config).
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Classify an ambiguous `.yaml`/`.yml`/`.json` file by its path + content.
|
|
12
|
+
* Returns the IaC language, or `null` when the file is not recognizably IaC.
|
|
13
|
+
*
|
|
14
|
+
* Note: Helm chart membership that depends on an ancestor `Chart.yaml` is
|
|
15
|
+
* resolved by the caller (it needs the file set); here we only catch the
|
|
16
|
+
* unambiguous Helm signal of a `{{ … }}` template under a `templates/` dir.
|
|
17
|
+
*/
|
|
18
|
+
export function classifyYaml(path, content) {
|
|
19
|
+
const posix = path.replace(/\\/g, '/');
|
|
20
|
+
const lower = posix.toLowerCase();
|
|
21
|
+
const fileName = posix.split('/').pop() ?? '';
|
|
22
|
+
// Helm chart metadata files (unambiguous by name).
|
|
23
|
+
if (fileName === 'Chart.yaml' || fileName === 'Chart.yml')
|
|
24
|
+
return 'Helm';
|
|
25
|
+
// Helm template: a Go-template expression inside a templates/ directory.
|
|
26
|
+
const inTemplatesDir = /(^|\/)templates\//.test(posix);
|
|
27
|
+
if (inTemplatesDir && /\{\{[-\s]/.test(content))
|
|
28
|
+
return 'Helm';
|
|
29
|
+
// CloudFormation / SAM — explicit format markers.
|
|
30
|
+
if (/(^|\n)\s*AWSTemplateFormatVersion\s*:/.test(content) ||
|
|
31
|
+
/(^|\n)\s*Transform\s*:\s*['"]?AWS::Serverless/.test(content) ||
|
|
32
|
+
isCloudFormationResources(content)) {
|
|
33
|
+
return 'CloudFormation';
|
|
34
|
+
}
|
|
35
|
+
// Kubernetes — apiVersion + kind at (near) the top level of a document.
|
|
36
|
+
if (isKubernetesManifest(content))
|
|
37
|
+
return 'Kubernetes';
|
|
38
|
+
// Ansible — playbook (top-level hosts/tasks/roles) or role-tree location.
|
|
39
|
+
if (isAnsiblePath(lower) || isAnsiblePlaybook(content))
|
|
40
|
+
return 'Ansible';
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
/** `Resources:` block whose entries carry `Type: AWS::…` (CFN without the header). */
|
|
44
|
+
function isCloudFormationResources(content) {
|
|
45
|
+
if (!/(^|\n)Resources\s*:/.test(content))
|
|
46
|
+
return false;
|
|
47
|
+
return /(^|\n)\s+Type\s*:\s*['"]?(AWS|Alexa|Custom)::/.test(content);
|
|
48
|
+
}
|
|
49
|
+
/** Any YAML document declaring both `apiVersion:` and `kind:`. */
|
|
50
|
+
function isKubernetesManifest(content) {
|
|
51
|
+
// Inspect each `---`-separated document; K8s objects pair apiVersion + kind.
|
|
52
|
+
for (const doc of content.split(/^---\s*$/m)) {
|
|
53
|
+
const hasApiVersion = /(^|\n)\s*apiVersion\s*:/.test(doc);
|
|
54
|
+
const hasKind = /(^|\n)\s*kind\s*:/.test(doc);
|
|
55
|
+
if (hasApiVersion && hasKind)
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
/** Located under an Ansible role tree (`roles/<name>/{tasks,handlers,...}/`). */
|
|
61
|
+
function isAnsiblePath(lowerPath) {
|
|
62
|
+
return /(^|\/)roles\/[^/]+\/(tasks|handlers|defaults|vars|meta)\//.test(lowerPath);
|
|
63
|
+
}
|
|
64
|
+
/** Top-level playbook markers: a list of plays with hosts/tasks/roles. */
|
|
65
|
+
function isAnsiblePlaybook(content) {
|
|
66
|
+
// Playbooks are a top-level list; plays declare `hosts:` and usually
|
|
67
|
+
// `tasks:`/`roles:`. Match a `- hosts:` item or a top-level tasks/handlers file.
|
|
68
|
+
if (/(^|\n)\s*-\s+hosts\s*:/.test(content))
|
|
69
|
+
return true;
|
|
70
|
+
// A list whose play items carry a `hosts:` key (possibly after `- name:`).
|
|
71
|
+
if (/(^|\n)\s*-\s/.test(content) && /(^|\n)\s+hosts\s*:/.test(content))
|
|
72
|
+
return true;
|
|
73
|
+
// tasks/handlers main.yml in a role: a top-level list whose items have `name:`
|
|
74
|
+
// plus a module key — too weak alone, so require an Ansible-specific keyword.
|
|
75
|
+
if (/(^|\n)\s*-\s+(name|block|include_tasks|import_tasks|ansible\.builtin)\s*:/.test(content)) {
|
|
76
|
+
return /(^|\n)\s*(notify|register|when|loop|with_items|become|ansible\.builtin\.)\s*:/.test(content)
|
|
77
|
+
|| /(^|\n)\s*-\s+(include_tasks|import_tasks|ansible\.builtin\.)/.test(content);
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=classify-yaml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify-yaml.js","sourceRoot":"","sources":["../../../../src/core/analyzer/iac/classify-yaml.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,OAAe;IACxD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IAE9C,mDAAmD;IACnD,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,WAAW;QAAE,OAAO,MAAM,CAAC;IAEzE,yEAAyE;IACzE,MAAM,cAAc,GAAG,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvD,IAAI,cAAc,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,MAAM,CAAC;IAE/D,kDAAkD;IAClD,IACE,uCAAuC,CAAC,IAAI,CAAC,OAAO,CAAC;QACrD,+CAA+C,CAAC,IAAI,CAAC,OAAO,CAAC;QAC7D,yBAAyB,CAAC,OAAO,CAAC,EAClC,CAAC;QACD,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,wEAAwE;IACxE,IAAI,oBAAoB,CAAC,OAAO,CAAC;QAAE,OAAO,YAAY,CAAC;IAEvD,0EAA0E;IAC1E,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IAEzE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,sFAAsF;AACtF,SAAS,yBAAyB,CAAC,OAAe;IAChD,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IACvD,OAAO,+CAA+C,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACvE,CAAC;AAED,kEAAkE;AAClE,SAAS,oBAAoB,CAAC,OAAe;IAC3C,6EAA6E;IAC7E,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7C,MAAM,aAAa,GAAG,yBAAyB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,aAAa,IAAI,OAAO;YAAE,OAAO,IAAI,CAAC;IAC5C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,iFAAiF;AACjF,SAAS,aAAa,CAAC,SAAiB;IACtC,OAAO,2DAA2D,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACrF,CAAC;AAED,0EAA0E;AAC1E,SAAS,iBAAiB,CAAC,OAAe;IACxC,qEAAqE;IACrE,iFAAiF;IACjF,IAAI,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACxD,2EAA2E;IAC3E,IAAI,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACpF,+EAA+E;IAC/E,8EAA8E;IAC9E,IAAI,2EAA2E,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9F,OAAO,+EAA+E,CAAC,IAAI,CAAC,OAAO,CAAC;eAC/F,8DAA8D,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CloudFormation / SAM extraction (spec-07).
|
|
3
|
+
*
|
|
4
|
+
* Handles JSON and YAML, including the short-form intrinsics (`!Ref`,
|
|
5
|
+
* `!GetAtt`, `!Sub`, …) via a CFN-aware custom-tag set so the `yaml` parser
|
|
6
|
+
* does not choke. Edges: Ref, Fn::GetAtt, Fn::Sub ${var}, DependsOn,
|
|
7
|
+
* Fn::ImportValue (cross-stack → external), nested stacks (TemplateURL).
|
|
8
|
+
* Pseudo-parameters (AWS::Region, …) are ignored as builtins.
|
|
9
|
+
*/
|
|
10
|
+
import type { IacGraph } from './types.js';
|
|
11
|
+
export declare function extractCloudFormation(files: Array<{
|
|
12
|
+
path: string;
|
|
13
|
+
content: string;
|
|
14
|
+
}>): IacGraph;
|
|
15
|
+
//# sourceMappingURL=cloudformation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudformation.d.ts","sourceRoot":"","sources":["../../../../src/core/analyzer/iac/cloudformation.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAA6B,MAAM,YAAY,CAAC;AA4BtE,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GAC9C,QAAQ,CAeV"}
|