From e7b1cf16f5252aa220e073a06adbd15170172727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kol=C3=A1rik?= Date: Mon, 16 May 2022 20:17:23 +0200 Subject: [PATCH] feat: add isSecurityHeld flag (#657) --- README.md | 1 + src/@types/pkg.ts | 1 + .../__snapshots__/formatPkg.test.ts.snap | 80 +++++++++++++++++++ src/__tests__/formatPkg.test.ts | 30 ++++++- src/config.ts | 2 + src/formatPkg.ts | 3 + 6 files changed, 116 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1c38a5b00..dca64322e 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,7 @@ For every single NPM package, we create a record in the Algolia index. The resul deprecated: 'Deprecated', // This field will be removed, please use `isDeprecated` instead isDeprecated: true, deprecatedReason: 'Deprecated', + isSecurityHeld: false, // See https://github.com/npm/security-holder badPackage: false, homepage: 'https://babeljs.io/', license: 'MIT', diff --git a/src/@types/pkg.ts b/src/@types/pkg.ts index 4e802a237..be153a68b 100644 --- a/src/@types/pkg.ts +++ b/src/@types/pkg.ts @@ -64,6 +64,7 @@ export interface RawPkg { deprecated: boolean | string; isDeprecated: boolean; deprecatedReason: string | null; + isSecurityHeld: boolean; homepage: string | null; license: string | null; keywords: string[]; diff --git a/src/__tests__/__snapshots__/formatPkg.test.ts.snap b/src/__tests__/__snapshots__/formatPkg.test.ts.snap index 7ccdac291..5ae445975 100644 --- a/src/__tests__/__snapshots__/formatPkg.test.ts.snap +++ b/src/__tests__/__snapshots__/formatPkg.test.ts.snap @@ -31,6 +31,7 @@ Object { "homepage": null, "humanDownloadsLast30Days": "0", "isDeprecated": true, + "isSecurityHeld": false, "keywords": Array [], "lastCrawl": Any, "lastPublisher": null, @@ -111,6 +112,7 @@ Object { "homepage": "https://bitbucket.org/atlassian/atlaskit#readme", "humanDownloadsLast30Days": "0", "isDeprecated": false, + "isSecurityHeld": false, "keywords": Array [ "atlaskit", "ui", @@ -337,6 +339,7 @@ Object { "homepage": null, "humanDownloadsLast30Days": "0", "isDeprecated": false, + "isSecurityHeld": false, "keywords": Array [], "lastCrawl": Any, "lastPublisher": Object { @@ -467,6 +470,7 @@ Object { "homepage": null, "humanDownloadsLast30Days": "0", "isDeprecated": false, + "isSecurityHeld": false, "keywords": Array [ "algolia", "instantsearch", @@ -557,6 +561,7 @@ Object { "homepage": null, "humanDownloadsLast30Days": "0", "isDeprecated": false, + "isSecurityHeld": false, "keywords": Array [ "index", "array", @@ -667,6 +672,7 @@ Object { "homepage": null, "humanDownloadsLast30Days": "0", "isDeprecated": false, + "isSecurityHeld": false, "keywords": Array [ "prism", "highlight", @@ -858,6 +864,7 @@ Object { "homepage": null, "humanDownloadsLast30Days": "0", "isDeprecated": false, + "isSecurityHeld": false, "keywords": Array [], "lastCrawl": Any, "lastPublisher": null, @@ -1537,3 +1544,76 @@ QE+S ], } `; + +exports[`security held log security held flag 1`] = ` +Object { + "_searchInternal": Object { + "alternativeNames": Array [ + "0", + "0.js", + "0js", + ], + "expiresAt": Any, + }, + "bin": Object {}, + "computedKeywords": Array [], + "computedMetadata": Object {}, + "created": NaN, + "dependencies": Object {}, + "deprecated": false, + "deprecatedReason": null, + "description": null, + "devDependencies": Object {}, + "downloadsLast30Days": 0, + "downloadsRatio": 0, + "gitHead": null, + "githubRepo": null, + "homepage": null, + "humanDownloadsLast30Days": "0", + "isDeprecated": false, + "isSecurityHeld": true, + "keywords": Array [], + "lastCrawl": Any, + "lastPublisher": null, + "license": null, + "modified": NaN, + "moduleTypes": Array [ + "unknown", + ], + "name": "0", + "objectID": "0", + "originalAuthor": Object { + "name": "npm", + }, + "owner": Object { + "avatar": "https://github.com/npm.png", + "link": "https://github.com/npm", + "name": "npm", + }, + "owners": Array [], + "popular": false, + "readme": "", + "repository": Object { + "branch": "master", + "head": undefined, + "host": "github.com", + "path": "", + "project": "security-holder", + "type": "git", + "url": "npm/security-holder", + "user": "npm", + }, + "rev": Any, + "styleTypes": Array [], + "tags": Object { + "latest": "1.2.3", + }, + "types": Object { + "ts": Object { + "possible": true, + }, + }, + "version": "0.0.0", + "versions": Object {}, +} +`; diff --git a/src/__tests__/formatPkg.test.ts b/src/__tests__/formatPkg.test.ts index 2545cec6a..24d04d914 100644 --- a/src/__tests__/formatPkg.test.ts +++ b/src/__tests__/formatPkg.test.ts @@ -8,7 +8,7 @@ import { getVersions, getExportKeys, } from '../formatPkg'; -import type { GetPackage } from '../npm/types'; +import type { GetPackage, PackageRepo } from '../npm/types'; import preact from './preact-simplified.json'; import rawPackages from './rawPackages.json'; @@ -859,3 +859,31 @@ describe('deprecated', () => { }); }); }); + +describe('security held', () => { + it('log security held flag', () => { + const pkg: GetPackage = { + ...BASE, + 'dist-tags': { + latest: '1.2.3', + }, + versions: { + '1.2.3': { + ...BASE_VERSION, + }, + }, + repository: 'npm/security-holder' as unknown as PackageRepo, + author: { name: 'npm' }, + }; + const formatted = formatPkg(pkg); + + expect(formatted).toMatchSnapshot({ + rev: expect.any(String), + lastCrawl: expect.any(String), + isSecurityHeld: true, + _searchInternal: { + expiresAt: expect.any(Number), + }, + }); + }); +}); diff --git a/src/config.ts b/src/config.ts index 42c3e71d2..167f5da83 100644 --- a/src/config.ts +++ b/src/config.ts @@ -18,6 +18,7 @@ const indexSettings: Settings = { '_searchInternal.expiresAt', 'deprecated', 'isDeprecated', + 'isSecurityHeld', 'types.ts', 'moduleTypes', 'styleTypes', @@ -38,6 +39,7 @@ const indexSettings: Settings = { 'words', 'proximity', 'attribute', + 'asc(isSecurityHeld)', 'asc(deprecated)', 'asc(isDeprecated)', 'asc(badPackage)', diff --git a/src/formatPkg.ts b/src/formatPkg.ts index 1e08022db..4ac929bca 100644 --- a/src/formatPkg.ts +++ b/src/formatPkg.ts @@ -146,6 +146,8 @@ export function formatPkg(pkg: GetPackage): RawPkg | undefined { const tags = pkg['dist-tags']; const isDeprecated = cleaned.deprecated !== undefined && cleaned.deprecated !== false; + const isSecurityHeld = + repository?.user === 'npm' && repository?.project === 'security-holder'; const rawPkg: RawPkg = { objectID: cleaned.name, @@ -170,6 +172,7 @@ export function formatPkg(pkg: GetPackage): RawPkg | undefined { deprecated: isDeprecated ? cleaned.deprecated! : false, isDeprecated, deprecatedReason: isDeprecated ? String(cleaned.deprecated) : null, + isSecurityHeld, homepage: getHomePage(cleaned), license, keywords,