@lmc-eu/spirit-analytics
Version:
Analytic tools for Spirit Design System
221 lines (189 loc) • 9.38 kB
JavaScript
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
var _chunkBD6ZSVQXcjs = require('./chunk-BD6ZSVQX.cjs');
// src/cli.ts
var _sade = require('sade'); var _sade2 = _interopRequireDefault(_sade);
var _zx = require('zx');
// src/scanner.ts
// src/runner.ts
// src/scanners/reactScanner.ts
var _reactscanner = require('react-scanner'); var _reactscanner2 = _interopRequireDefault(_reactscanner);
async function reactScanner(config) {
const output2 = await _reactscanner2.default.run({ ...config });
return output2;
}
// src/scanners/twigScanner.ts
function getComponentsFromDirectory(directoryPath) {
return _zx.fs.readdirSync(directoryPath).map((file) => `${file.charAt(0).toUpperCase()}${file.slice(1, -5)}`);
}
function getPathsFromYamlConfig(configFile) {
const twigXConfigLines = _zx.fs.readFileSync(configFile, "utf8").split("\n");
return twigXConfigLines.filter((line) => line.trim().startsWith("-")).map(
(line) => `${line.trim().substring(1).trim().replace(/"/g, "").replace(/^%kernel.\w+%/, ".")}/*.twig`
);
}
async function getLocalComponentsFromPaths(paths) {
return _zx.glob.call(void 0, paths, (error, files) => {
if (!error) {
return files.map(
(file) => _zx.path.basename(file).charAt(0).toUpperCase() + _zx.path.basename(file).slice(1, -5)
);
}
return [];
});
}
function determineModuleNameFromComponents(nodeName, localComponents, baseComponents) {
if (baseComponents.includes(nodeName)) {
return "@lmc-eu/spirit-web-twig";
}
const pascalCaseRegex = /^([A-Z][a-z0-9]+)+$/;
if (localComponents.includes(nodeName) || nodeName.match(pascalCaseRegex)) {
return "local_component";
}
return "html_element";
}
function searchFileForComponents(file, localComponents, baseComponents) {
const reStartTag = /<([a-zA-Z][a-zA-Z0-9]*)([^>]*)>/g;
const reAttr = /([\w-]+)="?([^"]*)"?/g;
const result = {};
const fileContent = _zx.fs.readFileSync(file, "utf-8");
let match = reStartTag.exec(fileContent);
while (match !== null) {
const [, nodeName, attrs] = match;
const nodeStartPos = match.index;
const numLineBreaks = _nullishCoalesce(_optionalChain([fileContent, 'access', _ => _.slice, 'call', _2 => _2(0, nodeStartPos), 'access', _3 => _3.match, 'call', _4 => _4(/\n/g), 'optionalAccess', _5 => _5.length]), () => ( 0));
const moduleName = determineModuleNameFromComponents(nodeName, localComponents, baseComponents);
const fullName = `${moduleName}:${nodeName}`;
const node = {
path: `${file}:${numLineBreaks + 1}`,
props: {}
};
attrs.replace(reAttr, (attrMatchString, name, value) => {
node.props[name] = value.replace(/\n\s+/g, "");
return "";
});
if (!result[fullName]) {
result[fullName] = [];
}
result[fullName].push(node);
match = reStartTag.exec(fileContent);
}
return result;
}
function searchDirectoryForComponents(dir, localComponents, baseComponents, exclude) {
let result = {};
if (!exclude.includes(_zx.path.basename(dir))) {
const files = _zx.fs.readdirSync(dir);
files.forEach((file) => {
const filePath = _zx.path.join(dir, file);
const fileStat = _zx.fs.lstatSync(filePath);
if (fileStat.isDirectory()) {
result = { ...result, ...searchDirectoryForComponents(filePath, localComponents, baseComponents, exclude) };
} else if (_zx.path.extname(filePath) === ".twig") {
result = { ...result, ...searchFileForComponents(filePath, localComponents, baseComponents) };
}
});
}
return result;
}
var output = (data, destination) => {
_zx.fs.mkdirSync(_zx.path.dirname(destination), { recursive: true });
_zx.fs.writeFileSync(destination, JSON.stringify(data, null, 2));
};
async function twigScanner(options) {
const spiritComponents = getComponentsFromDirectory(_zx.path.resolve(process.cwd(), options.coreComponentsPath || ""));
const twigXPaths = getPathsFromYamlConfig(_zx.path.resolve(process.cwd(), options.configFile || ""));
const localComponents = await getLocalComponentsFromPaths(twigXPaths);
const result = searchDirectoryForComponents(
_zx.path.resolve(process.cwd(), options.rootPath || ""),
localComponents,
spiritComponents,
options.exclude || []
);
output(result, _zx.path.resolve(process.cwd(), options.outputFile || ""));
return result;
}
// src/runner.ts
var getTrackedData = async ({
config,
source,
type
}) => {
const crawlFrom = _zx.path.resolve(source) || _zx.path.resolve(_chunkBD6ZSVQXcjs._dirname, _chunkBD6ZSVQXcjs.ROOT_PATH);
const spiritVersion = await _chunkBD6ZSVQXcjs.getVersions.call(void 0, crawlFrom);
let reactOutput = {};
let twigOutput = {};
if (type === "react" || type === null) {
reactOutput = await reactScanner({ ...config.react, crawlFrom });
}
if (type === "twig" || type === null) {
twigOutput = await twigScanner({ ...config.twig, crawlFrom });
}
return {
spiritVersion,
trackedData: {
react: reactOutput,
twig: twigOutput
}
};
};
var runner = (config, source, type) => getTrackedData({ config, source, type });
// src/scanner.ts
var getRunnerCall = async ({ outputPath, config, source, type }) => {
const result = await runner(config, source, type);
if (outputPath) {
_zx.fs.writeFile(_chunkBD6ZSVQXcjs.getOutputPath.call(void 0, outputPath, _chunkBD6ZSVQXcjs.timestamp.call(void 0, )), JSON.stringify(result, null, 2), "utf8").then(() => {
_chunkBD6ZSVQXcjs.infoMessage.call(void 0, `Successfully created ${_chunkBD6ZSVQXcjs.timestamp.call(void 0, )}.json file in the ${outputPath}`);
});
} else {
}
};
async function scanner2({ source, outputPath, config, type }) {
try {
await getRunnerCall({ outputPath, config, source, type });
} catch (err) {
_chunkBD6ZSVQXcjs.errorMessage.call(void 0, `
${err}`);
}
}
var scanner_default = scanner2;
// src/cli.ts
var packageJson = _zx.fs.readJsonSync(_zx.path.resolve(_chunkBD6ZSVQXcjs._dirname, "./package.json"));
async function cli(args) {
_sade2.default.call(void 0, "analytics", true).version(packageJson.version).describe(packageJson.description).option("-s, --source", "Source to scan from").example("-s assets").option("-o, --output", "Output path for parsed files").example("-o path/to/folder").option("-c --config", "Path to scanner config").example("-c path/to/scanner.config.js").option("-t --type", "Type of scanner").example("-t react").action(async ({ output: output2, config, source, type }) => {
let selectedConfig;
if (config && !_zx.fs.existsSync(config)) {
_chunkBD6ZSVQXcjs.errorMessage.call(void 0, "Could not find config file");
process.exit(1);
} else if (config && _zx.fs.existsSync(config)) {
_chunkBD6ZSVQXcjs.infoMessage.call(void 0, `Using provided config file: ${config}`);
selectedConfig = _zx.path.resolve(process.cwd(), config);
} else {
_chunkBD6ZSVQXcjs.infoMessage.call(void 0, "Using default config file");
selectedConfig = _zx.path.resolve(_chunkBD6ZSVQXcjs._dirname, "./spirit-analytics.config.js");
}
if (output2 && !_zx.fs.existsSync(output2)) {
_chunkBD6ZSVQXcjs.errorMessage.call(void 0, "Path does not exists");
process.exit(1);
}
const { default: loadedConfig } = await Promise.resolve().then(() => _interopRequireWildcard(require(selectedConfig)));
let selectedType = null;
if (type) {
selectedType = type;
}
if (source) {
scanner_default({ source, outputPath: output2, config: loadedConfig, type: selectedType });
_chunkBD6ZSVQXcjs.infoMessage.call(void 0, `Start scanning: ${source}`);
} else {
scanner_default({
source: _zx.path.resolve(process.cwd(), _chunkBD6ZSVQXcjs.ROOT_PATH),
outputPath: output2,
config: loadedConfig,
type: selectedType
});
_chunkBD6ZSVQXcjs.infoMessage.call(void 0, "Start scanning from default scope");
}
}).parse(args);
}
// src/types.ts
var types_exports = {};
exports.cli = cli; exports.constants = _chunkBD6ZSVQXcjs.constants_exports; exports.helpers = _chunkBD6ZSVQXcjs.helpers_exports; exports.reactScannerConfig = _chunkBD6ZSVQXcjs.react_scanner_config_default; exports.scanner = scanner_default; exports.spiritAdoptionProcessor = _chunkBD6ZSVQXcjs.spiritAdoptionProcessor_default; exports.types = types_exports;