chore(providence-analytics): apply "custom projects" in find-exports
This commit is contained in:
parent
0b95d906e3
commit
3865a2433f
5 changed files with 160 additions and 129 deletions
|
|
@ -4,23 +4,24 @@ const { default: traverse } = require('@babel/traverse');
|
||||||
const { Analyzer } = require('./helpers/Analyzer.js');
|
const { Analyzer } = require('./helpers/Analyzer.js');
|
||||||
const { trackDownIdentifier } = require('./helpers/track-down-identifier.js');
|
const { trackDownIdentifier } = require('./helpers/track-down-identifier.js');
|
||||||
const { normalizeSourcePaths } = require('./helpers/normalize-source-paths.js');
|
const { normalizeSourcePaths } = require('./helpers/normalize-source-paths.js');
|
||||||
const { aForEach } = require('../utils/async-array-utils.js');
|
|
||||||
const { LogService } = require('../services/LogService.js');
|
const { LogService } = require('../services/LogService.js');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('./helpers/track-down-identifier.js').RootFile} RootFile
|
* @typedef {import('./helpers/track-down-identifier.js').RootFile} RootFile
|
||||||
* @typedef {object} RootFileMapEntry
|
* @typedef {object} RootFileMapEntry
|
||||||
* @property {string} currentFileSpecifier this is the local name in the file we track from
|
* @typedef {string} currentFileSpecifier this is the local name in the file we track from
|
||||||
* @property {RootFile} rootFile contains file(filePath) and specifier
|
* @typedef {RootFile} rootFile contains file(filePath) and specifier
|
||||||
|
* @typedef {RootFileMapEntry[]} RootFileMap
|
||||||
|
*
|
||||||
|
* @typedef {{ exportSpecifiers:string[]; localMap: object; source:string, __tmp: { path:string } }} FindExportsSpecifierObj
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {RootFileMapEntry[]} RootFileMap
|
* @param {FindExportsSpecifierObj[]} transformedEntry
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async function trackdownRoot(transformedEntry, relativePath, projectPath) {
|
async function trackdownRoot(transformedEntry, relativePath, projectPath) {
|
||||||
const fullCurrentFilePath = pathLib.resolve(projectPath, relativePath);
|
const fullCurrentFilePath = pathLib.resolve(projectPath, relativePath);
|
||||||
await aForEach(transformedEntry, async specObj => {
|
for (const specObj of transformedEntry) {
|
||||||
/** @type {RootFileMap} */
|
/** @type {RootFileMap} */
|
||||||
const rootFileMap = [];
|
const rootFileMap = [];
|
||||||
if (specObj.exportSpecifiers[0] === '[file]') {
|
if (specObj.exportSpecifiers[0] === '[file]') {
|
||||||
|
|
@ -39,7 +40,7 @@ async function trackdownRoot(transformedEntry, relativePath, projectPath) {
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
await aForEach(specObj.exportSpecifiers, async (/** @type {string} */ specifier) => {
|
for (const specifier of specObj.exportSpecifiers) {
|
||||||
let rootFile;
|
let rootFile;
|
||||||
let localMapMatch;
|
let localMapMatch;
|
||||||
if (specObj.localMap) {
|
if (specObj.localMap) {
|
||||||
|
|
@ -48,7 +49,7 @@ async function trackdownRoot(transformedEntry, relativePath, projectPath) {
|
||||||
// TODO: find out if possible to use trackDownIdentifierFromScope
|
// TODO: find out if possible to use trackDownIdentifierFromScope
|
||||||
if (specObj.source) {
|
if (specObj.source) {
|
||||||
// TODO: see if still needed: && (localMapMatch || specifier === '[default]')
|
// TODO: see if still needed: && (localMapMatch || specifier === '[default]')
|
||||||
const importedIdentifier = (localMapMatch && localMapMatch.local) || specifier;
|
const importedIdentifier = localMapMatch?.local || specifier;
|
||||||
rootFile = await trackDownIdentifier(
|
rootFile = await trackDownIdentifier(
|
||||||
specObj.source,
|
specObj.source,
|
||||||
importedIdentifier,
|
importedIdentifier,
|
||||||
|
|
@ -69,10 +70,10 @@ async function trackdownRoot(transformedEntry, relativePath, projectPath) {
|
||||||
};
|
};
|
||||||
rootFileMap.push(entry);
|
rootFileMap.push(entry);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
specObj.rootFileMap = rootFileMap;
|
specObj.rootFileMap = rootFileMap;
|
||||||
});
|
}
|
||||||
return transformedEntry;
|
return transformedEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -139,6 +140,8 @@ function findExportsPerAstEntry(ast, { skipFileImports }) {
|
||||||
LogService.debug(`Analyzer "find-exports": started findExportsPerAstEntry method`);
|
LogService.debug(`Analyzer "find-exports": started findExportsPerAstEntry method`);
|
||||||
|
|
||||||
// Visit AST...
|
// Visit AST...
|
||||||
|
|
||||||
|
/** @type {FindExportsSpecifierObj} */
|
||||||
const transformedEntry = [];
|
const transformedEntry = [];
|
||||||
// Unfortunately, we cannot have async functions in babel traverse.
|
// Unfortunately, we cannot have async functions in babel traverse.
|
||||||
// Therefore, we store a temp reference to path that we use later for
|
// Therefore, we store a temp reference to path that we use later for
|
||||||
|
|
@ -147,7 +150,7 @@ function findExportsPerAstEntry(ast, { skipFileImports }) {
|
||||||
ExportNamedDeclaration(path) {
|
ExportNamedDeclaration(path) {
|
||||||
const exportSpecifiers = getExportSpecifiers(path.node);
|
const exportSpecifiers = getExportSpecifiers(path.node);
|
||||||
const localMap = getLocalNameSpecifiers(path.node);
|
const localMap = getLocalNameSpecifiers(path.node);
|
||||||
const source = path.node.source && path.node.source.value;
|
const source = path.node.source?.value;
|
||||||
transformedEntry.push({ exportSpecifiers, localMap, source, __tmp: { path } });
|
transformedEntry.push({ exportSpecifiers, localMap, source, __tmp: { path } });
|
||||||
},
|
},
|
||||||
ExportDefaultDeclaration(path) {
|
ExportDefaultDeclaration(path) {
|
||||||
|
|
@ -205,7 +208,8 @@ class FindExportsAnalyzer extends Analyzer {
|
||||||
* Traverse
|
* Traverse
|
||||||
*/
|
*/
|
||||||
const projectPath = cfg.targetProjectPath;
|
const projectPath = cfg.targetProjectPath;
|
||||||
const queryOutput = await this._traverse(async (ast, { relativePath }) => {
|
|
||||||
|
const traverseEntryFn = async (ast, { relativePath }) => {
|
||||||
let transformedEntry = findExportsPerAstEntry(ast, cfg);
|
let transformedEntry = findExportsPerAstEntry(ast, cfg);
|
||||||
|
|
||||||
transformedEntry = await normalizeSourcePaths(transformedEntry, relativePath, projectPath);
|
transformedEntry = await normalizeSourcePaths(transformedEntry, relativePath, projectPath);
|
||||||
|
|
@ -213,6 +217,12 @@ class FindExportsAnalyzer extends Analyzer {
|
||||||
transformedEntry = cleanup(transformedEntry);
|
transformedEntry = cleanup(transformedEntry);
|
||||||
|
|
||||||
return { result: transformedEntry };
|
return { result: transformedEntry };
|
||||||
|
};
|
||||||
|
|
||||||
|
const queryOutput = await this._traverse({
|
||||||
|
traverseEntryFn,
|
||||||
|
filePaths: cfg.targetFilePaths,
|
||||||
|
projectPath: cfg.targetProjectPath,
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
* @typedef {import('../../types/analyzers').FindExportsAnalyzerResult} FindExportsAnalyzerResult
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert to more easily iterable object
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* ```js
|
||||||
|
* [
|
||||||
|
* "file": "./file-1.js",
|
||||||
|
* "result": [{
|
||||||
|
* "exportSpecifiers": [ "a", "b"],
|
||||||
|
* "localMap": [{...},{...}],
|
||||||
|
* "source": null,
|
||||||
|
* "rootFileMap": [{"currentFileSpecifier": "a", "rootFile": { "file": "[current]", "specifier": "a" }}]
|
||||||
|
* }, ...],
|
||||||
|
* ```
|
||||||
|
* To:
|
||||||
|
* ```js
|
||||||
|
* [{
|
||||||
|
* "file": ""./file-1.js",
|
||||||
|
* "exportSpecifier": "a",
|
||||||
|
* "localMap": {...},
|
||||||
|
* "source": null,
|
||||||
|
* "rootFileMap": {...}
|
||||||
|
* },
|
||||||
|
* {{
|
||||||
|
* "file": ""./file-1.js",
|
||||||
|
* "exportSpecifier": "b",
|
||||||
|
* "localMap": {...},
|
||||||
|
* "source": null,
|
||||||
|
* "rootFileMap": {...}
|
||||||
|
* }}],
|
||||||
|
*
|
||||||
|
* @param {FindExportsAnalyzerResult} exportsAnalyzerResult
|
||||||
|
*/
|
||||||
|
function transformIntoIterableFindExportsOutput(exportsAnalyzerResult) {
|
||||||
|
/** @type {IterableFindExportsAnalyzerEntry[]} */
|
||||||
|
const iterableEntries = [];
|
||||||
|
|
||||||
|
for (const { file, result } of exportsAnalyzerResult.queryOutput) {
|
||||||
|
for (const { exportSpecifiers, source, rootFileMap, localMap, meta } of result) {
|
||||||
|
if (!exportSpecifiers) {
|
||||||
|
// eslint-disable-next-line no-continue
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (const exportSpecifier of exportSpecifiers) {
|
||||||
|
const i = exportSpecifiers.indexOf(exportSpecifier);
|
||||||
|
/** @type {IterableFindExportsAnalyzerEntry} */
|
||||||
|
const resultEntry = {
|
||||||
|
file,
|
||||||
|
specifier: exportSpecifier,
|
||||||
|
source,
|
||||||
|
rootFile: rootFileMap ? rootFileMap[i] : undefined,
|
||||||
|
localSpecifier: localMap ? localMap[i] : undefined,
|
||||||
|
meta,
|
||||||
|
};
|
||||||
|
iterableEntries.push(resultEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return iterableEntries;
|
||||||
|
}
|
||||||
|
module.exports = {
|
||||||
|
transformIntoIterableFindExportsOutput,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* @typedef {import('../../types/analyzers').FindImportsAnalyzerResult} FindImportsAnalyzerResult
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert to more easily iterable object
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* ```js
|
||||||
|
* [
|
||||||
|
* "file": "./file-1.js",
|
||||||
|
* "result": [{
|
||||||
|
* "importSpecifiers": [ "a", "b" ],
|
||||||
|
* "source": "exporting-ref-project",
|
||||||
|
* "normalizedSource": "exporting-ref-project"
|
||||||
|
* }], ,
|
||||||
|
* ```
|
||||||
|
* To:
|
||||||
|
* ```js
|
||||||
|
* [{
|
||||||
|
* "file": ""./file-1.js",
|
||||||
|
* "importSpecifier": "a",,
|
||||||
|
* "source": "exporting-ref-project",
|
||||||
|
* "normalizedSource": "exporting-ref-project"
|
||||||
|
* },
|
||||||
|
* {{
|
||||||
|
* "file": ""./file-1.js",
|
||||||
|
* "importSpecifier": "b",,
|
||||||
|
* "source": "exporting-ref-project",
|
||||||
|
* "normalizedSource": "exporting-ref-project"
|
||||||
|
* }}],
|
||||||
|
*
|
||||||
|
* @param {FindImportsAnalyzerResult} importsAnalyzerResult
|
||||||
|
*/
|
||||||
|
function transformIntoIterableFindImportsOutput(importsAnalyzerResult) {
|
||||||
|
/** @type {IterableFindImportsAnalyzerEntry[]} */
|
||||||
|
const iterableEntries = [];
|
||||||
|
|
||||||
|
for (const { file, result } of importsAnalyzerResult.queryOutput) {
|
||||||
|
for (const { importSpecifiers, source, normalizedSource } of result) {
|
||||||
|
if (!importSpecifiers) {
|
||||||
|
// eslint-disable-next-line no-continue
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (const importSpecifier of importSpecifiers) {
|
||||||
|
/** @type {IterableFindImportsAnalyzerEntry} */
|
||||||
|
const resultEntry = {
|
||||||
|
file,
|
||||||
|
specifier: importSpecifier,
|
||||||
|
source,
|
||||||
|
normalizedSource,
|
||||||
|
};
|
||||||
|
iterableEntries.push(resultEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return iterableEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
transformIntoIterableFindImportsOutput,
|
||||||
|
};
|
||||||
|
|
@ -5,6 +5,12 @@ const FindImportsAnalyzer = require('./find-imports.js');
|
||||||
const FindExportsAnalyzer = require('./find-exports.js');
|
const FindExportsAnalyzer = require('./find-exports.js');
|
||||||
const { Analyzer } = require('./helpers/Analyzer.js');
|
const { Analyzer } = require('./helpers/Analyzer.js');
|
||||||
const { fromImportToExportPerspective } = require('./helpers/from-import-to-export-perspective.js');
|
const { fromImportToExportPerspective } = require('./helpers/from-import-to-export-perspective.js');
|
||||||
|
const {
|
||||||
|
transformIntoIterableFindExportsOutput,
|
||||||
|
} = require('./helpers/transform-into-iterable-find-exports-output.js');
|
||||||
|
const {
|
||||||
|
transformIntoIterableFindImportsOutput,
|
||||||
|
} = require('./helpers/transform-into-iterable-find-imports-output.js');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../types/analyzers').FindImportsAnalyzerResult} FindImportsAnalyzerResult
|
* @typedef {import('../types/analyzers').FindImportsAnalyzerResult} FindImportsAnalyzerResult
|
||||||
|
|
@ -32,120 +38,6 @@ function compareImportAndExportPaths(exportPath, translatedImportPath) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert to more easily iterable object
|
|
||||||
*
|
|
||||||
* From:
|
|
||||||
* ```js
|
|
||||||
* [
|
|
||||||
* "file": "./file-1.js",
|
|
||||||
* "result": [{
|
|
||||||
* "exportSpecifiers": [ "a", "b"],
|
|
||||||
* "localMap": [{...},{...}],
|
|
||||||
* "source": null,
|
|
||||||
* "rootFileMap": [{"currentFileSpecifier": "a", "rootFile": { "file": "[current]", "specifier": "a" }}]
|
|
||||||
* }, ...],
|
|
||||||
* ```
|
|
||||||
* To:
|
|
||||||
* ```js
|
|
||||||
* [{
|
|
||||||
* "file": ""./file-1.js",
|
|
||||||
* "exportSpecifier": "a",
|
|
||||||
* "localMap": {...},
|
|
||||||
* "source": null,
|
|
||||||
* "rootFileMap": {...}
|
|
||||||
* },
|
|
||||||
* {{
|
|
||||||
* "file": ""./file-1.js",
|
|
||||||
* "exportSpecifier": "b",
|
|
||||||
* "localMap": {...},
|
|
||||||
* "source": null,
|
|
||||||
* "rootFileMap": {...}
|
|
||||||
* }}],
|
|
||||||
*
|
|
||||||
* @param {FindExportsAnalyzerResult} exportsAnalyzerResult
|
|
||||||
*/
|
|
||||||
function transformIntoIterableFindExportsOutput(exportsAnalyzerResult) {
|
|
||||||
/** @type {IterableFindExportsAnalyzerEntry[]} */
|
|
||||||
const iterableEntries = [];
|
|
||||||
|
|
||||||
for (const { file, result } of exportsAnalyzerResult.queryOutput) {
|
|
||||||
for (const { exportSpecifiers, source, rootFileMap, localMap, meta } of result) {
|
|
||||||
if (!exportSpecifiers) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (const exportSpecifier of exportSpecifiers) {
|
|
||||||
const i = exportSpecifiers.indexOf(exportSpecifier);
|
|
||||||
/** @type {IterableFindExportsAnalyzerEntry} */
|
|
||||||
const resultEntry = {
|
|
||||||
file,
|
|
||||||
specifier: exportSpecifier,
|
|
||||||
source,
|
|
||||||
rootFile: rootFileMap ? rootFileMap[i] : undefined,
|
|
||||||
localSpecifier: localMap ? localMap[i] : undefined,
|
|
||||||
meta,
|
|
||||||
};
|
|
||||||
iterableEntries.push(resultEntry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return iterableEntries;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert to more easily iterable object
|
|
||||||
*
|
|
||||||
* From:
|
|
||||||
* ```js
|
|
||||||
* [
|
|
||||||
* "file": "./file-1.js",
|
|
||||||
* "result": [{
|
|
||||||
* "importSpecifiers": [ "a", "b" ],
|
|
||||||
* "source": "exporting-ref-project",
|
|
||||||
* "normalizedSource": "exporting-ref-project"
|
|
||||||
* }], ,
|
|
||||||
* ```
|
|
||||||
* To:
|
|
||||||
* ```js
|
|
||||||
* [{
|
|
||||||
* "file": ""./file-1.js",
|
|
||||||
* "importSpecifier": "a",,
|
|
||||||
* "source": "exporting-ref-project",
|
|
||||||
* "normalizedSource": "exporting-ref-project"
|
|
||||||
* },
|
|
||||||
* {{
|
|
||||||
* "file": ""./file-1.js",
|
|
||||||
* "importSpecifier": "b",,
|
|
||||||
* "source": "exporting-ref-project",
|
|
||||||
* "normalizedSource": "exporting-ref-project"
|
|
||||||
* }}],
|
|
||||||
*
|
|
||||||
* @param {FindImportsAnalyzerResult} importsAnalyzerResult
|
|
||||||
*/
|
|
||||||
function transformIntoIterableFindImportsOutput(importsAnalyzerResult) {
|
|
||||||
/** @type {IterableFindImportsAnalyzerEntry[]} */
|
|
||||||
const iterableEntries = [];
|
|
||||||
|
|
||||||
for (const { file, result } of importsAnalyzerResult.queryOutput) {
|
|
||||||
for (const { importSpecifiers, source, normalizedSource } of result) {
|
|
||||||
if (!importSpecifiers) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (const importSpecifier of importSpecifiers) {
|
|
||||||
/** @type {IterableFindImportsAnalyzerEntry} */
|
|
||||||
const resultEntry = {
|
|
||||||
file,
|
|
||||||
specifier: importSpecifier,
|
|
||||||
source,
|
|
||||||
normalizedSource,
|
|
||||||
};
|
|
||||||
iterableEntries.push(resultEntry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return iterableEntries;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a 'compatible resultsArray' (compatible with dashboard + tests + ...?) from
|
* Makes a 'compatible resultsArray' (compatible with dashboard + tests + ...?) from
|
||||||
* a conciseResultsArray.
|
* a conciseResultsArray.
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ describe('Analyzer "find-exports"', () => {
|
||||||
const firstEntry = getEntry(queryResult);
|
const firstEntry = getEntry(queryResult);
|
||||||
expect(firstEntry.result[0].exportSpecifiers.length).to.equal(1);
|
expect(firstEntry.result[0].exportSpecifiers.length).to.equal(1);
|
||||||
expect(firstEntry.result[0].exportSpecifiers[0]).to.equal('x');
|
expect(firstEntry.result[0].exportSpecifiers[0]).to.equal('x');
|
||||||
expect(firstEntry.result[0].source).to.be.null;
|
expect(firstEntry.result[0].source).to.be.undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`supports [export default class X {}] (default export)`, async () => {
|
it(`supports [export default class X {}] (default export)`, async () => {
|
||||||
|
|
@ -189,7 +189,7 @@ describe('Analyzer "find-exports"', () => {
|
||||||
const firstEntry = getEntry(queryResult);
|
const firstEntry = getEntry(queryResult);
|
||||||
expect(firstEntry.result[0].exportSpecifiers.length).to.equal(1);
|
expect(firstEntry.result[0].exportSpecifiers.length).to.equal(1);
|
||||||
expect(firstEntry.result[0].exportSpecifiers[0]).to.equal('X');
|
expect(firstEntry.result[0].exportSpecifiers[0]).to.equal('X');
|
||||||
expect(firstEntry.result[0].source).to.be.null;
|
expect(firstEntry.result[0].source).to.be.undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`functions`, async () => {
|
it(`functions`, async () => {
|
||||||
|
|
@ -199,7 +199,7 @@ describe('Analyzer "find-exports"', () => {
|
||||||
const firstEntry = getEntry(queryResult);
|
const firstEntry = getEntry(queryResult);
|
||||||
expect(firstEntry.result[0].exportSpecifiers.length).to.equal(1);
|
expect(firstEntry.result[0].exportSpecifiers.length).to.equal(1);
|
||||||
expect(firstEntry.result[0].exportSpecifiers[0]).to.equal('y');
|
expect(firstEntry.result[0].exportSpecifiers[0]).to.equal('y');
|
||||||
expect(firstEntry.result[0].source).to.be.null;
|
expect(firstEntry.result[0].source).to.be.undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
// ...etc?
|
// ...etc?
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue