feat(providence): update version of oxc; cleanup; include .ts(x) and jsx by default
This commit is contained in:
parent
35e66052b6
commit
71992cc0fb
12 changed files with 133 additions and 170 deletions
5
.changeset/proud-pugs-think.md
Normal file
5
.changeset/proud-pugs-think.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'providence-analytics': patch
|
||||
---
|
||||
|
||||
update version of oxc; cleanup; include .ts(x) and jsx by default
|
||||
|
|
@ -28,7 +28,7 @@ It does this via the [oxc parser](https://oxc.rs/docs/guide/usage/parser.html),
|
|||
Providence expects an analyzer name that tells it what type of analysis to run:
|
||||
|
||||
```bash
|
||||
npx providence analyze <analyzer-name>
|
||||
npx providence-analytics analyze <analyzer-name>
|
||||
```
|
||||
|
||||
By default Providence ships these analyzers:
|
||||
|
|
@ -42,7 +42,7 @@ By default Providence ships these analyzers:
|
|||
Let's say we run `find-imports`:
|
||||
|
||||
```bash
|
||||
npx providence analyze find-imports
|
||||
npx providence-analytics analyze find-imports
|
||||
```
|
||||
|
||||
Now it retrieves all relevant data about es module imports.
|
||||
|
|
@ -68,14 +68,14 @@ For a "find" analyzer, there is one project involved (the target project).
|
|||
We can specify it like this (we override the default current working directory):
|
||||
|
||||
```bash
|
||||
npx providence analyze find-imports -t /importing/project
|
||||
npx providence-analytics analyze find-imports -t /importing/project
|
||||
```
|
||||
|
||||
For a "match" analyzer, there is also a reference project.
|
||||
Here we match the exports of the reference project (-r) against the imports of the target project (-t).
|
||||
|
||||
```bash
|
||||
npx providence analyze match-imports -t /importing/project -r /exporting/project
|
||||
npx providence-analytics analyze match-imports -t /importing/project -r /exporting/project
|
||||
```
|
||||
|
||||
## Utils
|
||||
|
|
@ -91,5 +91,5 @@ For a better understanding, check out the utils folders (tests and code).
|
|||
For more options, see:
|
||||
|
||||
```bash
|
||||
npx providence --help
|
||||
npx providence-analytics --help
|
||||
```
|
||||
|
|
|
|||
31
package-lock.json
generated
31
package-lock.json
generated
|
|
@ -5306,6 +5306,7 @@
|
|||
"version": "15.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz",
|
||||
"integrity": "sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
|
|
@ -28331,9 +28332,9 @@
|
|||
"version": "0.17.3",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rollup/plugin-node-resolve": "^15.3.0",
|
||||
"@rollup/plugin-node-resolve": "^16.0.0",
|
||||
"commander": "^2.20.3",
|
||||
"oxc-parser": "^0.39.0",
|
||||
"oxc-parser": "^0.46.0",
|
||||
"parse5": "^7.2.1",
|
||||
"semver": "^7.6.3"
|
||||
},
|
||||
|
|
@ -28598,6 +28599,30 @@
|
|||
"win32"
|
||||
]
|
||||
},
|
||||
"packages-node/providence-analytics/node_modules/@rollup/plugin-node-resolve": {
|
||||
"version": "16.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.0.tgz",
|
||||
"integrity": "sha512-0FPvAeVUT/zdWoO0jnb/V5BlBsUSNfkIOtFHzMO4H9MOklrmQFY6FduVHKucNb/aTFxvnGhj4MNj/T1oNdDfNg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
"@types/resolve": "1.20.2",
|
||||
"deepmerge": "^4.2.2",
|
||||
"is-module": "^1.0.0",
|
||||
"resolve": "^1.22.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^2.78.0||^3.0.0||^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"packages-node/providence-analytics/node_modules/@types/mocha": {
|
||||
"version": "10.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz",
|
||||
|
|
@ -28823,7 +28848,7 @@
|
|||
},
|
||||
"packages/ui": {
|
||||
"name": "@lion/ui",
|
||||
"version": "0.9.0",
|
||||
"version": "0.9.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@bundled-es-modules/message-format": "^6.2.4",
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@
|
|||
"test:node:unit": "mocha './{test-node,src}/**/*.test.js'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@rollup/plugin-node-resolve": "^15.3.0",
|
||||
"@rollup/plugin-node-resolve": "^16.0.0",
|
||||
"commander": "^2.20.3",
|
||||
"oxc-parser": "^0.39.0",
|
||||
"oxc-parser": "^0.46.0",
|
||||
"parse5": "^7.2.1",
|
||||
"semver": "^7.6.3"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import path from 'path';
|
||||
|
||||
import commander from 'commander';
|
||||
import path from 'path';
|
||||
|
||||
import { InputDataService } from '../program/core/InputDataService.js';
|
||||
import { getCurrentDir } from '../program/utils/get-current-dir.js';
|
||||
|
|
|
|||
|
|
@ -234,37 +234,10 @@ export default class FindClassesAnalyzer extends Analyzer {
|
|||
/** @type {AnalyzerAst} */
|
||||
static requiredAst = 'oxc';
|
||||
|
||||
/**
|
||||
* Will find all public members (properties (incl. getter/setters)/functions) of a class and
|
||||
* will make a distinction between private, public and protected methods
|
||||
* @param {Partial<FindClassesConfig>} customConfig
|
||||
*/
|
||||
async execute(customConfig) {
|
||||
const cfg = customConfig;
|
||||
|
||||
/**
|
||||
* Prepare
|
||||
*/
|
||||
const analyzerResult = await this._prepare(cfg);
|
||||
if (analyzerResult) {
|
||||
return analyzerResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse
|
||||
*/
|
||||
/** @type {FindClassesAnalyzerOutput} */
|
||||
const queryOutput = await this._traverse(async (ast, { relativePath }) => {
|
||||
const projectPath = cfg.targetProjectPath;
|
||||
const fullPath = path.resolve(projectPath, relativePath);
|
||||
const transformedEntry = await findMembersPerAstEntry(ast, fullPath, projectPath);
|
||||
return { result: transformedEntry };
|
||||
});
|
||||
// _flattenedFormsPostProcessor();
|
||||
|
||||
/**
|
||||
* Finalize
|
||||
*/
|
||||
return this._finalize(queryOutput, cfg);
|
||||
static async analyzeFile(oxcAst, context) {
|
||||
const projectPath = context.analyzerCfg.targetProjectPath;
|
||||
const fullPath = path.resolve(projectPath, context.relativePath);
|
||||
const transformedEntry = await findMembersPerAstEntry(oxcAst, fullPath, projectPath);
|
||||
return { result: transformedEntry };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { trackDownIdentifierFromScope } from '../utils/track-down-identifier.js'
|
|||
import { Analyzer } from '../core/Analyzer.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../../../types/index.js').FindCustomelementsConfig} FindCustomelementsConfig
|
||||
* @typedef {import('../../../types/index.js').AnalyzerAst} AnalyzerAst
|
||||
* @typedef {import('../../../types/index.js').AnalyzerName} AnalyzerName
|
||||
* @typedef {import('@babel/types').File} File
|
||||
*/
|
||||
|
|
@ -100,38 +100,21 @@ export default class FindCustomelementsAnalyzer extends Analyzer {
|
|||
/** @type {AnalyzerAst} */
|
||||
static requiredAst = 'oxc';
|
||||
|
||||
/**
|
||||
* Finds export specifiers and sources
|
||||
* @param {FindCustomelementsConfig} customConfig
|
||||
*/
|
||||
async execute(customConfig = {}) {
|
||||
const cfg = {
|
||||
get config() {
|
||||
return {
|
||||
targetProjectPath: null,
|
||||
...customConfig,
|
||||
...this._customConfig,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare
|
||||
*/
|
||||
const cachedAnalyzerResult = await this._prepare(cfg);
|
||||
if (cachedAnalyzerResult) {
|
||||
return cachedAnalyzerResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse
|
||||
*/
|
||||
const projectPath = cfg.targetProjectPath;
|
||||
const queryOutput = await this._traverse(async (ast, context) => {
|
||||
let transformedEntry = findCustomElementsPerAstFile(ast);
|
||||
transformedEntry = await trackdownRoot(transformedEntry, context.relativePath, projectPath);
|
||||
transformedEntry = cleanup(transformedEntry);
|
||||
return { result: transformedEntry };
|
||||
});
|
||||
|
||||
/**
|
||||
* Finalize
|
||||
*/
|
||||
return this._finalize(queryOutput, cfg);
|
||||
static async analyzeFile(oxcAst, context) {
|
||||
let transformedEntry = findCustomElementsPerAstFile(oxcAst);
|
||||
transformedEntry = await trackdownRoot(
|
||||
transformedEntry,
|
||||
context.relativePath,
|
||||
context.projectData.project.path,
|
||||
);
|
||||
transformedEntry = cleanup(transformedEntry);
|
||||
return { result: transformedEntry };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* eslint-disable no-shadow, no-param-reassign */
|
||||
import path from 'path';
|
||||
|
||||
// import { transformIntoIterableFindExportsOutput } from './helpers/transform-into-iterable-find-exports-output.js';
|
||||
import { getReferencedDeclaration } from '../utils/get-source-code-fragment-of-declaration.js';
|
||||
import { normalizeSourcePaths } from './helpers/normalize-source-paths.js';
|
||||
import { trackDownIdentifier } from '../utils/track-down-identifier.js';
|
||||
|
|
@ -274,4 +275,10 @@ export default class FindExportsAnalyzer extends Analyzer {
|
|||
|
||||
return { result: transformedFile };
|
||||
}
|
||||
|
||||
static async analyzeProject(...args) {
|
||||
const totalResult = await super.analyzeProject(...args);
|
||||
// return transformIntoIterableFindExportsOutput({ queryOutput: totalResult });
|
||||
return totalResult;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,16 +23,9 @@ import { Analyzer } from '../core/Analyzer.js';
|
|||
|
||||
/**
|
||||
* Intends to work for oxc, swc, and babel asts
|
||||
* @param {SwcNode} s
|
||||
*/
|
||||
function getSpecifierValue(s) {
|
||||
// for (const exportedorImportedName of [...exportedNames, ...importedNames]) {
|
||||
// for (const valueName of valueNames) {
|
||||
// const result = s[exportedorImportedName][valueName];
|
||||
// if (result) return result;
|
||||
// }
|
||||
// }
|
||||
// return undefined;
|
||||
|
||||
return (
|
||||
// These are regular import values and must be checked first
|
||||
s.imported?.value ||
|
||||
|
|
@ -164,57 +157,35 @@ export default class FindImportsSwcAnalyzer extends Analyzer {
|
|||
static requiredAst = /** @type {AnalyzerAst} */ ('oxc');
|
||||
|
||||
/**
|
||||
* Finds import specifiers and sources
|
||||
* @param {FindImportsConfig} customConfig
|
||||
* @typedef FindImportsConfig
|
||||
* @property {boolean} [keepInternalSources=false] by default, relative paths like '../x.js' are
|
||||
* filtered out. This option keeps them.
|
||||
* means that 'external-dep/file' will be resolved to 'external-dep/file.js' will both be stored
|
||||
* as the latter
|
||||
*/
|
||||
async execute(customConfig = {}) {
|
||||
/**
|
||||
* @typedef FindImportsConfig
|
||||
* @property {boolean} [keepInternalSources=false] by default, relative paths like '../x.js' are
|
||||
* filtered out. This option keeps them.
|
||||
* means that 'external-dep/file' will be resolved to 'external-dep/file.js' will both be stored
|
||||
* as the latter
|
||||
*/
|
||||
const cfg = {
|
||||
get config() {
|
||||
return {
|
||||
targetProjectPath: null,
|
||||
// post process file
|
||||
keepInternalSources: false,
|
||||
...customConfig,
|
||||
...this._customConfig,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare
|
||||
*/
|
||||
const cachedAnalyzerResult = await this._prepare(cfg);
|
||||
if (cachedAnalyzerResult) {
|
||||
return cachedAnalyzerResult;
|
||||
static async analyzeFile(oxcAst, context) {
|
||||
let transformedFile = findImportsPerAstFile(oxcAst);
|
||||
// Post processing based on configuration...
|
||||
transformedFile = await normalizeSourcePaths(
|
||||
transformedFile,
|
||||
context.relativePath,
|
||||
context.analyzerCfg.targetProjectPath,
|
||||
);
|
||||
|
||||
if (!context.analyzerCfg.keepInternalSources) {
|
||||
// @ts-expect-error
|
||||
transformedFile = transformedFile.filter(entry => !isRelativeSourcePath(entry.source));
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse
|
||||
*/
|
||||
const queryOutput = await this._traverse(async (oxcAst, context) => {
|
||||
// @ts-expect-error
|
||||
let transformedFile = findImportsPerAstFile(oxcAst);
|
||||
// Post processing based on configuration...
|
||||
transformedFile = await normalizeSourcePaths(
|
||||
transformedFile,
|
||||
context.relativePath,
|
||||
// @ts-expect-error
|
||||
cfg.targetProjectPath,
|
||||
);
|
||||
|
||||
if (!cfg.keepInternalSources) {
|
||||
// @ts-expect-error
|
||||
transformedFile = transformedFile.filter(entry => !isRelativeSourcePath(entry.source));
|
||||
}
|
||||
|
||||
return { result: transformedFile };
|
||||
});
|
||||
|
||||
/**
|
||||
* Finalize
|
||||
*/
|
||||
return this._finalize(queryOutput, cfg);
|
||||
return { result: transformedFile };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -348,36 +348,28 @@ export class Analyzer {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {FileAstTraverseFn|{traverseEntryFn: FileAstTraverseFn; filePaths:string[]; projectPath: string}} traverseEntryOrConfig
|
||||
* @param {FileAstTraverseFn|{traverseEntryFn: FileAstTraverseFn; filePaths:string[]; projectPath: string; targetData: ProjectInputDataWithMeta}} analyzeFileCfg
|
||||
*/
|
||||
async _traverse(traverseEntryOrConfig) {
|
||||
static async analyzeProject(analyzeFileCfg) {
|
||||
LogService.debug(`Analyzer "${this.name}": started _traverse method`);
|
||||
|
||||
let traverseEntryFn;
|
||||
let finalTargetData;
|
||||
|
||||
if (typeof traverseEntryOrConfig === 'function') {
|
||||
traverseEntryFn = traverseEntryOrConfig;
|
||||
finalTargetData = this.targetData;
|
||||
if (!analyzeFileCfg.filePaths) {
|
||||
finalTargetData = analyzeFileCfg.targetData;
|
||||
} else {
|
||||
traverseEntryFn = traverseEntryOrConfig.traverseEntryFn;
|
||||
if (!traverseEntryOrConfig.filePaths) {
|
||||
finalTargetData = this.targetData;
|
||||
} else {
|
||||
const { projectPath, projectName } = traverseEntryOrConfig;
|
||||
if (!projectPath) {
|
||||
LogService.error(`[Analyzer._traverse]: you must provide a projectPath`);
|
||||
}
|
||||
finalTargetData = await InputDataService.createDataObject([
|
||||
{
|
||||
project: {
|
||||
name: projectName || '[n/a]',
|
||||
path: projectPath,
|
||||
},
|
||||
entries: traverseEntryOrConfig.filePaths,
|
||||
},
|
||||
]);
|
||||
const { projectPath, projectName } = analyzeFileCfg;
|
||||
if (!projectPath) {
|
||||
LogService.error(`[Analyzer._traverse]: you must provide a projectPath`);
|
||||
}
|
||||
finalTargetData = await InputDataService.createDataObject([
|
||||
{
|
||||
project: {
|
||||
name: projectName || '[n/a]',
|
||||
path: projectPath,
|
||||
},
|
||||
entries: analyzeFileCfg.filePaths,
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -385,9 +377,13 @@ export class Analyzer {
|
|||
*/
|
||||
const astDataProjects = await QueryService.addAstToProjectsData(
|
||||
finalTargetData,
|
||||
this.constructor.requiredAst,
|
||||
this.requiredAst,
|
||||
);
|
||||
return analyzePerAstFile(
|
||||
astDataProjects[0],
|
||||
analyzeFileCfg.traverseEntryFn,
|
||||
analyzeFileCfg.config,
|
||||
);
|
||||
return analyzePerAstFile(astDataProjects[0], traverseEntryFn, this.config);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -409,11 +405,13 @@ export class Analyzer {
|
|||
/**
|
||||
* Traverse
|
||||
*/
|
||||
const queryOutput = await this._traverse({
|
||||
const queryOutput = await /** @type {typeof Analyzer} */ (this.constructor).analyzeProject({
|
||||
// @ts-ignore
|
||||
traverseEntryFn: this.constructor.analyzeFile,
|
||||
filePaths: cfg.targetFilePaths,
|
||||
projectPath: cfg.targetProjectPath,
|
||||
filePaths: cfg.targetFilePaths,
|
||||
targetData: this.targetData,
|
||||
config: this.config,
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@ import { AstService } from './AstService.js';
|
|||
* @typedef {import('../../../types/index.js').Feature} Feature
|
||||
*/
|
||||
|
||||
/** @type {`.${string}`[]} */
|
||||
const defaultExtensions = ['.js', '.ts', '.jsx', '.tsx', '.mjs'];
|
||||
|
||||
/**
|
||||
* @typedef {(rootPath:PathFromSystemRoot) => PackageJson|undefined} GetPackageJsonFn
|
||||
* @type {GetPackageJsonFn}
|
||||
|
|
@ -179,8 +182,9 @@ const getNpmPackagePaths = memoize((/** @type {PathFromSystemRoot} */ rootPath)
|
|||
});
|
||||
|
||||
/**
|
||||
* @param {any|any[]} v
|
||||
* @returns {any[]}
|
||||
* @template T
|
||||
* @param {T|T[]} v
|
||||
* @returns {T[]}
|
||||
*/
|
||||
function ensureArray(v) {
|
||||
return Array.isArray(v) ? v : [v];
|
||||
|
|
@ -429,7 +433,7 @@ export class InputDataService {
|
|||
static get defaultGatherFilesConfig() {
|
||||
return {
|
||||
allowlist: ['!node_modules/**', '!bower_components/**', '!**/*.conf.js', '!**/*.config.js'],
|
||||
extensions: ['.js'],
|
||||
extensions: defaultExtensions,
|
||||
depth: Infinity,
|
||||
};
|
||||
}
|
||||
|
|
@ -440,7 +444,7 @@ export class InputDataService {
|
|||
* @param {string[]} extensions
|
||||
* @returns {string}
|
||||
*/
|
||||
static _getDefaultGlobDepthPattern(depth = Infinity, extensions = ['.js']) {
|
||||
static _getDefaultGlobDepthPattern(depth = Infinity, extensions = defaultExtensions) {
|
||||
// `.{${cfg.extensions.map(e => e.slice(1)).join(',')},}`;
|
||||
const extensionsGlobPart = `.{${extensions.map(extension => extension.slice(1)).join(',')},}`;
|
||||
if (depth === Infinity) {
|
||||
|
|
@ -472,6 +476,15 @@ export class InputDataService {
|
|||
* @returns {Promise<PathFromSystemRoot[]>} result list of file paths
|
||||
*/
|
||||
static async gatherFilesFromDir(startPath, customConfig = {}) {
|
||||
const allowlistModes = ['npm', 'git', 'all', 'export-map'];
|
||||
if (customConfig.allowlistMode && !allowlistModes.includes(customConfig.allowlistMode)) {
|
||||
throw new Error(
|
||||
`[gatherFilesConfig] Please provide a valid allowListMode like "${allowlistModes.join(
|
||||
'|',
|
||||
)}". Found: "${customConfig.allowlistMode}"`,
|
||||
);
|
||||
}
|
||||
|
||||
const cfg = {
|
||||
...this.defaultGatherFilesConfig,
|
||||
...customConfig,
|
||||
|
|
@ -483,15 +496,6 @@ export class InputDataService {
|
|||
];
|
||||
}
|
||||
|
||||
const allowlistModes = ['npm', 'git', 'all', 'export-map'];
|
||||
if (customConfig.allowlistMode && !allowlistModes.includes(customConfig.allowlistMode)) {
|
||||
throw new Error(
|
||||
`[gatherFilesConfig] Please provide a valid allowListMode like "${allowlistModes.join(
|
||||
'|',
|
||||
)}". Found: "${customConfig.allowlistMode}"`,
|
||||
);
|
||||
}
|
||||
|
||||
if (cfg.allowlistMode === 'export-map') {
|
||||
const pkgJson = getPackageJson(startPath);
|
||||
if (!pkgJson?.exports) {
|
||||
|
|
|
|||
|
|
@ -424,9 +424,7 @@ describe('Memoize', () => {
|
|||
{ fn: spy2Memoized, count: 4 },
|
||||
]);
|
||||
|
||||
console.debug('spy3Memoized');
|
||||
spy3Memoized();
|
||||
console.debug(memoize.cacheStrategyItems);
|
||||
expect(memoize.cacheStrategyItems).to.deep.equal([
|
||||
{ fn: spy2Memoized, count: 4 },
|
||||
{ fn: spy3Memoized, count: 1 }, // we start over
|
||||
|
|
|
|||
Loading…
Reference in a new issue