UNPKG

@oaklean/profiler-core

Version:

Part of the @oaklean suite. It provides all basic functions to work with the `.oak` file format. It allows parsing the `.oak` file format as well as tools for analyzing the measurement values. It also provides all necessary capabilities required for prec

273 lines 23.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ProfilerConfig = void 0; const fs = __importStar(require("fs")); const BaseModel_1 = require("./BaseModel"); const config_1 = require("../constants/config"); const PathUtils_1 = require("../helper/PathUtils"); const UnifiedPath_1 = require("../system/UnifiedPath"); const Crypto_1 = require("../system/Crypto"); const PermissionHelper_1 = require("../helper/PermissionHelper"); // Types const types_1 = require("../types"); class ProfilerConfig extends BaseModel_1.BaseModel { constructor(filePath, config) { super(); this.filePath = filePath; this.extends = config.extends; this.registryOptions = config.registryOptions; this.exportOptions = config.exportOptions; this.projectOptions = config.projectOptions; this.runtimeOptions = config.runtimeOptions; } static getDefaultConfig() { return new ProfilerConfig(new UnifiedPath_1.UnifiedPath(process.cwd()).join(config_1.STATIC_CONFIG_FILENAME), config_1.DEFAULT_PROFILER_CONFIG); } getAnonymizedRuntimeOptions() { if (this.runtimeOptions.sensorInterface) { switch (this.runtimeOptions.sensorInterface.type) { case types_1.SensorInterfaceType.windows: return Object.assign(Object.assign({}, this.runtimeOptions), { sensorInterface: { type: types_1.SensorInterfaceType.windows, options: { sampleInterval: this.runtimeOptions.sensorInterface.options.sampleInterval, outputFilePath: '<anonymized>' } } }); case types_1.SensorInterfaceType.perf: return Object.assign(Object.assign({}, this.runtimeOptions), { sensorInterface: { type: types_1.SensorInterfaceType.perf, options: { sampleInterval: this.runtimeOptions.sensorInterface.options.sampleInterval, outputFilePath: '<anonymized>' } } }); case types_1.SensorInterfaceType.powermetrics: return Object.assign(Object.assign({}, this.runtimeOptions), { sensorInterface: { type: types_1.SensorInterfaceType.powermetrics, options: { sampleInterval: this.runtimeOptions.sensorInterface.options.sampleInterval, outputFilePath: '<anonymized>' } } }); } } return this.runtimeOptions; } getV8CPUSamplingInterval() { return this.runtimeOptions.v8.cpu.sampleInterval; } getRegistryUploadUrl() { return `http://${this.registryOptions.url}/upload`; } uploadEnabled() { var _a, _b; return (((_a = this.registryOptions) === null || _a === void 0 ? void 0 : _a.url) !== undefined) && ((_b = this.registryOptions) === null || _b === void 0 ? void 0 : _b.url) !== ''; } getProjectIdentifier() { if (!Crypto_1.Crypto.validateUniqueID(this.projectOptions.identifier)) { throw new Error('ProfilerConfig.getProjectIdentifier: identifier should be an uuid4'); } return this.projectOptions.identifier; } getRootDir() { if (PathUtils_1.PathUtils.isAbsolute(this.exportOptions.rootDir)) { return new UnifiedPath_1.UnifiedPath(this.exportOptions.rootDir); } return this.filePath.dirName().join(this.exportOptions.rootDir); } getOutDir() { if (PathUtils_1.PathUtils.isAbsolute(this.exportOptions.outDir)) { return new UnifiedPath_1.UnifiedPath(this.exportOptions.outDir); } return this.filePath.dirName().join(this.exportOptions.outDir); } getOutHistoryDir() { if (PathUtils_1.PathUtils.isAbsolute(this.exportOptions.outHistoryDir)) { return new UnifiedPath_1.UnifiedPath(this.exportOptions.outHistoryDir); } return this.filePath.dirName().join(this.exportOptions.outHistoryDir); } getSensorInterfaceType() { var _a; return (_a = this.runtimeOptions.sensorInterface) === null || _a === void 0 ? void 0 : _a.type; } getSensorInterfaceOptions() { var _a; return (_a = this.runtimeOptions.sensorInterface) === null || _a === void 0 ? void 0 : _a.options; } shouldExportV8Profile() { return this.exportOptions.exportV8Profile; } shouldExportReport() { return this.exportOptions.exportReport; } shouldExportSensorInterfaceData() { return this.exportOptions.exportSensorInterfaceData; } getSeedForMathRandom() { return this.runtimeOptions.seeds['Math.random']; } configAsExtended(pathDiff) { const exportOptions = this.exportOptions; if (exportOptions) { if (exportOptions.outDir && !PathUtils_1.PathUtils.isAbsolute(exportOptions.outDir)) { exportOptions.outDir = pathDiff.join(exportOptions.outDir).toString(); } if (exportOptions.outHistoryDir && !PathUtils_1.PathUtils.isAbsolute(exportOptions.outHistoryDir)) { exportOptions.outHistoryDir = pathDiff.join(exportOptions.outHistoryDir).toString(); } if (exportOptions.rootDir && !PathUtils_1.PathUtils.isAbsolute(exportOptions.rootDir)) { exportOptions.rootDir = pathDiff.join(exportOptions.rootDir).toString(); } } return { exportOptions: exportOptions, projectOptions: this.projectOptions, runtimeOptions: this.runtimeOptions, registryOptions: this.registryOptions }; } /** * Fills unspecified values of the config with values of the given config * * example usage: * - every config that gets resolved inherits values of the default config (baseConfig) * to ensure that unspecified values are filled with the default value. This happens via: * config.implement(baseConfig): * * - if a config contains the extends keyword like this: * { * "extends": "<config that gets extended>" * } * the config gets extended via: * config.implement(<config that gets extended>): * * it also adjusts the inherited path values values to make them relative to the config * * * @param config to inherit from */ implement(config) { var _a, _b, _c, _d, _e, _f; const pathDiff = this.filePath.dirName().pathTo(config.filePath.dirName()); const configToExtend = config.configAsExtended(pathDiff); const newExportOptions = Object.assign(Object.assign({}, configToExtend.exportOptions), this.exportOptions); const newProjectOptions = Object.assign(Object.assign({}, configToExtend.projectOptions), this.projectOptions); const newRuntimeOptions = Object.assign(Object.assign(Object.assign({}, configToExtend.runtimeOptions), this.runtimeOptions), { seeds: Object.assign(Object.assign({}, (((_a = configToExtend === null || configToExtend === void 0 ? void 0 : configToExtend.runtimeOptions) === null || _a === void 0 ? void 0 : _a.seeds) || {})), (((_b = this.runtimeOptions) === null || _b === void 0 ? void 0 : _b.seeds) || {})), v8: { cpu: Object.assign(Object.assign({}, (((_d = (_c = configToExtend.runtimeOptions) === null || _c === void 0 ? void 0 : _c.v8) === null || _d === void 0 ? void 0 : _d.cpu) || {})), (((_f = (_e = this.runtimeOptions) === null || _e === void 0 ? void 0 : _e.v8) === null || _f === void 0 ? void 0 : _f.cpu) || {})) } }); const newRegistryOptions = Object.assign(Object.assign({}, configToExtend.registryOptions), this.registryOptions); this.exportOptions = newExportOptions; this.projectOptions = newProjectOptions; this.runtimeOptions = newRuntimeOptions; this.registryOptions = newRegistryOptions; } static fromJSON(json) { let data; if (typeof json === 'string') { data = JSON.parse(json); } else { data = json; } if (data.projectOptions === undefined || data.projectOptions.identifier === undefined) { throw new Error('ProfilerConfig: the project has no identifier yet'); } if (!Crypto_1.Crypto.validateUniqueID(data.projectOptions.identifier)) { throw new Error('ProfilerConfig.getProjectIdentifier: Loaded identifier from the config should be an uuid4'); } return new ProfilerConfig(new UnifiedPath_1.UnifiedPath(''), { extends: data.extends, exportOptions: data.exportOptions, projectOptions: data.projectOptions, runtimeOptions: data.runtimeOptions, registryOptions: data.registryOptions }); } toJSON() { return ({ extends: this.extends, exportOptions: this.exportOptions, projectOptions: this.projectOptions, runtimeOptions: this.runtimeOptions, registryOptions: this.registryOptions }); } storeToFile(filePath) { if (!fs.existsSync(filePath.dirName().toPlatformString())) { PermissionHelper_1.PermissionHelper.mkdirRecursivelyWithUserPermission(filePath.dirName().toPlatformString()); } PermissionHelper_1.PermissionHelper.writeFileWithUserPermission(filePath.toPlatformString(), JSON.stringify(this, null, 2)); } // loads a config from a given file path and extends it // this method is NOT used to ensure load a valid (complete) config, use resolveFromFile to achieve that static loadFromFile(filePath) { if (!fs.existsSync(filePath.toPlatformString())) { return undefined; } const loadedConfig = ProfilerConfig.fromJSON(fs.readFileSync(filePath.toPlatformString()).toString()); loadedConfig.filePath = filePath; if (loadedConfig.extends) { const configToExtendFilePath = filePath.dirName().join(loadedConfig.extends); const configToExtend = ProfilerConfig.loadFromFile(configToExtendFilePath); if (configToExtend) { loadedConfig.implement(configToExtend); return loadedConfig; } } return loadedConfig; } // loads a config from a given file path and fills all non defined values with the resp. default values static resolveFromFile(filePath) { const baseConfig = ProfilerConfig.getDefaultConfig(); if (!filePath) { return baseConfig; } const config = this.loadFromFile(filePath); if (config) { baseConfig.filePath = config.filePath; config.implement(baseConfig); return config; } return baseConfig; } static autoResolveFromPath(startDir) { // Searches from the given path upwards until it finds the config file const configFilePath = PathUtils_1.PathUtils.findUp(config_1.STATIC_CONFIG_FILENAME, startDir.toPlatformString()); if (!configFilePath) { return ProfilerConfig.resolveFromFile(undefined); } return ProfilerConfig.resolveFromFile(new UnifiedPath_1.UnifiedPath(configFilePath)); } static autoResolve() { // Searches from the processes execution path upwards until it finds the config file return this.autoResolveFromPath(new UnifiedPath_1.UnifiedPath(process.cwd())); } } exports.ProfilerConfig = ProfilerConfig; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHJvZmlsZXJDb25maWcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbW9kZWwvUHJvZmlsZXJDb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx1Q0FBd0I7QUFFeEIsMkNBQXVDO0FBRXZDLGdEQUc0QjtBQUM1QixtREFBK0M7QUFDL0MsdURBQW1EO0FBQ25ELDZDQUF5QztBQUN6QyxpRUFBNkQ7QUFDN0QsUUFBUTtBQUNSLG9DQVlpQjtBQUVqQixNQUFhLGNBQWUsU0FBUSxxQkFBUztJQVE1QyxZQUFZLFFBQXFCLEVBQUUsTUFBdUI7UUFDekQsS0FBSyxFQUFFLENBQUE7UUFDUCxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQTtRQUN4QixJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUE7UUFDN0IsSUFBSSxDQUFDLGVBQWUsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFBO1FBQzdDLElBQUksQ0FBQyxhQUFhLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQTtRQUN6QyxJQUFJLENBQUMsY0FBYyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUE7UUFDM0MsSUFBSSxDQUFDLGNBQWMsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFBO0lBQzVDLENBQUM7SUFFRCxNQUFNLENBQUMsZ0JBQWdCO1FBQ3RCLE9BQU8sSUFBSSxjQUFjLENBQ3hCLElBQUkseUJBQVcsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsK0JBQXNCLENBQUMsRUFDM0QsZ0NBQXVCLENBQ3ZCLENBQUE7SUFDRixDQUFDO0lBRUQsMkJBQTJCO1FBQzFCLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN6QyxRQUFRLElBQUksQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNsRCxLQUFLLDJC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