From 7148100d9c0ad63cf8717366c9eff9a3dd20943b Mon Sep 17 00:00:00 2001 From: fraxken Date: Wed, 15 May 2024 15:21:41 +0200 Subject: [PATCH] refactor: implement API exports & minimal docs --- README.md | 23 +++++++++--- docs/api/AstAnalyser.md | 66 ++++++++++++++++++++++++++++++++++ docs/api/EntryFilesAnalyser.md | 38 ++++++++++++++++++++ index.d.ts | 2 ++ index.js | 5 ++- types/api.d.ts | 7 +++- 6 files changed, 134 insertions(+), 7 deletions(-) create mode 100644 docs/api/AstAnalyser.md create mode 100644 docs/api/EntryFilesAnalyser.md diff --git a/README.md b/README.md index 1255b95..4cf9754 100644 --- a/README.md +++ b/README.md @@ -67,11 +67,13 @@ require(Buffer.from("6673", "hex").toString()); Then use `js-x-ray` to run an analysis of the JavaScript code: ```js -import { runASTAnalysis } from "@nodesecure/js-x-ray"; +import { AstAnalyser } from "@nodesecure/js-x-ray"; import { readFileSync } from "node:fs"; -const { warnings, dependencies } = runASTAnalysis( - readFileSync("./file.js", "utf-8") +const scanner = new AstAnalyser(); + +const { warnings, dependencies } = await scanner.analyseFile( + "./file.js" ); console.log(dependencies); @@ -174,11 +176,16 @@ You can pass an array of probes to the `runASTAnalysis/runASTAnalysisOnFile` fun Here using the example probe upper: ```ts -import { runASTAnalysis } from "@nodesecure/js-x-ray"; +import { AstAnalyser } from "@nodesecure/js-x-ray"; // add your customProbes here (see example above) -const result = runASTAnalysis("const danger = 'danger';", { customProbes, skipDefaultProbes: true }); +const scanner = new AstAnalyser({ + customProbes, + skipDefaultProbes: true +}); + +const result = scanner.analyse("const danger = 'danger';"); console.log(result); ``` @@ -202,6 +209,12 @@ Congrats, you have created your first custom probe! 🎉 > Check the types in [index.d.ts](index.d.ts) and [types/api.d.ts](types/api.d.ts) for more details about the `options` ## API + +- [AstAnalyser](./docs/api/AstAnalyser.md) +- [EntryFilesAnalyser](./docs/api/EntryFilesAnalyser.md) + +Legacy APIs waiting to be deprecated; +
runASTAnalysis(str: string, options?: RuntimeOptions & AstAnalyserOptions): Report diff --git a/docs/api/AstAnalyser.md b/docs/api/AstAnalyser.md new file mode 100644 index 0000000..557325f --- /dev/null +++ b/docs/api/AstAnalyser.md @@ -0,0 +1,66 @@ +# AstAnalyser + +```js +import { AstAnalyser } from "@nodesecure/js-x-ray"; +import { TsSourceParser } from "@nodesecure/ts-source-parser"; + +const scanner = new AstAnalyser({ + customParser: new TsSourceParser() +}); + +const result = scanner.analyse("const x: number = 5;"); +console.log(result); +``` + +AstAnalyser options is described by the following TS interface: + +```ts +interface AstAnalyserOptions { + /** + * @default JsSourceParser + */ + customParser?: SourceParser; + /** + * @default [] + */ + customProbes?: Probe[]; + /** + * @default false + */ + skipDefaultProbes?: boolean; +} +``` + +By default the AstAnalyser class is capable of parsing JavaScript source code using Meriyah. + +## API + +```ts +declare class AstAnalyser { + constructor(options?: AstAnalyserOptions); + analyse: (str: string, options?: RuntimeOptions) => Report; + analyseFile(pathToFile: string, options?: RuntimeFileOptions): Promise; +} +``` + +The `analyseFile` method is a superset of `analyse` with the ability to read the file on the local filesystem with additional features like detecting if the file is ESM or CJS. + +```ts +interface Report { + dependencies: Map; + warnings: Warning[]; + idsLengthAvg: number; + stringScore: number; + isOneLineRequire: boolean; +} + +type ReportOnFile = { + ok: true, + warnings: Warning[]; + dependencies: Map; + isMinified: boolean; +} | { + ok: false, + warnings: Warning[]; +} +``` diff --git a/docs/api/EntryFilesAnalyser.md b/docs/api/EntryFilesAnalyser.md new file mode 100644 index 0000000..dcff432 --- /dev/null +++ b/docs/api/EntryFilesAnalyser.md @@ -0,0 +1,38 @@ +# EntryFilesAnalyser + +```js +import { EntryFilesAnalyser } from "@nodesecure/js-x-ray"; + +const efa = new EntryFilesAnalyser(); + +// Either a string path or a WHAWG URL +const entryFiles = [ + "./path/to/file.js" +]; + +for await (const report of efa.analyse(entryFiles)) { + console.log(report); +} +``` + +The constructor options is described by the following TS interface + +```ts +interface EntryFilesAnalyserOptions { + astAnalyzer?: AstAnalyser; + loadExtensions?: (defaults: string[]) => string[]; +} +``` + +Default files extensions are `.js`, `.cjs`, `.mjs` and `.node` + +## API + +```ts +declare class EntryFilesAnalyser { + constructor(options?: EntryFilesAnalyserOptions); + analyse(entryFiles: (string | URL)[]): AsyncGenerator; +} +``` + +For more informations about `Report` and `ReportOnFile` interfaces please see [AstAnalyser documentation](./AstAnalyser.md) diff --git a/index.d.ts b/index.d.ts index cb75030..6a46095 100644 --- a/index.d.ts +++ b/index.d.ts @@ -6,6 +6,7 @@ import { EntryFilesAnalyserOptions, SourceParser, + JsSourceParser, runASTAnalysis, runASTAnalysisOnFile, Report, @@ -31,6 +32,7 @@ export { AstAnalyserOptions, EntryFilesAnalyser, EntryFilesAnalyserOptions, + JsSourceParser, SourceParser, runASTAnalysis, runASTAnalysisOnFile, diff --git a/index.js b/index.js index 0702198..9241d2d 100644 --- a/index.js +++ b/index.js @@ -2,6 +2,7 @@ import { warnings } from "./src/warnings.js"; import { JsSourceParser } from "./src/JsSourceParser.js"; import { AstAnalyser } from "./src/AstAnalyser.js"; +import { EntryFilesAnalyser } from "./src/EntryFilesAnalyser.js"; function runASTAnalysis( str, @@ -28,8 +29,8 @@ async function runASTAnalysisOnFile( options = {} ) { const { - customParser = new JsSourceParser(), customProbes = [], + customParser = new JsSourceParser(), skipDefaultProbes = false, ...opts } = options; @@ -46,6 +47,8 @@ async function runASTAnalysisOnFile( export { warnings, AstAnalyser, + EntryFilesAnalyser, + JsSourceParser, runASTAnalysis, runASTAnalysisOnFile }; diff --git a/types/api.d.ts b/types/api.d.ts index 6d556d5..255ce7b 100644 --- a/types/api.d.ts +++ b/types/api.d.ts @@ -4,8 +4,11 @@ import { Statement } from "meriyah/dist/src/estree.js"; export { AstAnalyser, AstAnalyserOptions, + EntryFilesAnalyser, EntryFilesAnalyserOptions, + + JsSourceParser, SourceParser, runASTAnalysis, runASTAnalysisOnFile, @@ -101,7 +104,7 @@ interface SourceParser { declare class AstAnalyser { constructor(options?: AstAnalyserOptions); analyse: (str: string, options?: RuntimeOptions) => Report; - analyzeFile(pathToFile: string, options?: RuntimeFileOptions): Promise; + analyseFile(pathToFile: string, options?: RuntimeFileOptions): Promise; } interface EntryFilesAnalyserOptions { @@ -118,5 +121,7 @@ declare class EntryFilesAnalyser { analyse(entryFiles: (string | URL)[]): AsyncGenerator; } +declare class JsSourceParser implements SourceParser {} + declare function runASTAnalysis(str: string, options?: RuntimeOptions & AstAnalyserOptions): Report; declare function runASTAnalysisOnFile(pathToFile: string, options?: RuntimeFileOptions & AstAnalyserOptions): Promise;