@amplitude/ampli
Version:
Amplitude CLI
132 lines (131 loc) • 6.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const path = require("path");
const lodash_1 = require("lodash");
const debug_1 = require("../../debug");
const sentry_1 = require("../../sentry");
const settings_1 = require("../../settings");
const string_1 = require("../../util/string");
const execSyncToString_1 = require("../../util/child_process/execSyncToString");
const errors_1 = require("../../errors");
const constants_1 = require("../../constants");
const FileService_1 = require("../../services/FileService");
const debug = debug_1.default.extend('verify');
class Verifier {
constructor(fileExtensionPattern, ampliContentFilters = ['ampli', 'itly', 'Ampli', 'Itly', 'Iteratively'], fileFilter = null, ignoreDirs = [], fileService = new FileService_1.FileService()) {
this.fileExtensionPattern = fileExtensionPattern;
this.ampliContentFilters = ampliContentFilters;
this.fileFilter = fileFilter;
this.ignoreDirs = ignoreDirs;
this.fileService = fileService;
this.getReferenceName = (eventName) => `track${string_1.sanitize(eventName)}`;
this.execSyncToString = (command, options) => {
sentry_1.default.captureExec(string_1.sanitizeFilePaths(command, this.fileExtensionPattern), options);
const result = execSyncToString_1.default(command, options);
debug(result);
return result;
};
this.execSyncToJson = (command, options) => {
const result = this.execSyncToString(command, options);
return JSON.parse(result);
};
this.debug = (formatter, ...args) => debug(formatter, args);
}
async verify(eventNames, workingDirs) {
try {
const matchingFiles = await this.getFilePaths(workingDirs);
if (matchingFiles.length > 0) {
this.checkDependencies();
const results = await this.doVerify(eventNames, workingDirs);
const refNameToEventNameMap = eventNames.reduce((map, name) => {
map[this.getReferenceName(name)] = name;
return map;
}, {});
return {
references: results.references.map(ref => (Object.assign(Object.assign({}, ref), { name: refNameToEventNameMap[ref.name], filePath: workingDirs.map(workingDir => path.relative(workingDir, ref.filePath)).sort((path1, path2) => path1.length - path2.length)[0] }))),
errors: results.errors,
};
}
return {
references: [],
errors: [],
};
}
catch (error) {
debug(error);
sentry_1.default.captureException(error);
if (constants_1.APP_SETTINGS.localDevelopment && !debug.enabled) {
console.error(error);
}
const execError = error;
if (execError) {
if (execError.status === 127) {
throw new errors_1.VerificationError(errors_1.USER_ERROR_MESSAGES.verifyRequiredCommandNotFound(error.stderr || error.stdout));
}
}
if (error.errno && error.message) {
throw error;
}
throw new errors_1.VerificationError(errors_1.USER_ERROR_MESSAGES.unexpectedError());
}
}
checkDependencies() { }
async verifyEach(verifyFile, workingDirs) {
const filePaths = await this.getFilePaths(workingDirs);
const results = await Promise.all(filePaths.map(async (filePath) => {
const references = [];
const errors = [];
debug(`verifyEach: ${filePath}\n`);
const fileContents = await this.fileService.getFileContentsIfIncludes(filePath, this.ampliContentFilters);
if (fileContents) {
try {
verifyFile(filePath, fileContents, ref => {
references.push(ref);
debug(`addReference[${references.length}]: %o\n`, ref);
}, error => {
errors.push(error);
debug(`addError[${errors.length}]: %o\n`, error);
});
}
catch (error) {
debug(`addError[${errors.length}]: %o\n`, error);
errors.push({
location: filePath,
message: error.toString(),
});
}
}
return {
references,
errors,
};
}));
return {
references: lodash_1.flatten(results.map(r => r.references)),
errors: lodash_1.flatten(results.map(r => r.errors)),
};
}
async verifyBatch(verifyFiles, workingDirs) {
const references = [];
const errors = [];
const filePaths = await this.getFilePaths(workingDirs);
const sourceFileContents = await Promise.all(filePaths.map(file => this.fileService.getFileContentsIfIncludes(file, this.ampliContentFilters)));
const sourceFilePaths = filePaths.filter((file, i) => sourceFileContents[i]);
if (sourceFilePaths.length > 0) {
verifyFiles(sourceFilePaths, ref => references.push(ref), error => errors.push(error));
}
return { references, errors };
}
async getFilePaths(workingDirs) {
const codegenPath = settings_1.getSettings().getPath();
const ignoreDirs = [codegenPath, ...this.ignoreDirs];
const results = await Promise.all(workingDirs.map(async (workingDir) => {
const filePaths = await this.fileService.findFiles(workingDir, this.fileExtensionPattern, ignoreDirs, ['.gitignore', '.itlyignore', '.ampliignore']);
return this.fileFilter ? filePaths.filter(this.fileFilter) : filePaths;
}));
const result = [];
results.forEach(r => result.push(...r));
return result;
}
}
exports.default = Verifier;