From f6a5f107dcbe1f21c67986c73db243fdd1dc662f Mon Sep 17 00:00:00 2001 From: Kouadio Fabrice N'guessan <72697416+fabnguess@users.noreply.github.com> Date: Sun, 18 Aug 2024 21:59:01 +0000 Subject: [PATCH] refactor: migrate to TypeScript (#88) * chore: migrate to ts * refactor: complete migration --------- Co-authored-by: fraxken --- .eslintrc | 7 -- FLAGS.md | 57 +++++---- README.md | 2 +- eslint.config.mjs | 3 + index.d.ts | 2 - index.js | 2 - package.json | 115 ++++++++++--------- scripts/generateFlags.js | 36 ------ scripts/generateFlags.ts | 50 ++++++++ src/index.ts | 2 + src/{manifest.js => manifest.ts} | 13 ++- src/node.d.ts | 2 - src/node.js | 41 ------- src/node.ts | 45 ++++++++ src/web.js | 33 ------ src/web.ts | 51 ++++++++ test/fetchFlagFile.js | 40 ------- test/fetchFlagFile.spec.ts | 29 +++++ test/{getFlags.js => getFlags.spec.ts} | 2 +- test/{getManifest.js => getManifest.spec.ts} | 22 ++-- tsconfig.json | 20 ++++ web.d.ts | 35 ------ 22 files changed, 310 insertions(+), 299 deletions(-) delete mode 100644 .eslintrc create mode 100644 eslint.config.mjs delete mode 100644 index.d.ts delete mode 100644 index.js delete mode 100644 scripts/generateFlags.js create mode 100644 scripts/generateFlags.ts create mode 100644 src/index.ts rename src/{manifest.js => manifest.ts} (89%) delete mode 100644 src/node.d.ts delete mode 100644 src/node.js create mode 100644 src/node.ts delete mode 100644 src/web.js create mode 100644 src/web.ts delete mode 100644 test/fetchFlagFile.js create mode 100644 test/fetchFlagFile.spec.ts rename test/{getFlags.js => getFlags.spec.ts} (93%) rename test/{getManifest.js => getManifest.spec.ts} (84%) create mode 100644 tsconfig.json delete mode 100644 web.d.ts diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index cc12cba..0000000 --- a/.eslintrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "@nodesecure/eslint-config", - "parserOptions": { - "sourceType": "module", - "requireConfigFile": false - } -} diff --git a/FLAGS.md b/FLAGS.md index e12a365..cec121b 100644 --- a/FLAGS.md +++ b/FLAGS.md @@ -35,11 +35,11 @@ Documentation: [npm-install](https://docs.npmjs.com/cli/install) The package use a Node.js core package that allow to access the network. These core package are: -* \- http -* \- https -* \- net -* \- http2 -* \- dgram +* http +* https +* net +* http2 +* dgram ⚠️ This flag only work if the AST analysis as successfully retrieved all dependencies as expected. @@ -80,20 +80,7 @@ Minified JavaScript code are commonly used by hacker to obfuscate the code to av Example of minified code: -![](https://i.imgur.com/13Mxfb2.png) - -⚠️ sometimes one line file are considered minified (we are working to fix this in the future). - - - -Under the hood we use the npm package [is-minified-code](https://github.com/MartinKolarik/is-minified-code/). - - - -Files can be found in the **Minified Files** list items of the left menu. - - -![](https://i.imgur.com/e8BbBeb.png)
👀 hasMissingOrUnusedDependency +![](https://i.imgur.com/13Mxfb2.png)
👀 hasMissingOrUnusedDependency The package has a missing dependency (in package.json) or a dependency that is not used in the code (this may happen if the AST Analysis fail!) @@ -109,7 +96,7 @@ Example: ISC OR GPL-2.0-with-GCC-exception. -Under the hood we use [conformance](https://github.com/cutenode/conformance#readme) to parse licenses ! +Under the hood we use [@nodesecure/licenses-conformance](https://github.com/NodeSecure/licenses-conformance) to assert licenses conformance!
🐲 hasNativeCode @@ -119,9 +106,9 @@ The package use native components (package, file, configuration) like **binding. The flag is set to true if: -* \- One of the package file has an extension like .c, .cpp, .gyp (etc..) -* \- One of the package dependency is known for building native addons. -* \- The package.json file has the property "gypfile" set to **true**. +* One of the package file has an extension like .c, .cpp, .gyp (etc..) +* One of the package dependency is known for building native addons. +* The package.json file has the property "gypfile" set to **true**.
📜 hasNoLicense @@ -135,10 +122,6 @@ The code and logic behind the detection is handled in the [npm-tarball-license-p For more information on how license must be described in the package.json, please check the [npm documentation](https://docs.npmjs.com/files/package.json#license). - - -⚠️ we are working to stabilize this flag ! -
📦 hasScript The package has pre and/or post script in the **package.json** file. These script will be executed before or after the installation of a dependency (this is useful for example to build native addons or similar things). However these script may be used to execute malicious code on your system. @@ -148,7 +131,18 @@ The package has pre and/or post script in the **package.json** file. These scrip
🚨 Vulnerabilities -Vulnerabilities has been detected for the given package **version**. We are fetching vulnerabilities from the official [Node.js Security-WG repository](https://github.com/nodejs/security-wg) +Vulnerabilities has been detected for the given package **version**. We are fetching vulnerabilities from multiple sources using NodeSecure [vulnera](https://github.com/NodeSecure/vulnera). + + + +Available source are + +* GitHub Audit (previously NPM Audit) +* Sonatype DB +* Snyk +* Node.js Security-WG DB **(DEPRECATED)** + +We currently working to implement NVD and [OSV](https://osv.dev/).
⚠ hasWarnings @@ -180,6 +174,11 @@ Indicate that the package is **also used somewhere else in the dependency tree** The project has been detected as a GIT repository. Sometimes a dependency on the package.json link to a GIT repository, example: + + `{ "dependencies": { "zen-observable": "^0.8.15", "nanoid": "github:ai/nanoid", "js-x-ray": "git://github.com/NodeSecure/js-x-ray.git", "nanodelay": "git+ssh://git@github.com:ai/nanodelay.git", "nanoevents": "git+https://github.com/ai/nanoevents.git" } }` + + + ![](https://i.imgur.com/ww4UtyR.png) Because under the hood we use [pacote](https://github.com/npm/pacote#readme) to fetch and extract packages we are supporting this given pattern. @@ -196,4 +195,4 @@ This can happen, for example, when the package uses **tags** such as: * @beta * @next -
+ \ No newline at end of file diff --git a/README.md b/README.md index 4b4f194..71d847e 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ ## Requirements -- [Node.js](https://nodejs.org/en/) v18 or higher +- [Node.js](https://nodejs.org/en/) v20 or higher ## Getting Started diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..8a1e9d0 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,3 @@ +import { typescriptConfig } from "@openally/config.eslint"; + +export default typescriptConfig(); diff --git a/index.d.ts b/index.d.ts deleted file mode 100644 index a3b6179..0000000 --- a/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./src/node"; -export * from "./src/web"; diff --git a/index.js b/index.js deleted file mode 100644 index 0df76e6..0000000 --- a/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./src/node.js"; -export * from "./src/web.js"; diff --git a/package.json b/package.json index 76f482f..6112217 100644 --- a/package.json +++ b/package.json @@ -1,57 +1,58 @@ -{ - "name": "@nodesecure/flags", - "version": "2.4.0", - "description": "NodeSecure security flags", - "scripts": { - "test": "node --test test/", - "coverage": "c8 -r html npm test", - "lint": "eslint index.js", - "generateFlags": "node scripts/generateFlags.js" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/NodeSecure/flags.git" - }, - "keywords": [ - "nodesecure", - "flags", - "documentation" - ], - "exports": { - ".": { - "import": "./index.js" - }, - "./web": { - "types": "./web.d.ts", - "import": "./src/web.js" - }, - "./package.json": "./package.json" - }, - "types": "./index.d.ts", - "modes": { - "web": "src/web.js" - }, - "author": "GENTILHOMME Thomas ", - "files": [ - "index.d.ts", - "index.js", - "web.d.ts", - "src", - "FLAGS.md" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/NodeSecure/flags/issues" - }, - "homepage": "https://github.com/NodeSecure/flags#readme", - "devDependencies": { - "@nodesecure/eslint-config": "^1.8.0", - "c8": "^10.1.2", - "eslint": "^9.9.0", - "turndown": "^7.1.2" - }, - "type": "module", - "engines": { - "node": ">=18" - } -} +{ + "name": "@nodesecure/flags", + "version": "2.4.0", + "description": "NodeSecure security flags", + "scripts": { + "test": "glob -c \"tsx --test\" \"./test/**/*.spec.ts\"", + "coverage": "c8 -r html npm test", + "lint": "eslint index.js", + "generateFlags": "tsx scripts/generateFlags.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/NodeSecure/flags.git" + }, + "keywords": [ + "nodesecure", + "flags", + "documentation" + ], + "exports": { + ".": { + "import": "./index.js" + }, + "./web": { + "types": "./web.d.ts", + "import": "./src/web.js" + }, + "./package.json": "./package.json" + }, + "types": "./dist/index.d.ts", + "modes": { + "web": "src/web.js" + }, + "author": "GENTILHOMME Thomas ", + "files": [ + "dist" + ], + "license": "MIT", + "bugs": { + "url": "https://github.com/NodeSecure/flags/issues" + }, + "homepage": "https://github.com/NodeSecure/flags#readme", + "devDependencies": { + "@openally/config.eslint": "^1.0.0", + "@openally/config.typescript": "^1.0.3", + "@types/node": "^22.2.0", + "@types/turndown": "^5.0.5", + "c8": "^10.1.2", + "glob": "^11.0.0", + "tsx": "^4.17.0", + "turndown": "^7.1.2", + "typescript": "^5.5.4" + }, + "type": "module", + "engines": { + "node": ">=20" + } +} diff --git a/scripts/generateFlags.js b/scripts/generateFlags.js deleted file mode 100644 index 05e5298..0000000 --- a/scripts/generateFlags.js +++ /dev/null @@ -1,36 +0,0 @@ -// Import Node.js Dependencies -import path from "path"; -import fs from "fs/promises"; -import { fileURLToPath } from "url"; - -// Import Third-party Dependency -import TurndownService from "turndown"; - -// CONSTANTS -const __dirname = path.dirname(fileURLToPath(import.meta.url)); -const kRootPath = path.join(__dirname, ".."); -const kFlagsPath = path.join(kRootPath, "src", "flags"); - -const files = await fs.readdir(kFlagsPath); -const allFlagsContent = await Promise.all( - files.map((file) => fs.readFile(path.join(kFlagsPath, file))) -); - -const turndownService = new TurndownService(); - -turndownService.addRule("h1", { - filter: "h1", - replacement: (content) => `${content}` -}); - -turndownService.addRule("div", { - filter: "div", - replacement: (content) => `
${content}
` -}); - -const mdFile = turndownService.turndown(allFlagsContent.join("").toString()); - -const templateDocumentation = await fs.readFile( - path.join(__dirname, "template", "flagDocHeader.md"), "utf-8" -); -await fs.writeFile(path.join(kRootPath, "FLAGS.md"), templateDocumentation.toString().concat(mdFile)); diff --git a/scripts/generateFlags.ts b/scripts/generateFlags.ts new file mode 100644 index 0000000..5198e8f --- /dev/null +++ b/scripts/generateFlags.ts @@ -0,0 +1,50 @@ +// Import Node.js Dependencies +import path from "node:path"; +import fs from "node:fs/promises"; +import { fileURLToPath } from "node:url"; + +// Import Third-party Dependency +import TurndownService from "turndown"; + +// CONSTANTS +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const kRootPath = path.join(__dirname, ".."); + +const turndownService = new TurndownService(); + +turndownService.addRule("h1", { + filter: "h1", + replacement: (content) => `${content}` +}); +turndownService.addRule("div", { + filter: "div", + replacement: (content) => `
${content}
` +}); + +const { flags, headerTemplate } = await loadHTMLs(); +await fs.writeFile( + path.join(kRootPath, "FLAGS.md"), + headerTemplate.concat( + turndownService.turndown(flags) + ) +); + +async function loadHTMLs() { + const HTMLFlagsLocation = path.join(kRootPath, "src", "flags"); + const HTMLFlagsEntries = await fs.readdir(HTMLFlagsLocation); + + const [headerTemplate, ...HTMLFlagsFiles] = await Promise.all([ + fs.readFile( + path.join(__dirname, "template", "flagDocHeader.md"), + "utf-8" + ), + ...HTMLFlagsEntries.map( + (file) => fs.readFile(path.join(HTMLFlagsLocation, file), "utf-8") + ) + ]); + + return { + flags: HTMLFlagsFiles.join(""), + headerTemplate + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..1b0c867 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,2 @@ +export * from "./node.js"; +export * from "./web.js"; diff --git a/src/manifest.js b/src/manifest.ts similarity index 89% rename from src/manifest.js rename to src/manifest.ts index d93fbe8..ee52d4e 100644 --- a/src/manifest.js +++ b/src/manifest.ts @@ -1,6 +1,13 @@ -/* eslint-disable max-len */ +export type FlagDescriptor = { + /** An emoji to visually identify the anomaly **/ + emoji: string; + /** Title (or name) of the flag **/ + title: string; + /** Short description/warning of the anomaly **/ + tooltipDescription: string; +}; +export type Flag = keyof typeof FLAGS | (string & {}); -/** @type {flags.Manifest} **/ export const FLAGS = { externalCapacity: { emoji: "🌍", @@ -92,4 +99,4 @@ export const FLAGS = { title: "isDuplicated", tooltipDescription: "The package is also used somewhere else in the dependency tree but with a different version" } -}; +} satisfies Record; diff --git a/src/node.d.ts b/src/node.d.ts deleted file mode 100644 index e63d77b..0000000 --- a/src/node.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export function lazyFetchFlagFile(name: string): ReadableStream; -export function eagerFetchFlagFile(name: string): Promise; diff --git a/src/node.js b/src/node.js deleted file mode 100644 index 432d5ca..0000000 --- a/src/node.js +++ /dev/null @@ -1,41 +0,0 @@ -// Import Node.js Dependencies -import fs from "fs"; -import path from "path"; -import { fileURLToPath } from "url"; - -// Import Internal Dependencies -import { getFlags } from "./web.js"; - -// CONSTANTS -const __dirname = path.dirname(fileURLToPath(import.meta.url)); -const kFlagsPath = path.join(__dirname, "flags"); - -/** - * @description lazy read a flag file by getting a Node.js ReadableStream - * @param {!string} name flag (HTML File) name - */ -export function lazyFetchFlagFile(name) { - if (typeof name !== "string") { - throw new TypeError("You should provide a flag name"); - } - - const flags = getFlags(); - if (!flags.has(name)) { - throw new Error("There is no file associated with that name"); - } - - const fileName = path.extname(name) === ".html" ? name : `${name}.html`; - - return fs.createReadStream(path.join(kFlagsPath, fileName)); -} - -export async function eagerFetchFlagFile(name) { - const rStream = lazyFetchFlagFile(name); - let htmlStr = ""; - - for await (const chunk of rStream) { - htmlStr += chunk; - } - - return htmlStr; -} diff --git a/src/node.ts b/src/node.ts new file mode 100644 index 0000000..8096c37 --- /dev/null +++ b/src/node.ts @@ -0,0 +1,45 @@ +// Import Node.js Dependencies +import fs from "node:fs"; +import path from "node:path"; +import * as consumers from "node:stream/consumers"; +import { fileURLToPath } from "node:url"; +import { Readable } from "node:stream"; + +// Import Internal Dependencies +import { getFlags } from "./web.js"; + +// CONSTANTS +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const kFlagsPath = path.join(__dirname, "flags"); + +/** + * @description lazy read a flag file by getting a Node.js Readable Stream + */ +export function lazyFetchFlagFile( + name: string +): Readable { + if (typeof name !== "string") { + throw new TypeError("You should provide a flag name"); + } + + const flags = getFlags(); + if (!flags.has(name)) { + throw new Error("There is no file associated with that name"); + } + + const fileName = path.extname(name) === ".html" ? + name : + `${name}.html`; + + return fs.createReadStream( + path.join(kFlagsPath, fileName) + ); +} + +export function eagerFetchFlagFile( + name: string +): Promise { + return consumers.text( + lazyFetchFlagFile(name) + ); +} diff --git a/src/web.js b/src/web.js deleted file mode 100644 index 7f8fe2f..0000000 --- a/src/web.js +++ /dev/null @@ -1,33 +0,0 @@ -// Import Internal Dependencies -import { FLAGS } from "./manifest.js"; - -const kNotFoundFlags = "🔴"; -const kManifestEmoji = Object.fromEntries(getManifestEmoji()); - -/** - * @description Export src/manifest.json - */ -export function getManifest() { - return FLAGS; -} - -/** - * @example - * const kManifestEmoji = Object.fromEntries(getManifestEmoji()); - */ -export function* getManifestEmoji() { - for (const { emoji, title } of Object.values(FLAGS)) { - yield [title, emoji]; - } -} - -export function getEmojiFromTitle(title) { - return kManifestEmoji[title] ?? kNotFoundFlags; -} - -/** - * @description Complete list of flags title (as an ES6 Set) - */ -export function getFlags() { - return new Set(Object.values(FLAGS).map((flagDescriptor) => flagDescriptor.title)); -} diff --git a/src/web.ts b/src/web.ts new file mode 100644 index 0000000..8e779bc --- /dev/null +++ b/src/web.ts @@ -0,0 +1,51 @@ +// Import Internal Dependencies +import { + FLAGS, + type Flag, + type FlagDescriptor +} from "./manifest.js"; + +// CONSTANTS +const kNotFoundFlags = "🔴"; +const kManifestEmoji = Object.fromEntries( + getManifestEmoji() +); + +/** + * @description Export src/manifest.json + */ +export function getManifest() { + return structuredClone(FLAGS); +} + +/** + * @example + * const kManifestEmoji = Object.fromEntries(getManifestEmoji()); + */ +export function* getManifestEmoji(): IterableIterator<[string, string]> { + for (const { title, emoji } of Object.values(FLAGS)) { + yield [title, emoji]; + } +} + +export function getEmojiFromTitle( + title: Flag +): string { + return kManifestEmoji[title] ?? kNotFoundFlags; +} + +/** + * @description Complete list of flags title (as an ES6 Set) + */ +export function getFlags(): Set { + return new Set( + Object + .values(FLAGS) + .map((descriptor) => descriptor.title) + ); +} + +export type { + Flag, + FlagDescriptor +} diff --git a/test/fetchFlagFile.js b/test/fetchFlagFile.js deleted file mode 100644 index b2a51c6..0000000 --- a/test/fetchFlagFile.js +++ /dev/null @@ -1,40 +0,0 @@ -// Import Node.js Dependencies -import { describe, it } from "node:test"; -import assert from "node:assert"; - -// Import Internal Dependencies -import { getFlags, lazyFetchFlagFile } from "../index.js"; - -describe("lazyFetchFlagFile()", () => { - it("should throw an Error if no flag name is provided", () => { - try { - lazyFetchFlagFile(); - assert.fail("Should not get here since there is no flagName"); - } - catch (err) { - assert.equal(err.name, "TypeError"); - assert.equal(err.message, "You should provide a flag name"); - } - }); - it("should throw an Error if provided flags doesn't exist", () => { - try { - lazyFetchFlagFile("wrongFlagName"); - assert.fail("Should not get here since this is not a valid flagName"); - } - catch (err) { - assert.equal(err.name, "Error"); - assert.equal(err.message, "There is no file associated with that name"); - } - }); - it("should return a ReadableStream and every flags should have a valid html file", () => { - for (const flag of getFlags()) { - try { - const rStream = lazyFetchFlagFile(flag); - assert.equal(typeof rStream[Symbol.asyncIterator] === "function", true); - } - catch (err) { - assert.fail(err); - } - } - }); -}); diff --git a/test/fetchFlagFile.spec.ts b/test/fetchFlagFile.spec.ts new file mode 100644 index 0000000..cf8eb37 --- /dev/null +++ b/test/fetchFlagFile.spec.ts @@ -0,0 +1,29 @@ +// Import Node.js Dependencies +import { describe, it } from "node:test"; +import assert from "node:assert"; + +// Import Internal Dependencies +import { getFlags, lazyFetchFlagFile } from "../src/index.js"; + +describe("lazyFetchFlagFile()", () => { + it("should throw an Error if no flag name is provided", () => { + assert.throws(() => lazyFetchFlagFile(null as unknown as string), { + name: "TypeError", + message: "You should provide a flag name" + }); + }); + + it("should throw an Error if provided flags doesn't exist", () => { + assert.throws(() => lazyFetchFlagFile("wrongFlagName"), { + name: "Error", + message: "There is no file associated with that name" + }); + }); + + it("should return a ReadableStream and every flags should have a valid html file", () => { + for (const flag of getFlags()) { + const rStream = lazyFetchFlagFile(flag); + assert.strictEqual(typeof rStream[Symbol.asyncIterator], "function"); + } + }); +}); diff --git a/test/getFlags.js b/test/getFlags.spec.ts similarity index 93% rename from test/getFlags.js rename to test/getFlags.spec.ts index 8a271b0..cd6e31f 100644 --- a/test/getFlags.js +++ b/test/getFlags.spec.ts @@ -3,7 +3,7 @@ import { describe, it } from "node:test"; import assert from "node:assert"; // Import Internal Dependencies -import { getFlags, getManifest } from "../index.js"; +import { getFlags, getManifest } from "../src/index.js"; describe("getFlags()", () => { it("should return a Set with multiple flags", () => { diff --git a/test/getManifest.js b/test/getManifest.spec.ts similarity index 84% rename from test/getManifest.js rename to test/getManifest.spec.ts index 39c532a..e384815 100644 --- a/test/getManifest.js +++ b/test/getManifest.spec.ts @@ -3,15 +3,7 @@ import { describe, it } from "node:test"; import assert from "node:assert"; // Import Internal Dependencies -import { getManifest, getEmojiFromTitle, getManifestEmoji } from "../index.js"; - -function isFlagObject(flagObject) { - assert.equal(typeof flagObject, "object"); - - assert.equal("emoji" in flagObject, true); - assert.equal("title" in flagObject, true); - assert.equal("tooltipDescription" in flagObject, true); -} +import { getManifest, getEmojiFromTitle, getManifestEmoji, FlagDescriptor } from "../src/index.js"; describe("getManifest()", () => { it("should return a Record", () => { @@ -22,7 +14,7 @@ describe("getManifest()", () => { for (const [key, flagObject] of Object.entries(manifest)) { assert.equal(typeof key, "string"); - isFlagObject(flagObject); + assertFlagDescriptor(flagObject); } }); }); @@ -42,3 +34,13 @@ describe("getEmojiFromTitle()", () => { assert.equal(getEmojiFromTitle("hasNativeCode"), "🐲"); }); }); + +function assertFlagDescriptor( + flagObject: FlagDescriptor +): void { + assert.equal(typeof flagObject, "object"); + + assert.equal("emoji" in flagObject, true); + assert.equal("title" in flagObject, true); + assert.equal("tooltipDescription" in flagObject, true); +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..8382380 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "@openally/config.typescript", + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "types": [ + "node" + ], + }, + "include": [ + "src", + "src/flags/**.html" + ], + "exclude": [ + "node_modules", + "dist", + "eslint.config.mjs", + "scripts" + ] +} diff --git a/web.d.ts b/web.d.ts deleted file mode 100644 index c71819f..0000000 --- a/web.d.ts +++ /dev/null @@ -1,35 +0,0 @@ - -export type Flags = - "isGit" | - "isDeprecated" | - "isOutdated" | - "hasNativeCode" | - "hasManifest" | - "hasOutdatedDependency" | - "hasWarnings" | - "hasNoLicense" | - "hasMultipleLicenses" | - "hasMissingOrUnusedDependency" | - "hasMinifiedCode" | - "hasIndirectDependencies" | - "hasCustomResolver" | - "hasDependencies" | - "hasExternalCapacity" | - "hasScript" | - "hasBannedFile"; - -export interface FlagObject { - /** An emoji to visually identify the anomaly **/ - emoji: string; - /** Title (or name) of the flag **/ - title: string; - /** Short description/warning of the anomaly **/ - tooltipDescription: string; -} - -export type Manifest = Record; - -export function getManifest(): Manifest; -export function getManifestEmoji(): IterableIterator<[Flags, string]>; -export function getEmojiFromTitle(title: Flags): string; -export function getFlags(): Record;