@n1k1t/unit-generator
Version:
Coverage based unit tests AI generator
129 lines • 5.64 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Project = void 0;
const minimatch_1 = __importDefault(require("minimatch"));
const path_1 = __importDefault(require("path"));
const promises_1 = __importDefault(require("fs/promises"));
const fast_glob_1 = __importDefault(require("fast-glob"));
const lodash_1 = __importDefault(require("lodash"));
const content_1 = require("./content");
const renderFilesTree = (tree, indent = 0) => Object
.keys(tree)
.map((key) => {
const children = renderFilesTree(tree[key], indent + 2);
return ' '.repeat(indent) + key + (children ? `\n${children}` : '');
})
.join('\n');
class Project {
constructor(provided) {
this.provided = provided;
this.cwd = this.provided.cwd ?? process.cwd();
this.sources = this.provided.sources;
this.content = {
/** Renders `.package.json` content */
dependencies: () => {
if (!this.sources.dependencies) {
return content_1.GroupContent.build([]);
}
return content_1.AttachmentContent.build({
title: 'Available packages in the `package.json` of this project',
content: Object
.entries((this.sources.dependencies))
.map(([name, version]) => `${name} (version ${version})`)
.join('\n')
});
},
/** Renders `.editorconfig` content */
editorconfig: () => {
if (!this.sources.editorconfig?.length) {
return content_1.GroupContent.build([]);
}
return content_1.AttachmentContent.build({
title: 'Editor config file content',
extension: '.editorconfig',
content: this.sources.editorconfig,
});
},
/** Renders project files tree */
tree: (patterns) => {
const filtered = this.files.glob(patterns);
if (!filtered.length) {
return content_1.GroupContent.build([]);
}
const tree = {};
filtered.forEach((path) => {
let current = tree;
path.split('/').forEach((part) => {
if (!current[part]) {
current[part] = {};
}
current = current[part];
});
});
return content_1.AttachmentContent.build({
title: 'Project files tree',
content: renderFilesTree(tree),
});
},
};
this.files = {
/** Returns glob result of the project files */
glob: (patterns) => {
if (!patterns?.length) {
return this.sources.files;
}
const parsed = patterns.map((pattern) => pattern === '.'
? '**'
: pattern.startsWith('./')
? pattern.slice(2)
: pattern);
return this.sources.files.filter((file) => parsed.some((pattern) => (0, minimatch_1.default)(file, pattern, { matchBase: true })));
},
/** Adds path to the project files */
add: (path) => {
if (!this.sources.files.includes(path)) {
this.sources.files.push(path);
}
},
/** Removes file or directory from the project files */
rm: (path) => {
this.sources.files = this.sources.files.filter((file) => !file.startsWith(path));
},
};
}
static async build(options) {
const cwd = options?.cwd ?? process.cwd();
const editorconfig = await promises_1.default.readFile(path_1.default.join(cwd, '.editorconfig'), 'utf8').catch(() => '');
const dependencies = await promises_1.default.readFile(path_1.default.join(cwd, 'package.json'), 'utf8').catch(() => null);
const gitignore = await promises_1.default.readFile(path_1.default.join(cwd, '.gitignore'), 'utf8').catch(() => '');
const ignore = gitignore
.split('\n')
.map((segment) => segment.trim().replace(/^\//, '').replace(/\/$/, '/**'))
.filter((segment) => segment.length && !segment.startsWith('!'))
.concat(['**/*.spec.{ts,js}']);
const files = await (0, fast_glob_1.default)(['**/*.{ts,js,json,md}'], { cwd, ignore });
const source = new Project({
cwd,
sources: {
editorconfig,
ignore,
files,
...(dependencies && {
dependencies: (() => {
const json = JSON.parse(dependencies);
return Object
.entries(Object.assign(json.dependencies ?? {}, json.devDependencies ?? {}))
.filter(([name]) => !name.startsWith('@types/'))
.reduce((acc, [name, version]) => lodash_1.default.set(acc, name, version), {});
})(),
}),
},
});
return source;
}
}
exports.Project = Project;
//# sourceMappingURL=project.js.map