103 lines
2.8 KiB
JavaScript
103 lines
2.8 KiB
JavaScript
|
|
const fs = require('fs');
|
||
|
|
const path = require('path');
|
||
|
|
const jsYaml = require('js-yaml');
|
||
|
|
|
||
|
|
function extractYaml(filePath, repoRoot) {
|
||
|
|
const sourceCode = fs.readFileSync(filePath, 'utf8');
|
||
|
|
const relPath = path.relative(repoRoot, filePath);
|
||
|
|
const moduleId = relPath;
|
||
|
|
const entities = [];
|
||
|
|
const relationships = [];
|
||
|
|
|
||
|
|
entities.push({
|
||
|
|
id: moduleId,
|
||
|
|
type: 'Config',
|
||
|
|
name: relPath,
|
||
|
|
kind: 'yaml-config',
|
||
|
|
visibility: 'public',
|
||
|
|
line_range: [1, sourceCode.split('\n').length]
|
||
|
|
});
|
||
|
|
|
||
|
|
try {
|
||
|
|
// Attempt to load multiple documents
|
||
|
|
const docs = jsYaml.loadAll(sourceCode);
|
||
|
|
let lineNum = 1;
|
||
|
|
for (const doc of docs) {
|
||
|
|
if (doc && typeof doc === 'object') {
|
||
|
|
for (const key of Object.keys(doc)) {
|
||
|
|
const keyId = `${moduleId}:${key}`;
|
||
|
|
entities.push({
|
||
|
|
id: keyId,
|
||
|
|
type: 'Config',
|
||
|
|
name: key,
|
||
|
|
kind: 'yaml-key',
|
||
|
|
visibility: 'public',
|
||
|
|
line_range: [lineNum, lineNum] // Approximation without AST
|
||
|
|
});
|
||
|
|
relationships.push({
|
||
|
|
type: 'CONTAINS',
|
||
|
|
source: moduleId,
|
||
|
|
target: keyId
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch (e) {
|
||
|
|
// Log warning, return base module
|
||
|
|
console.error(`YAML parse error in ${relPath}: ${e.message}`);
|
||
|
|
}
|
||
|
|
|
||
|
|
return { file: filePath, language: 'yaml', entities, relationships };
|
||
|
|
}
|
||
|
|
|
||
|
|
function extractHcl(filePath, repoRoot) {
|
||
|
|
const sourceCode = fs.readFileSync(filePath, 'utf8');
|
||
|
|
const relPath = path.relative(repoRoot, filePath);
|
||
|
|
const moduleId = relPath;
|
||
|
|
const entities = [];
|
||
|
|
const relationships = [];
|
||
|
|
const lines = sourceCode.split('\n');
|
||
|
|
|
||
|
|
entities.push({
|
||
|
|
id: moduleId,
|
||
|
|
type: 'Config',
|
||
|
|
name: relPath,
|
||
|
|
kind: 'terraform',
|
||
|
|
visibility: 'public',
|
||
|
|
line_range: [1, lines.length]
|
||
|
|
});
|
||
|
|
|
||
|
|
// Regex for top-level HCL blocks (e.g., resource "aws_s3_bucket" "my_bucket" {)
|
||
|
|
const blockRegex = /^(resource|data|module|variable|output|provider)\s+"([^"]+)"(?:\s+"([^"]+)")?\s*\{/;
|
||
|
|
|
||
|
|
for (let i = 0; i < lines.length; i++) {
|
||
|
|
const match = lines[i].match(blockRegex);
|
||
|
|
if (match) {
|
||
|
|
const type = match[1];
|
||
|
|
const name1 = match[2];
|
||
|
|
const name2 = match[3];
|
||
|
|
const fullName = name2 ? `${type}.${name1}.${name2}` : `${type}.${name1}`;
|
||
|
|
const blockId = `${moduleId}:${fullName}`;
|
||
|
|
|
||
|
|
entities.push({
|
||
|
|
id: blockId,
|
||
|
|
type: 'Config',
|
||
|
|
name: fullName,
|
||
|
|
kind: 'hcl-block',
|
||
|
|
visibility: 'public',
|
||
|
|
line_range: [i + 1, i + 1] // Approximation
|
||
|
|
});
|
||
|
|
|
||
|
|
relationships.push({
|
||
|
|
type: 'CONTAINS',
|
||
|
|
source: moduleId,
|
||
|
|
target: blockId
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return { file: filePath, language: 'hcl', entities, relationships };
|
||
|
|
}
|
||
|
|
|
||
|
|
module.exports = { extractYaml, extractHcl };
|