From f5facbe988e2d9085e87b4e888f96905030a1746 Mon Sep 17 00:00:00 2001 From: OmarCastro Date: Fri, 1 Apr 2022 19:43:36 +0100 Subject: [PATCH 01/20] feat: create package name filter --- .../packages/package-name-filter.test.ts | 76 ++++++++++++ src/packages/package-name-filter.ts | 114 ++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 __tests__/packages/package-name-filter.test.ts create mode 100644 src/packages/package-name-filter.ts diff --git a/__tests__/packages/package-name-filter.test.ts b/__tests__/packages/package-name-filter.test.ts new file mode 100644 index 00000000..4fc450c9 --- /dev/null +++ b/__tests__/packages/package-name-filter.test.ts @@ -0,0 +1,76 @@ +import { getPackageNameFilter } from '../../src/packages' + +describe('package name filter -- create filter', () => { + + const packageNameList = [ + 'com.company.project.module1.package1', + 'com.company.project.module1.package2', + 'com.company.project.module2.package1', + 'com.company.project.module2.package2', + 'com.company.project.module3.package-name-lorem', + 'com.company.project.module3.package-name-ipsum', + 'com.company.project.module3.package-name-dolor', + ] + + it('getPackageNameFilter -- wildcard filter', done => { + const filter = getPackageNameFilter('com.company.project.module1.*') + + const result = packageNameList.filter(filter.apply); + + expect(filter.subfilters[0].type).toBe('wildcard') + expect(result).toEqual([ + 'com.company.project.module1.package1', + 'com.company.project.module1.package2', + ]) + done() + }) + + it('getPackageNameFilter -- regex filter', done => { + const filter = getPackageNameFilter('/com\\.company\\.project\\.module.*\\.package1/') + const result = packageNameList.filter(filter.apply); + + expect(filter.subfilters[0].type).toBe('regex') + expect(result).toEqual([ + 'com.company.project.module1.package1', + 'com.company.project.module2.package1', + ]) + done() + }) + + it('getPackageNameFilter -- exact match filter', done => { + const filter = getPackageNameFilter('com.company.project.module1.package1') + const result = packageNameList.filter(filter.apply); + + expect(filter.subfilters[0].type).toBe('string') + expect(result).toEqual(['com.company.project.module1.package1']) + done() + }) + + + it('getPackageNameFilter -- multiple filters', done => { + const filter = getPackageNameFilter('com.company.project.module1.package1, com.company.project.module2.*, /.*module3.*-ipsum/') + const result = packageNameList.filter(filter.apply); + + expect(filter.subfilters.length).toBe(3) + expect(filter.subfilters[0].type).toBe('string') + expect(filter.subfilters[1].type).toBe('wildcard') + expect(filter.subfilters[2].type).toBe('regex') + expect(result).toEqual([ + 'com.company.project.module1.package1', + 'com.company.project.module2.package1', + 'com.company.project.module2.package2', + 'com.company.project.module3.package-name-ipsum' + ]) + done() + }) + + + it('getPackageNameFilter -- memoization, same input shoud return same output', done => { + const filterText = 'com.company.project.module1.package1, com.company.project.module2.*, /.*module3.*-dolor/, *.-lorem' + const filter1 = getPackageNameFilter(filterText) + const filter2 = getPackageNameFilter(filterText) + expect(filter1).toBe(filter2) + expect(filter1.subfilters.length).toBe(4) + done() + }) + }) \ No newline at end of file diff --git a/src/packages/package-name-filter.ts b/src/packages/package-name-filter.ts new file mode 100644 index 00000000..1e5a7d98 --- /dev/null +++ b/src/packages/package-name-filter.ts @@ -0,0 +1,114 @@ +/** + * Used to apply memoization on getPackageNameFilter + */ +const resultCache = {} as Record + +interface PackageNameSubFilter { + type: 'regex' | 'wildcard' | 'string' + apply: (packageName: string) => boolean +} + +interface PackageNamesFilter { + readonly subfilters: readonly PackageNameSubFilter[] + readonly isEmpty: boolean + readonly apply: (packageName: string) => boolean +} + + +/** + * Get a filter based on package names to match + * + * @param packageNames - serialized package names filter as string + * @returns the respective package filter + */ +export function getPackageNameFilter(packageNames: string) : PackageNamesFilter { + if(resultCache[packageNames] ){ + return resultCache[packageNames] + } + const result = calculatePackageNameFilter(packageNames) + resultCache[packageNames] = result + return result +} + +const emptyFilter = Object.freeze({ + subfilters: Object.freeze([]), + isEmpty: true, + apply:() => false as boolean +}) + +/** + * Generates a filter based package names to match + * + * @param packageNames - serialized package names filter as string + * @returns the respective package filter + */ +function calculatePackageNameFilter(packageNames: string): Readonly { + if(packageNames === ""){ + return emptyFilter; + } + const separatedPackageNames = packageNames + .split(",") + .map(packageName => packageName.trim()) + .filter(packageNames => packageNames !== "") + + + if (separatedPackageNames.length <= 0){ + return emptyFilter; + } + + const subfilters = separatedPackageNames.map(createFilter) + return { + subfilters, + isEmpty: subfilters.length <= 0, + apply:(packageNames) => subfilters.some(filter => filter.apply(packageNames)) + } + +} + + +function createFilter(packageName: string): PackageNameSubFilter { + if(packageName.startsWith('*') || packageName.endsWith('*')){ + return createWildcardFilter(packageName) + } else if(packageName.startsWith("/") && packageName.endsWith("/")){ + return createRegexFilter(packageName) + } else { + return createExactMatchFilter(packageName) + } +} + +function createWildcardFilter(wildcardPackageName: string): PackageNameSubFilter { + const startsWithWildCard = wildcardPackageName.startsWith('*') + const endsWithWildCard = wildcardPackageName.endsWith('*') + let fn: PackageNameSubFilter["apply"] + if(startsWithWildCard && endsWithWildCard){ + const targetText = wildcardPackageName.substring(1, wildcardPackageName.length - 1) + fn = (packageName: string) => packageName.includes(targetText) + } else if(startsWithWildCard){ + const targetText = wildcardPackageName.substring(1) + fn = (packageName: string) => packageName.endsWith(targetText) + } else { + const targetText = wildcardPackageName.substring(0, wildcardPackageName.length - 1) + fn = (packageName: string) => packageName.startsWith(targetText) + } + return { + type: 'wildcard', + apply: fn + } +} + +function createRegexFilter(regexPackageName: string): PackageNameSubFilter { + const regexPattern = regexPackageName.substring(1, regexPackageName.length - 1) + const regex = new RegExp(regexPattern) + return { + type: 'regex', + apply: (packageName: string) => regex.test(packageName) + } +} + +function createExactMatchFilter(matchingPackageName: string): PackageNameSubFilter { + return { + type: 'string', + apply: (packageName: string) => packageName === matchingPackageName + } + +} \ No newline at end of file From 8a81d7ab189acebcf662e1ae8847d0922782a428 Mon Sep 17 00:00:00 2001 From: OmarCastro Date: Fri, 1 Apr 2022 19:45:12 +0100 Subject: [PATCH 02/20] feat: add query for repo packages --- src/packages/get-packages.ts | 168 +++++++++++++++++++++++++++++++++++ src/packages/graphql.ts | 20 +++++ src/packages/index.ts | 2 + 3 files changed, 190 insertions(+) create mode 100644 src/packages/get-packages.ts create mode 100644 src/packages/graphql.ts create mode 100644 src/packages/index.ts diff --git a/src/packages/get-packages.ts b/src/packages/get-packages.ts new file mode 100644 index 00000000..961996d3 --- /dev/null +++ b/src/packages/get-packages.ts @@ -0,0 +1,168 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import {GraphQlQueryResponse} from '@octokit/graphql/dist-types/types' +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import {Observable, from, throwError} from 'rxjs' +import {catchError, map} from 'rxjs/operators' +import {graphql} from './graphql' + +export interface PackageInfo { + id: string + name: string +} + +export interface QueryInfo { + packages: PackageInfo[] + cursor: string + paginate: boolean + totalCount: number +} + +export interface GetPackagesQueryResponse { + repository: { + packages: { + totalCount: number + edges: {node: PackageInfo}[] + pageInfo: { + endCursor: string + hasNextPage: boolean + } + } + } +} + +const query = ` + query getPackages($owner: String!, $name: String!, $first: Int!){ + repository(owner: $owner, name: $name) { + packages(first:$first){ + totalCount + edges { + node { + name + id + } + } + pageInfo { + endCursor + hasNextPage + } + } + } + }` + +const Paginatequery = ` + query getPackages($owner: String!, $name: String!, $first: Int!, $after: String!){ + repository(owner: $owner, name: $name) { + packages(first:$first){ + totalCount + edges { + node { + name + id + } + } + pageInfo { + endCursor + hasNextPage + } + } + } + }` + +export function queryForRepoPackages( + owner: string, + repo: string, + numPackages: number, + startCursor: string, + token: string +): Observable { + if (startCursor === '') { + return from( + graphql(token, query, { + owner, + repo, + first: numPackages, + headers: { + Accept: 'application/vnd.github.packages-preview+json' + } + }) as Promise + ).pipe( + catchError((err: GraphQlQueryResponse) => { + const msg = 'query for packages failed.' + return throwError( + err.errors && err.errors.length > 0 + ? `${msg} ${err.errors[0].message}` + : `${msg} verify input parameters are correct ${JSON.stringify(err, null, 2)}` + ) + }) + ) + } else { + return from( + graphql(token, Paginatequery, { + owner, + repo, + first: numPackages, + before: startCursor, + headers: { + Accept: 'application/vnd.github.packages-preview+json' + } + }) as Promise + ).pipe( + catchError((err: GraphQlQueryResponse) => { + const msg = 'query for packages failed.' + return throwError( + err.errors && err.errors.length > 0 + ? `${msg} ${err.errors[0].message}` + : `${msg} verify input parameters are correct` + ) + }) + ) + } +} + +export function getRepoPackages( + owner: string, + repo: string, + numPackages: number, + startCursor: string, + token: string +): Observable { + return queryForRepoPackages( + owner, + repo, + numPackages, + startCursor, + token + ).pipe( + map(result => { + let r: QueryInfo + if (result.repository.packages.edges.length < 1) { + console.log( + `package: No packages found for owner: ${owner} in repo: ${repo}` + ) + r = { + packages: [] as PackageInfo[], + cursor: '', + paginate: false, + totalCount: 0 + } + return r + } + + const packages = result.repository.packages.edges + const pages = result.repository.packages.pageInfo + const count = result.repository.packages.totalCount + + r = { + packages: packages.map(value => ({ + id: value.node.id, + name: value.node.name + })), + cursor: pages.endCursor, + paginate: pages.hasNextPage, + totalCount: count + } + + return r + }) + ) +} diff --git a/src/packages/graphql.ts b/src/packages/graphql.ts new file mode 100644 index 00000000..cb6b2ede --- /dev/null +++ b/src/packages/graphql.ts @@ -0,0 +1,20 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import {GitHub} from '@actions/github' +import {GraphQlQueryResponseData} from '@octokit/graphql/dist-types/types' +import {RequestParameters} from '@octokit/types/dist-types/RequestParameters' + +/** + * Sends a GraphQL query request based on endpoint options + * + * @param {string} token Auth token + * @param {string} query GraphQL query. Example: `'query { viewer { login } }'`. + * @param {object} parameters URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`. + */ +export async function graphql( + token: string, + query: string, + parameters: RequestParameters +): Promise { + const github = new GitHub(token) + return await github.graphql(query, parameters) +} diff --git a/src/packages/index.ts b/src/packages/index.ts new file mode 100644 index 00000000..eadf04e4 --- /dev/null +++ b/src/packages/index.ts @@ -0,0 +1,2 @@ +export * from './get-packages' +export * from './package-name-filter' From 31e12b6293c20a053e3219766addd1e585366d0e Mon Sep 17 00:00:00 2001 From: OmarCastro Date: Fri, 1 Apr 2022 19:46:37 +0100 Subject: [PATCH 03/20] test: add packages query tests --- __tests__/packages/get-packages.test.ts | 66 +++++++++++++++++++++++++ __tests__/packages/graphql.mock.ts | 45 +++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 __tests__/packages/get-packages.test.ts create mode 100644 __tests__/packages/graphql.mock.ts diff --git a/__tests__/packages/get-packages.test.ts b/__tests__/packages/get-packages.test.ts new file mode 100644 index 00000000..27672257 --- /dev/null +++ b/__tests__/packages/get-packages.test.ts @@ -0,0 +1,66 @@ +import {mockPackagesQueryResponse} from './graphql.mock' +import { + getRepoPackages as _getRepoPackages, + QueryInfo +} from '../../src/packages' +import {Observable} from 'rxjs' + +describe.skip('get versions tests -- call graphql', () => { + it('getRepoPackages -- succeeds', done => { + const numPackages = 1 + getRepoPackages({numPackages}).subscribe(result => { + expect(result.packages.length).toBe(numPackages) + done() + }) + }) + + it('getRepoPackages -- fails for invalid repo', done => { + getRepoPackages({repo: 'actions-testin'}).subscribe({ + error: err => { + expect(err).toBeTruthy() + done() + }, + complete: async () => done.fail('no error thrown') + }) + }) + }) + + describe('get versions tests -- mock graphql', () => { + it('getRepoPackages -- success', done => { + const numPackages = 5 + mockPackagesQueryResponse(numPackages) + + getRepoPackages({numPackages}).subscribe(result => { + expect(result.packages.length).toBe(numPackages) + done() + }) + }) + }) + + interface Params { + owner?: string + repo?: string + numPackages?: number + startCursor?: string + token?: string + } + + const defaultParams = { + owner: 'namratajha', + repo: 'test-repo', + packageName: 'test-repo', + numPackages: 1, + startCursor: '', + token: process.env.GITHUB_TOKEN as string + } + + function getRepoPackages(params?: Params): Observable { + const p: Required = {...defaultParams, ...params} + return _getRepoPackages( + p.owner, + p.repo, + p.numPackages, + p.startCursor, + p.token + ) + } \ No newline at end of file diff --git a/__tests__/packages/graphql.mock.ts b/__tests__/packages/graphql.mock.ts new file mode 100644 index 00000000..c037dbbb --- /dev/null +++ b/__tests__/packages/graphql.mock.ts @@ -0,0 +1,45 @@ +import { + GraphQlQueryResponseData, + RequestParameters +} from '@octokit/graphql/dist-types/types' + +import * as Graphql from '../../src/packages/graphql' +import {GetPackagesQueryResponse} from '../../src/packages' + +export function getMockedPackagesQueryResponse( + numPackages: number +): GetPackagesQueryResponse { + const packages = [] + for (let i = 1; i <= numPackages; ++i) { + packages.push({ + node: { + id: i.toString(), + name: `package${i}` + } + }) + } + + return { + repository: { + packages: { + totalCount: 200, + pageInfo: { + endCursor: 'AAA', + hasNextPage: false + }, + edges: packages + } + } + } +} + +export function mockPackagesQueryResponse(numVersions: number): void { + const response = new Promise(resolve => { + resolve(getMockedPackagesQueryResponse(numVersions)) + }) as Promise + jest + .spyOn(Graphql, 'graphql') + .mockImplementation( + (token: string, query: string, parameters: RequestParameters) => response + ) +} From 4513f31cc89d2117659cdff40a7562bc89372961 Mon Sep 17 00:00:00 2001 From: OmarCastro Date: Fri, 1 Apr 2022 19:56:36 +0100 Subject: [PATCH 04/20] chore: lint code --- src/packages/get-packages.ts | 6 +- src/packages/package-name-filter.ts | 162 +++++++++++++++------------- 2 files changed, 91 insertions(+), 77 deletions(-) diff --git a/src/packages/get-packages.ts b/src/packages/get-packages.ts index 961996d3..bc916706 100644 --- a/src/packages/get-packages.ts +++ b/src/packages/get-packages.ts @@ -91,7 +91,11 @@ export function queryForRepoPackages( return throwError( err.errors && err.errors.length > 0 ? `${msg} ${err.errors[0].message}` - : `${msg} verify input parameters are correct ${JSON.stringify(err, null, 2)}` + : `${msg} verify input parameters are correct ${JSON.stringify( + err, + null, + 2 + )}` ) }) ) diff --git a/src/packages/package-name-filter.ts b/src/packages/package-name-filter.ts index 1e5a7d98..5e71ca54 100644 --- a/src/packages/package-name-filter.ts +++ b/src/packages/package-name-filter.ts @@ -4,111 +4,121 @@ const resultCache = {} as Record interface PackageNameSubFilter { - type: 'regex' | 'wildcard' | 'string' - apply: (packageName: string) => boolean + type: 'regex' | 'wildcard' | 'string' + apply: (packageName: string) => boolean } interface PackageNamesFilter { - readonly subfilters: readonly PackageNameSubFilter[] - readonly isEmpty: boolean - readonly apply: (packageName: string) => boolean + readonly subfilters: readonly PackageNameSubFilter[] + readonly isEmpty: boolean + readonly apply: (packageName: string) => boolean } - /** * Get a filter based on package names to match - * + * * @param packageNames - serialized package names filter as string * @returns the respective package filter */ -export function getPackageNameFilter(packageNames: string) : PackageNamesFilter { - if(resultCache[packageNames] ){ - return resultCache[packageNames] - } - const result = calculatePackageNameFilter(packageNames) - resultCache[packageNames] = result - return result +export function getPackageNameFilter(packageNames: string): PackageNamesFilter { + if (resultCache[packageNames]) { + return resultCache[packageNames] + } + const result = calculatePackageNameFilter(packageNames) + resultCache[packageNames] = result + return result } const emptyFilter = Object.freeze({ - subfilters: Object.freeze([]), - isEmpty: true, - apply:() => false as boolean + subfilters: Object.freeze([]), + isEmpty: true, + apply: () => false as boolean }) /** * Generates a filter based package names to match - * + * * @param packageNames - serialized package names filter as string * @returns the respective package filter */ -function calculatePackageNameFilter(packageNames: string): Readonly { - if(packageNames === ""){ - return emptyFilter; - } - const separatedPackageNames = packageNames - .split(",") - .map(packageName => packageName.trim()) - .filter(packageNames => packageNames !== "") - - - if (separatedPackageNames.length <= 0){ - return emptyFilter; - } +function calculatePackageNameFilter( + packageNames: string +): Readonly { + if (packageNames === '') { + return emptyFilter + } + const separatedPackageNames = packageNames + .split(',') + .map(name => name.trim()) + .filter(name => name !== '') - const subfilters = separatedPackageNames.map(createFilter) - return { - subfilters, - isEmpty: subfilters.length <= 0, - apply:(packageNames) => subfilters.some(filter => filter.apply(packageNames)) - } + if (separatedPackageNames.length <= 0) { + return emptyFilter + } + const subfilters = separatedPackageNames.map(createFilter) + return { + subfilters, + isEmpty: subfilters.length <= 0, + apply: names => subfilters.some(filter => filter.apply(names)) + } } - function createFilter(packageName: string): PackageNameSubFilter { - if(packageName.startsWith('*') || packageName.endsWith('*')){ - return createWildcardFilter(packageName) - } else if(packageName.startsWith("/") && packageName.endsWith("/")){ - return createRegexFilter(packageName) - } else { - return createExactMatchFilter(packageName) - } + if (packageName.startsWith('*') || packageName.endsWith('*')) { + return createWildcardFilter(packageName) + } else if (packageName.startsWith('/') && packageName.endsWith('/')) { + return createRegexFilter(packageName) + } else { + return createExactMatchFilter(packageName) + } } -function createWildcardFilter(wildcardPackageName: string): PackageNameSubFilter { - const startsWithWildCard = wildcardPackageName.startsWith('*') - const endsWithWildCard = wildcardPackageName.endsWith('*') - let fn: PackageNameSubFilter["apply"] - if(startsWithWildCard && endsWithWildCard){ - const targetText = wildcardPackageName.substring(1, wildcardPackageName.length - 1) - fn = (packageName: string) => packageName.includes(targetText) - } else if(startsWithWildCard){ - const targetText = wildcardPackageName.substring(1) - fn = (packageName: string) => packageName.endsWith(targetText) - } else { - const targetText = wildcardPackageName.substring(0, wildcardPackageName.length - 1) - fn = (packageName: string) => packageName.startsWith(targetText) - } - return { - type: 'wildcard', - apply: fn - } +function createWildcardFilter( + wildcardPackageName: string +): PackageNameSubFilter { + const startsWithWildCard = wildcardPackageName.startsWith('*') + const endsWithWildCard = wildcardPackageName.endsWith('*') + let fn: PackageNameSubFilter['apply'] + if (startsWithWildCard && endsWithWildCard) { + const targetText = wildcardPackageName.substring( + 1, + wildcardPackageName.length - 1 + ) + fn = (packageName: string) => packageName.includes(targetText) + } else if (startsWithWildCard) { + const targetText = wildcardPackageName.substring(1) + fn = (packageName: string) => packageName.endsWith(targetText) + } else { + const targetText = wildcardPackageName.substring( + 0, + wildcardPackageName.length - 1 + ) + fn = (packageName: string) => packageName.startsWith(targetText) + } + return { + type: 'wildcard', + apply: fn + } } function createRegexFilter(regexPackageName: string): PackageNameSubFilter { - const regexPattern = regexPackageName.substring(1, regexPackageName.length - 1) - const regex = new RegExp(regexPattern) - return { - type: 'regex', - apply: (packageName: string) => regex.test(packageName) - } + const regexPattern = regexPackageName.substring( + 1, + regexPackageName.length - 1 + ) + const regex = new RegExp(regexPattern) + return { + type: 'regex', + apply: (packageName: string) => regex.test(packageName) + } } -function createExactMatchFilter(matchingPackageName: string): PackageNameSubFilter { - return { - type: 'string', - apply: (packageName: string) => packageName === matchingPackageName - } - -} \ No newline at end of file +function createExactMatchFilter( + matchingPackageName: string +): PackageNameSubFilter { + return { + type: 'string', + apply: (packageName: string) => packageName === matchingPackageName + } +} From f0a7caf9f3d4f1d9744c3a32b1937996c425267d Mon Sep 17 00:00:00 2001 From: OmarCastro Date: Fri, 1 Apr 2022 20:23:50 +0100 Subject: [PATCH 05/20] src: handle packageNames on delete versions --- src/delete.ts | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/input.ts | 6 +++++- src/main.ts | 1 + 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/delete.ts b/src/delete.ts index c2f9c3c6..8f0a3e2d 100644 --- a/src/delete.ts +++ b/src/delete.ts @@ -1,7 +1,8 @@ import {Input} from './input' import {EMPTY, Observable, of, throwError} from 'rxjs' import {deletePackageVersions, getOldestVersions, VersionInfo} from './version' -import {concatMap, map, expand, tap} from 'rxjs/operators' +import {getRepoPackages, getPackageNameFilter, PackageInfo} from './packages' +import {concatMap, map, mergeMap, expand, tap} from 'rxjs/operators' const RATE_LIMIT = 99 let totalCount = 0 @@ -41,11 +42,67 @@ export function getVersionIds( ) } +export function getPackageNames( + owner: string, + repo: string, + numPackages: number, + cursor: string, + token: string +): Observable { + return getRepoPackages( + owner, + repo, + numPackages, + cursor, + token + ).pipe( + expand(value => + value.paginate + ? getRepoPackages( + owner, + repo, + numPackages, + value.cursor, + token + ) + : EMPTY + ), + tap( + value => (totalCount = totalCount === 0 ? value.totalCount : totalCount) + ), + map(value => value.packages) + ) +} + + export function finalIds(input: Input): Observable { if (input.packageVersionIds.length > 0) { return of(input.packageVersionIds) } if (input.hasOldestVersionQueryInfo()) { + const filter = getPackageNameFilter(input.packageNames) + if(!filter.isEmpty){ + return getPackageNames( + input.owner, + input.repo, + RATE_LIMIT, + '', + input.token + ).pipe( + mergeMap( value => { + return value + .filter(info => filter.apply(info.name)) + .map(info => finalIds(new Input({ + ...input, + packageNames: '', + packageName: info.name + }))) + }) + ).pipe( + mergeMap(val => val) + ) + } + if (input.minVersionsToKeep < 0) { // This code block is when num-old-versions-to-delete is specified. // Setting input.numOldVersionsToDelete is set as minimum of input.numOldVersionsToDelete and RATE_LIMIT diff --git a/src/input.ts b/src/input.ts index 35244d52..aa349821 100644 --- a/src/input.ts +++ b/src/input.ts @@ -3,6 +3,7 @@ export interface InputParams { owner?: string repo?: string packageName?: string + packageNames?: string numOldVersionsToDelete?: number minVersionsToKeep?: number ignoreVersions?: RegExp @@ -15,6 +16,7 @@ const defaultParams = { owner: '', repo: '', packageName: '', + packageNames: '', numOldVersionsToDelete: 0, minVersionsToKeep: 0, ignoreVersions: new RegExp(''), @@ -27,6 +29,7 @@ export class Input { owner: string repo: string packageName: string + packageNames: string numOldVersionsToDelete: number minVersionsToKeep: number ignoreVersions: RegExp @@ -41,6 +44,7 @@ export class Input { this.owner = validatedParams.owner this.repo = validatedParams.repo this.packageName = validatedParams.packageName + this.packageNames = validatedParams.packageNames this.numOldVersionsToDelete = validatedParams.numOldVersionsToDelete this.minVersionsToKeep = validatedParams.minVersionsToKeep this.ignoreVersions = validatedParams.ignoreVersions @@ -53,7 +57,7 @@ export class Input { return !!( this.owner && this.repo && - this.packageName && + (this.packageName || this.packageNames) && this.numOldVersionsToDelete >= 0 && this.token ) diff --git a/src/main.ts b/src/main.ts index 2905ad0e..8a88d1c1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -13,6 +13,7 @@ function getActionInput(): Input { owner: getInput('owner') ? getInput('owner') : context.repo.owner, repo: getInput('repo') ? getInput('repo') : context.repo.repo, packageName: getInput('package-name'), + packageNames: getInput('package-names'), numOldVersionsToDelete: Number(getInput('num-old-versions-to-delete')), minVersionsToKeep: Number(getInput('min-versions-to-keep')), ignoreVersions: RegExp(getInput('ignore-versions')), From 3f267361f0bf305bce04d6ab39ac86215da5dfe3 Mon Sep 17 00:00:00 2001 From: OmarCastro Date: Mon, 4 Apr 2022 14:05:10 +0100 Subject: [PATCH 06/20] src: add * wildcard to match all packages --- src/packages/package-name-filter.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/packages/package-name-filter.ts b/src/packages/package-name-filter.ts index 5e71ca54..262459fe 100644 --- a/src/packages/package-name-filter.ts +++ b/src/packages/package-name-filter.ts @@ -80,7 +80,9 @@ function createWildcardFilter( const startsWithWildCard = wildcardPackageName.startsWith('*') const endsWithWildCard = wildcardPackageName.endsWith('*') let fn: PackageNameSubFilter['apply'] - if (startsWithWildCard && endsWithWildCard) { + if(wildcardPackageName === "*"){ + fn = () => true + } else if (startsWithWildCard && endsWithWildCard) { const targetText = wildcardPackageName.substring( 1, wildcardPackageName.length - 1 From 65316631bfc9f0e65ccf1c1046be39f522af860c Mon Sep 17 00:00:00 2001 From: OmarCastro Date: Mon, 4 Apr 2022 14:05:49 +0100 Subject: [PATCH 07/20] test: add tests for all wildcard cases --- .../packages/package-name-filter.test.ts | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/__tests__/packages/package-name-filter.test.ts b/__tests__/packages/package-name-filter.test.ts index 4fc450c9..781d7c74 100644 --- a/__tests__/packages/package-name-filter.test.ts +++ b/__tests__/packages/package-name-filter.test.ts @@ -12,7 +12,7 @@ describe('package name filter -- create filter', () => { 'com.company.project.module3.package-name-dolor', ] - it('getPackageNameFilter -- wildcard filter', done => { + it('getPackageNameFilter -- wildcard end filter', done => { const filter = getPackageNameFilter('com.company.project.module1.*') const result = packageNameList.filter(filter.apply); @@ -25,6 +25,44 @@ describe('package name filter -- create filter', () => { done() }) + it('getPackageNameFilter -- wildcard start filter', done => { + const filter = getPackageNameFilter('*.package1') + + const result = packageNameList.filter(filter.apply); + + expect(filter.subfilters[0].type).toBe('wildcard') + expect(result).toEqual([ + 'com.company.project.module1.package1', + 'com.company.project.module2.package1', + ]) + done() + }) + + it('getPackageNameFilter -- wildcard both sides filter', done => { + const filter = getPackageNameFilter('*.project.module3.*') + + const result = packageNameList.filter(filter.apply); + + expect(filter.subfilters[0].type).toBe('wildcard') + expect(result).toEqual([ + 'com.company.project.module3.package-name-lorem', + 'com.company.project.module3.package-name-ipsum', + 'com.company.project.module3.package-name-dolor' + ]) + done() + }) + + + it('getPackageNameFilter -- wildcard all filter', done => { + const filter = getPackageNameFilter('*') + + const result = packageNameList.filter(filter.apply); + + expect(filter.subfilters[0].type).toBe('wildcard') + expect(result).toEqual(packageNameList.slice()) + done() + }) + it('getPackageNameFilter -- regex filter', done => { const filter = getPackageNameFilter('/com\\.company\\.project\\.module.*\\.package1/') const result = packageNameList.filter(filter.apply); From 34301c84addc6048918e0b4a7c5f702bbdbb0cf8 Mon Sep 17 00:00:00 2001 From: OmarCastro Date: Mon, 4 Apr 2022 14:24:48 +0100 Subject: [PATCH 08/20] doc: update README.md --- README.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ffa908dd..63404593 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ This action deletes versions of a package from [GitHub Packages](https://github. * Delete all package versions except n most recent versions * Delete oldest version(s) * Ignore version(s) from deletion through regex -* Delete version(s) of a package that is hosted in the same repo that is executing the workflow -* Delete version(s) of a package that is hosted in a different repo than the one executing the workflow +* Delete version(s) of packages that are hosted in the same repo that is executing the workflow +* Delete version(s) of packages that are hosted in a different repo than the one executing the workflow * Delete a single version * Delete multiple versions * Delete specific version(s) @@ -35,9 +35,20 @@ This action deletes versions of a package from [GitHub Packages](https://github. # Name of the package. # Defaults to an empty string. - # Required if `package-version-ids` input is not given. + # Required if `package-version-ids` or `package-names` input is not given. package-name: + # Names of the package. + # Can be one of the following: + # - a single package name + # - a group of packages that matches a wildcard at start, end, both sides, or all packages (e.g. "package*") + # - a group of packages that matches a regex, must start with slash at the beginning and end (e.g. "/package.*/") + # - a comma separated list of the previous cases + # Defaults to an empty string. + # Required if `package-version-ids` or `package-name` input is not given. + package-names: + + # The number of old versions to delete starting from the oldest version. # Defaults to 1. num-old-versions-to-delete: @@ -70,7 +81,7 @@ This action deletes versions of a package from [GitHub Packages](https://github. # Valid Input Combinations -`owner`, `repo`, `package-name` and `token` can be used with the following combinations in a workflow - +`owner`, `repo`, `package-name` (of `package-names`) and `token` can be used with the following combinations in a workflow - - `num-old-versions-to-delete` - `min-versions-to-keep` @@ -86,12 +97,13 @@ This action deletes versions of a package from [GitHub Packages](https://github. - [Delete all except y latest versions while ignoring particular package versions](#delete-all-except-y-latest-versions-while-ignoring-particular-package-versions) - [Delete oldest x number of versions while ignoring particular package versions](#delete-oldest-x-number-of-versions-while-ignoring-particular-package-versions) - [Delete all except y latest versions of a package](#delete-all-except-y-latest-versions-of-a-package) + - [Delete all except y latest versions of all packages in a repo](#delete-all-except-y-latest-versions-of-all-packages-in-a-repo) - [Delete oldest x number of versions of a package](#delete-oldest-x-number-of-versions-of-a-package) - [Delete oldest version of a package](#delete-oldest-version-of-a-package) - [Delete a specific version of a package](#delete-a-specific-version-of-a-package) - [Delete multiple specific versions of a package](#delete-multiple-specific-versions-of-a-package) - + ### Delete all pre-release versions except y latest pre-release package versions To delete all pre release versions except y latest pre-release package versions in the same repo as the workflow the __package-name__, __min-versions-to-keep__ and __delete-only-pre-release-versions__ inputs are required. @@ -241,6 +253,41 @@ This action deletes versions of a package from [GitHub Packages](https://github.
+ ### Delete all except y latest versions of a package + + To delete all except y latest versions of all packages hosted in the same repo as the workflow the __package-names__ and __min-versions-to-keep__ inputs are required. + + __Example__ + + Delete all except latest 2 versions of a package hosted in the same repo as the workflow + + ```yaml + - uses: actions/delete-package-versions@v3 + with: + package-names: '*' + min-versions-to-keep: 2 + ``` + + To delete all except y latest versions of all packages hosted in a repo other than the workflow the __owner__, __repo__, __package-names__, __token__ and __min-versions-to-keep__ inputs are required. + + The [token][token] needs the delete packages and read packages scope. It is recommended [to store the token as a secret][secret]. In this example the [token][token] was stored as a secret named __GITHUB_PAT__. + + __Example__ + + Delete all except latest 2 versions of a package hosted in a repo other than the workflow + + ```yaml + - uses: actions/delete-package-versions@v3 + with: + owner: 'github' + repo: 'packages' + package-names: '*' + token: ${{ secrets.PAT }} + min-versions-to-keep: 2 + ``` + +
+ ### Delete oldest x number of versions of a package To delete the oldest x number of versions of a package hosted in the same repo as the workflow the __package-name__, and __num-old-versions-to-delete__ inputs are required. From 7e81fc4da9d894d3e9465291a88ad25fbf94181d Mon Sep 17 00:00:00 2001 From: OmarCastro Date: Mon, 4 Apr 2022 14:32:00 +0100 Subject: [PATCH 09/20] chore: lint code --- src/delete.ts | 47 ++++++++++++----------------- src/packages/package-name-filter.ts | 2 +- 2 files changed, 20 insertions(+), 29 deletions(-) diff --git a/src/delete.ts b/src/delete.ts index 8f0a3e2d..646ccc05 100644 --- a/src/delete.ts +++ b/src/delete.ts @@ -49,22 +49,10 @@ export function getPackageNames( cursor: string, token: string ): Observable { - return getRepoPackages( - owner, - repo, - numPackages, - cursor, - token - ).pipe( + return getRepoPackages(owner, repo, numPackages, cursor, token).pipe( expand(value => value.paginate - ? getRepoPackages( - owner, - repo, - numPackages, - value.cursor, - token - ) + ? getRepoPackages(owner, repo, numPackages, value.cursor, token) : EMPTY ), tap( @@ -74,33 +62,36 @@ export function getPackageNames( ) } - export function finalIds(input: Input): Observable { if (input.packageVersionIds.length > 0) { return of(input.packageVersionIds) } if (input.hasOldestVersionQueryInfo()) { const filter = getPackageNameFilter(input.packageNames) - if(!filter.isEmpty){ + if (!filter.isEmpty) { return getPackageNames( input.owner, input.repo, RATE_LIMIT, '', input.token - ).pipe( - mergeMap( value => { - return value - .filter(info => filter.apply(info.name)) - .map(info => finalIds(new Input({ - ...input, - packageNames: '', - packageName: info.name - }))) - }) - ).pipe( - mergeMap(val => val) ) + .pipe( + mergeMap(value => { + return value + .filter(info => filter.apply(info.name)) + .map(info => + finalIds( + new Input({ + ...input, + packageNames: '', + packageName: info.name + }) + ) + ) + }) + ) + .pipe(mergeMap(val => val)) } if (input.minVersionsToKeep < 0) { diff --git a/src/packages/package-name-filter.ts b/src/packages/package-name-filter.ts index 262459fe..fba0af00 100644 --- a/src/packages/package-name-filter.ts +++ b/src/packages/package-name-filter.ts @@ -80,7 +80,7 @@ function createWildcardFilter( const startsWithWildCard = wildcardPackageName.startsWith('*') const endsWithWildCard = wildcardPackageName.endsWith('*') let fn: PackageNameSubFilter['apply'] - if(wildcardPackageName === "*"){ + if (wildcardPackageName === '*') { fn = () => true } else if (startsWithWildCard && endsWithWildCard) { const targetText = wildcardPackageName.substring( From 36d9774f0308c45a0546019cff52c8de068bbd3d Mon Sep 17 00:00:00 2001 From: OmarCastro Date: Mon, 4 Apr 2022 15:16:13 +0100 Subject: [PATCH 10/20] doc: add example of comma separated list in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 63404593..72ff6502 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ This action deletes versions of a package from [GitHub Packages](https://github. # - a single package name # - a group of packages that matches a wildcard at start, end, both sides, or all packages (e.g. "package*") # - a group of packages that matches a regex, must start with slash at the beginning and end (e.g. "/package.*/") - # - a comma separated list of the previous cases + # - a comma separated list of the previous cases (e.g. "package-lorem, *-ipsum, /.*dolor/") # Defaults to an empty string. # Required if `package-version-ids` or `package-name` input is not given. package-names: From f98a76d802af4320125db346e7ec06076752381d Mon Sep 17 00:00:00 2001 From: OmarCastro Date: Tue, 31 May 2022 15:32:17 +0100 Subject: [PATCH 11/20] review: fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 72ff6502..36a7c732 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ This action deletes versions of a package from [GitHub Packages](https://github. # Valid Input Combinations -`owner`, `repo`, `package-name` (of `package-names`) and `token` can be used with the following combinations in a workflow - +`owner`, `repo`, `package-name` (or `package-names`) and `token` can be used with the following combinations in a workflow - - `num-old-versions-to-delete` - `min-versions-to-keep` From 39865728ac8bd9bf4c47b841ad5452043118272b Mon Sep 17 00:00:00 2001 From: OmarCastro Date: Tue, 31 May 2022 16:05:11 +0100 Subject: [PATCH 12/20] review: remove no longer used package totalCount there is no need to get totalCount if it is not going to be used - remove faulty tap call on getPackageNames method - remove totalCount on query, as pageInfo.hasNextPage is enough for pagination - remove totalCount on graphql.mock.ts --- __tests__/packages/graphql.mock.ts | 1 - src/delete.ts | 3 --- src/packages/get-packages.ts | 11 ++--------- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/__tests__/packages/graphql.mock.ts b/__tests__/packages/graphql.mock.ts index c037dbbb..c07c370d 100644 --- a/__tests__/packages/graphql.mock.ts +++ b/__tests__/packages/graphql.mock.ts @@ -22,7 +22,6 @@ export function getMockedPackagesQueryResponse( return { repository: { packages: { - totalCount: 200, pageInfo: { endCursor: 'AAA', hasNextPage: false diff --git a/src/delete.ts b/src/delete.ts index 646ccc05..05c18990 100644 --- a/src/delete.ts +++ b/src/delete.ts @@ -55,9 +55,6 @@ export function getPackageNames( ? getRepoPackages(owner, repo, numPackages, value.cursor, token) : EMPTY ), - tap( - value => (totalCount = totalCount === 0 ? value.totalCount : totalCount) - ), map(value => value.packages) ) } diff --git a/src/packages/get-packages.ts b/src/packages/get-packages.ts index bc916706..6f99145e 100644 --- a/src/packages/get-packages.ts +++ b/src/packages/get-packages.ts @@ -14,13 +14,11 @@ export interface QueryInfo { packages: PackageInfo[] cursor: string paginate: boolean - totalCount: number } export interface GetPackagesQueryResponse { repository: { packages: { - totalCount: number edges: {node: PackageInfo}[] pageInfo: { endCursor: string @@ -34,7 +32,6 @@ const query = ` query getPackages($owner: String!, $name: String!, $first: Int!){ repository(owner: $owner, name: $name) { packages(first:$first){ - totalCount edges { node { name @@ -53,7 +50,6 @@ const Paginatequery = ` query getPackages($owner: String!, $name: String!, $first: Int!, $after: String!){ repository(owner: $owner, name: $name) { packages(first:$first){ - totalCount edges { node { name @@ -146,15 +142,13 @@ export function getRepoPackages( r = { packages: [] as PackageInfo[], cursor: '', - paginate: false, - totalCount: 0 + paginate: false } return r } const packages = result.repository.packages.edges const pages = result.repository.packages.pageInfo - const count = result.repository.packages.totalCount r = { packages: packages.map(value => ({ @@ -162,8 +156,7 @@ export function getRepoPackages( name: value.node.name })), cursor: pages.endCursor, - paginate: pages.hasNextPage, - totalCount: count + paginate: pages.hasNextPage } return r From c307ec0def2aefc429e7528278521ef4861b44d7 Mon Sep 17 00:00:00 2001 From: OmarCastro Date: Tue, 31 May 2022 22:57:17 +0100 Subject: [PATCH 13/20] review: add package-names input to actions.yml --- action.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/action.yml b/action.yml index 519a3b8f..2837de93 100644 --- a/action.yml +++ b/action.yml @@ -27,6 +27,19 @@ inputs: Required if dynamically deleting oldest versions. required: false + + package-names: + description: > + Names of the package. + Can be one of the following: + - a single package name + - a group of packages that matches a wildcard at start, end, both sides, or all packages (e.g. "package*") + - a group of packages that matches a regex, must start with slash at the beginning and end (e.g. "/package.*/") + - a comma separated list of the previous cases (e.g. "package-lorem, *-ipsum, /.*dolor/") + Defaults to an empty string. + Required if `package-version-ids` or `package-name` input is not given. + required: false + num-old-versions-to-delete: description: > Number of versions to delete starting with the oldest version. From 03234f817ba17a45567716fefee909d2720312e8 Mon Sep 17 00:00:00 2001 From: OmarCastro Date: Tue, 31 May 2022 23:03:11 +0100 Subject: [PATCH 14/20] dist: execute 'npm run pack' --- dist/index.js | 302 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 299 insertions(+), 3 deletions(-) diff --git a/dist/index.js b/dist/index.js index ee3c486f..a4e7170a 100644 --- a/dist/index.js +++ b/dist/index.js @@ -5,7 +5,7 @@ /***/ ((module) => { "use strict"; -module.exports = JSON.parse('{"_args":[["@octokit/rest@16.43.2","/workspaces/delete-package-versions"]],"_from":"@octokit/rest@16.43.2","_id":"@octokit/rest@16.43.2","_inBundle":false,"_integrity":"sha512-ngDBevLbBTFfrHZeiS7SAMAZ6ssuVmXuya+F/7RaVvlysgGa1JKJkKWY+jV6TCJYcW0OALfJ7nTIGXcBXzycfQ==","_location":"/@octokit/rest","_phantomChildren":{"deprecation":"2.3.1","once":"1.4.0","os-name":"3.1.0"},"_requested":{"type":"version","registry":true,"raw":"@octokit/rest@16.43.2","name":"@octokit/rest","escapedName":"@octokit%2frest","scope":"@octokit","rawSpec":"16.43.2","saveSpec":null,"fetchSpec":"16.43.2"},"_requiredBy":["/@actions/github"],"_resolved":"https://registry.npmjs.org/@octokit/rest/-/rest-16.43.2.tgz","_spec":"16.43.2","_where":"/workspaces/delete-package-versions","author":{"name":"Gregor Martynus","url":"https://github.com/gr2m"},"bugs":{"url":"https://github.com/octokit/rest.js/issues"},"bundlesize":[{"path":"./dist/octokit-rest.min.js.gz","maxSize":"33 kB"}],"contributors":[{"name":"Mike de Boer","email":"info@mikedeboer.nl"},{"name":"Fabian Jakobs","email":"fabian@c9.io"},{"name":"Joe Gallo","email":"joe@brassafrax.com"},{"name":"Gregor Martynus","url":"https://github.com/gr2m"}],"dependencies":{"@octokit/auth-token":"^2.4.0","@octokit/plugin-paginate-rest":"^1.1.1","@octokit/plugin-request-log":"^1.0.0","@octokit/plugin-rest-endpoint-methods":"2.4.0","@octokit/request":"^5.2.0","@octokit/request-error":"^1.0.2","atob-lite":"^2.0.0","before-after-hook":"^2.0.0","btoa-lite":"^1.0.0","deprecation":"^2.0.0","lodash.get":"^4.4.2","lodash.set":"^4.3.2","lodash.uniq":"^4.5.0","octokit-pagination-methods":"^1.1.0","once":"^1.4.0","universal-user-agent":"^4.0.0"},"description":"GitHub REST API client for Node.js","devDependencies":{"@gimenete/type-writer":"^0.1.3","@octokit/auth":"^1.1.1","@octokit/fixtures-server":"^5.0.6","@octokit/graphql":"^4.2.0","@types/node":"^13.1.0","bundlesize":"^0.18.0","chai":"^4.1.2","compression-webpack-plugin":"^3.1.0","cypress":"^4.0.0","glob":"^7.1.2","http-proxy-agent":"^4.0.0","lodash.camelcase":"^4.3.0","lodash.merge":"^4.6.1","lodash.upperfirst":"^4.3.1","lolex":"^6.0.0","mkdirp":"^1.0.0","mocha":"^7.0.1","mustache":"^4.0.0","nock":"^11.3.3","npm-run-all":"^4.1.2","nyc":"^15.0.0","prettier":"^1.14.2","proxy":"^1.0.0","semantic-release":"^17.0.0","sinon":"^8.0.0","sinon-chai":"^3.0.0","sort-keys":"^4.0.0","string-to-arraybuffer":"^1.0.0","string-to-jsdoc-comment":"^1.0.0","typescript":"^3.3.1","webpack":"^4.0.0","webpack-bundle-analyzer":"^3.0.0","webpack-cli":"^3.0.0"},"files":["index.js","index.d.ts","lib","plugins"],"homepage":"https://github.com/octokit/rest.js#readme","keywords":["octokit","github","rest","api-client"],"license":"MIT","name":"@octokit/rest","nyc":{"ignore":["test"]},"publishConfig":{"access":"public"},"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"repository":{"type":"git","url":"git+https://github.com/octokit/rest.js.git"},"scripts":{"build":"npm-run-all build:*","build:browser":"npm-run-all build:browser:*","build:browser:development":"webpack --mode development --entry . --output-library=Octokit --output=./dist/octokit-rest.js --profile --json > dist/bundle-stats.json","build:browser:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=Octokit --output-path=./dist --output-filename=octokit-rest.min.js --devtool source-map","build:ts":"npm run -s update-endpoints:typescript","coverage":"nyc report --reporter=html && open coverage/index.html","generate-bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","lint":"prettier --check \'{lib,plugins,scripts,test}/**/*.{js,json,ts}\' \'docs/*.{js,json}\' \'docs/src/**/*\' index.js README.md package.json","lint:fix":"prettier --write \'{lib,plugins,scripts,test}/**/*.{js,json,ts}\' \'docs/*.{js,json}\' \'docs/src/**/*\' index.js README.md package.json","postvalidate:ts":"tsc --noEmit --target es6 test/typescript-validate.ts","prebuild:browser":"mkdirp dist/","pretest":"npm run -s lint","prevalidate:ts":"npm run -s build:ts","start-fixtures-server":"octokit-fixtures-server","test":"nyc mocha test/mocha-node-setup.js \\"test/*/**/*-test.js\\"","test:browser":"cypress run --browser chrome","update-endpoints":"npm-run-all update-endpoints:*","update-endpoints:fetch-json":"node scripts/update-endpoints/fetch-json","update-endpoints:typescript":"node scripts/update-endpoints/typescript","validate:ts":"tsc --target es6 --noImplicitAny index.d.ts"},"types":"index.d.ts","version":"16.43.2"}'); +module.exports = JSON.parse('{"_args":[["@octokit/rest@16.43.2","/home/omar/workspace/git/delete-package-versions"]],"_from":"@octokit/rest@16.43.2","_id":"@octokit/rest@16.43.2","_inBundle":false,"_integrity":"sha512-ngDBevLbBTFfrHZeiS7SAMAZ6ssuVmXuya+F/7RaVvlysgGa1JKJkKWY+jV6TCJYcW0OALfJ7nTIGXcBXzycfQ==","_location":"/@octokit/rest","_phantomChildren":{"deprecation":"2.3.1","once":"1.4.0","os-name":"3.1.0"},"_requested":{"type":"version","registry":true,"raw":"@octokit/rest@16.43.2","name":"@octokit/rest","escapedName":"@octokit%2frest","scope":"@octokit","rawSpec":"16.43.2","saveSpec":null,"fetchSpec":"16.43.2"},"_requiredBy":["/@actions/github"],"_resolved":"https://registry.npmjs.org/@octokit/rest/-/rest-16.43.2.tgz","_spec":"16.43.2","_where":"/home/omar/workspace/git/delete-package-versions","author":{"name":"Gregor Martynus","url":"https://github.com/gr2m"},"bugs":{"url":"https://github.com/octokit/rest.js/issues"},"bundlesize":[{"path":"./dist/octokit-rest.min.js.gz","maxSize":"33 kB"}],"contributors":[{"name":"Mike de Boer","email":"info@mikedeboer.nl"},{"name":"Fabian Jakobs","email":"fabian@c9.io"},{"name":"Joe Gallo","email":"joe@brassafrax.com"},{"name":"Gregor Martynus","url":"https://github.com/gr2m"}],"dependencies":{"@octokit/auth-token":"^2.4.0","@octokit/plugin-paginate-rest":"^1.1.1","@octokit/plugin-request-log":"^1.0.0","@octokit/plugin-rest-endpoint-methods":"2.4.0","@octokit/request":"^5.2.0","@octokit/request-error":"^1.0.2","atob-lite":"^2.0.0","before-after-hook":"^2.0.0","btoa-lite":"^1.0.0","deprecation":"^2.0.0","lodash.get":"^4.4.2","lodash.set":"^4.3.2","lodash.uniq":"^4.5.0","octokit-pagination-methods":"^1.1.0","once":"^1.4.0","universal-user-agent":"^4.0.0"},"description":"GitHub REST API client for Node.js","devDependencies":{"@gimenete/type-writer":"^0.1.3","@octokit/auth":"^1.1.1","@octokit/fixtures-server":"^5.0.6","@octokit/graphql":"^4.2.0","@types/node":"^13.1.0","bundlesize":"^0.18.0","chai":"^4.1.2","compression-webpack-plugin":"^3.1.0","cypress":"^4.0.0","glob":"^7.1.2","http-proxy-agent":"^4.0.0","lodash.camelcase":"^4.3.0","lodash.merge":"^4.6.1","lodash.upperfirst":"^4.3.1","lolex":"^6.0.0","mkdirp":"^1.0.0","mocha":"^7.0.1","mustache":"^4.0.0","nock":"^11.3.3","npm-run-all":"^4.1.2","nyc":"^15.0.0","prettier":"^1.14.2","proxy":"^1.0.0","semantic-release":"^17.0.0","sinon":"^8.0.0","sinon-chai":"^3.0.0","sort-keys":"^4.0.0","string-to-arraybuffer":"^1.0.0","string-to-jsdoc-comment":"^1.0.0","typescript":"^3.3.1","webpack":"^4.0.0","webpack-bundle-analyzer":"^3.0.0","webpack-cli":"^3.0.0"},"files":["index.js","index.d.ts","lib","plugins"],"homepage":"https://github.com/octokit/rest.js#readme","keywords":["octokit","github","rest","api-client"],"license":"MIT","name":"@octokit/rest","nyc":{"ignore":["test"]},"publishConfig":{"access":"public"},"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"repository":{"type":"git","url":"git+https://github.com/octokit/rest.js.git"},"scripts":{"build":"npm-run-all build:*","build:browser":"npm-run-all build:browser:*","build:browser:development":"webpack --mode development --entry . --output-library=Octokit --output=./dist/octokit-rest.js --profile --json > dist/bundle-stats.json","build:browser:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=Octokit --output-path=./dist --output-filename=octokit-rest.min.js --devtool source-map","build:ts":"npm run -s update-endpoints:typescript","coverage":"nyc report --reporter=html && open coverage/index.html","generate-bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","lint":"prettier --check \'{lib,plugins,scripts,test}/**/*.{js,json,ts}\' \'docs/*.{js,json}\' \'docs/src/**/*\' index.js README.md package.json","lint:fix":"prettier --write \'{lib,plugins,scripts,test}/**/*.{js,json,ts}\' \'docs/*.{js,json}\' \'docs/src/**/*\' index.js README.md package.json","postvalidate:ts":"tsc --noEmit --target es6 test/typescript-validate.ts","prebuild:browser":"mkdirp dist/","pretest":"npm run -s lint","prevalidate:ts":"npm run -s build:ts","start-fixtures-server":"octokit-fixtures-server","test":"nyc mocha test/mocha-node-setup.js \\"test/*/**/*-test.js\\"","test:browser":"cypress run --browser chrome","update-endpoints":"npm-run-all update-endpoints:*","update-endpoints:fetch-json":"node scripts/update-endpoints/fetch-json","update-endpoints:typescript":"node scripts/update-endpoints/typescript","validate:ts":"tsc --target es6 --noImplicitAny index.d.ts"},"types":"index.d.ts","version":"16.43.2"}'); /***/ }), @@ -15,9 +15,11 @@ module.exports = JSON.parse('{"_args":[["@octokit/rest@16.43.2","/workspaces/del "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.deleteVersions = exports.finalIds = exports.getVersionIds = void 0; +exports.deleteVersions = exports.finalIds = exports.getPackageNames = exports.getVersionIds = void 0; +const input_1 = __nccwpck_require__(8657); const rxjs_1 = __nccwpck_require__(5805); const version_1 = __nccwpck_require__(4428); +const packages_1 = __nccwpck_require__(221); const operators_1 = __nccwpck_require__(7801); const RATE_LIMIT = 99; let totalCount = 0; @@ -27,11 +29,27 @@ function getVersionIds(owner, repo, packageName, numVersions, cursor, token) { : rxjs_1.EMPTY), operators_1.tap(value => (totalCount = totalCount === 0 ? value.totalCount : totalCount)), operators_1.map(value => value.versions)); } exports.getVersionIds = getVersionIds; +function getPackageNames(owner, repo, numPackages, cursor, token) { + return packages_1.getRepoPackages(owner, repo, numPackages, cursor, token).pipe(operators_1.expand(value => value.paginate + ? packages_1.getRepoPackages(owner, repo, numPackages, value.cursor, token) + : rxjs_1.EMPTY), operators_1.map(value => value.packages)); +} +exports.getPackageNames = getPackageNames; function finalIds(input) { if (input.packageVersionIds.length > 0) { return rxjs_1.of(input.packageVersionIds); } if (input.hasOldestVersionQueryInfo()) { + const filter = packages_1.getPackageNameFilter(input.packageNames); + if (!filter.isEmpty) { + return getPackageNames(input.owner, input.repo, RATE_LIMIT, '', input.token) + .pipe(operators_1.mergeMap(value => { + return value + .filter(info => filter.apply(info.name)) + .map(info => finalIds(new input_1.Input(Object.assign(Object.assign({}, input), { packageNames: '', packageName: info.name })))); + })) + .pipe(operators_1.mergeMap(val => val)); + } if (input.minVersionsToKeep < 0) { // This code block is when num-old-versions-to-delete is specified. // Setting input.numOldVersionsToDelete is set as minimum of input.numOldVersionsToDelete and RATE_LIMIT @@ -131,6 +149,7 @@ const defaultParams = { owner: '', repo: '', packageName: '', + packageNames: '', numOldVersionsToDelete: 0, minVersionsToKeep: 0, ignoreVersions: new RegExp(''), @@ -144,6 +163,7 @@ class Input { this.owner = validatedParams.owner; this.repo = validatedParams.repo; this.packageName = validatedParams.packageName; + this.packageNames = validatedParams.packageNames; this.numOldVersionsToDelete = validatedParams.numOldVersionsToDelete; this.minVersionsToKeep = validatedParams.minVersionsToKeep; this.ignoreVersions = validatedParams.ignoreVersions; @@ -154,7 +174,7 @@ class Input { hasOldestVersionQueryInfo() { return !!(this.owner && this.repo && - this.packageName && + (this.packageName || this.packageNames) && this.numOldVersionsToDelete >= 0 && this.token); } @@ -177,6 +197,281 @@ class Input { exports.Input = Input; +/***/ }), + +/***/ 6436: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getRepoPackages = exports.queryForRepoPackages = void 0; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const rxjs_1 = __nccwpck_require__(5805); +const operators_1 = __nccwpck_require__(7801); +const graphql_1 = __nccwpck_require__(4223); +const query = ` + query getPackages($owner: String!, $name: String!, $first: Int!){ + repository(owner: $owner, name: $name) { + packages(first:$first){ + edges { + node { + name + id + } + } + pageInfo { + endCursor + hasNextPage + } + } + } + }`; +const Paginatequery = ` + query getPackages($owner: String!, $name: String!, $first: Int!, $after: String!){ + repository(owner: $owner, name: $name) { + packages(first:$first){ + edges { + node { + name + id + } + } + pageInfo { + endCursor + hasNextPage + } + } + } + }`; +function queryForRepoPackages(owner, repo, numPackages, startCursor, token) { + if (startCursor === '') { + return rxjs_1.from(graphql_1.graphql(token, query, { + owner, + repo, + first: numPackages, + headers: { + Accept: 'application/vnd.github.packages-preview+json' + } + })).pipe(operators_1.catchError((err) => { + const msg = 'query for packages failed.'; + return rxjs_1.throwError(err.errors && err.errors.length > 0 + ? `${msg} ${err.errors[0].message}` + : `${msg} verify input parameters are correct ${JSON.stringify(err, null, 2)}`); + })); + } + else { + return rxjs_1.from(graphql_1.graphql(token, Paginatequery, { + owner, + repo, + first: numPackages, + before: startCursor, + headers: { + Accept: 'application/vnd.github.packages-preview+json' + } + })).pipe(operators_1.catchError((err) => { + const msg = 'query for packages failed.'; + return rxjs_1.throwError(err.errors && err.errors.length > 0 + ? `${msg} ${err.errors[0].message}` + : `${msg} verify input parameters are correct`); + })); + } +} +exports.queryForRepoPackages = queryForRepoPackages; +function getRepoPackages(owner, repo, numPackages, startCursor, token) { + return queryForRepoPackages(owner, repo, numPackages, startCursor, token).pipe(operators_1.map(result => { + let r; + if (result.repository.packages.edges.length < 1) { + console.log(`package: No packages found for owner: ${owner} in repo: ${repo}`); + r = { + packages: [], + cursor: '', + paginate: false + }; + return r; + } + const packages = result.repository.packages.edges; + const pages = result.repository.packages.pageInfo; + r = { + packages: packages.map(value => ({ + id: value.node.id, + name: value.node.name + })), + cursor: pages.endCursor, + paginate: pages.hasNextPage + }; + return r; + })); +} +exports.getRepoPackages = getRepoPackages; + + +/***/ }), + +/***/ 4223: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.graphql = void 0; +/* eslint-disable @typescript-eslint/no-unused-vars */ +const github_1 = __nccwpck_require__(5438); +/** + * Sends a GraphQL query request based on endpoint options + * + * @param {string} token Auth token + * @param {string} query GraphQL query. Example: `'query { viewer { login } }'`. + * @param {object} parameters URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`. + */ +function graphql(token, query, parameters) { + return __awaiter(this, void 0, void 0, function* () { + const github = new github_1.GitHub(token); + return yield github.graphql(query, parameters); + }); +} +exports.graphql = graphql; + + +/***/ }), + +/***/ 221: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +__exportStar(__nccwpck_require__(6436), exports); +__exportStar(__nccwpck_require__(2539), exports); + + +/***/ }), + +/***/ 2539: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getPackageNameFilter = void 0; +/** + * Used to apply memoization on getPackageNameFilter + */ +const resultCache = {}; +/** + * Get a filter based on package names to match + * + * @param packageNames - serialized package names filter as string + * @returns the respective package filter + */ +function getPackageNameFilter(packageNames) { + if (resultCache[packageNames]) { + return resultCache[packageNames]; + } + const result = calculatePackageNameFilter(packageNames); + resultCache[packageNames] = result; + return result; +} +exports.getPackageNameFilter = getPackageNameFilter; +const emptyFilter = Object.freeze({ + subfilters: Object.freeze([]), + isEmpty: true, + apply: () => false +}); +/** + * Generates a filter based package names to match + * + * @param packageNames - serialized package names filter as string + * @returns the respective package filter + */ +function calculatePackageNameFilter(packageNames) { + if (packageNames === '') { + return emptyFilter; + } + const separatedPackageNames = packageNames + .split(',') + .map(name => name.trim()) + .filter(name => name !== ''); + if (separatedPackageNames.length <= 0) { + return emptyFilter; + } + const subfilters = separatedPackageNames.map(createFilter); + return { + subfilters, + isEmpty: subfilters.length <= 0, + apply: names => subfilters.some(filter => filter.apply(names)) + }; +} +function createFilter(packageName) { + if (packageName.startsWith('*') || packageName.endsWith('*')) { + return createWildcardFilter(packageName); + } + else if (packageName.startsWith('/') && packageName.endsWith('/')) { + return createRegexFilter(packageName); + } + else { + return createExactMatchFilter(packageName); + } +} +function createWildcardFilter(wildcardPackageName) { + const startsWithWildCard = wildcardPackageName.startsWith('*'); + const endsWithWildCard = wildcardPackageName.endsWith('*'); + let fn; + if (wildcardPackageName === '*') { + fn = () => true; + } + else if (startsWithWildCard && endsWithWildCard) { + const targetText = wildcardPackageName.substring(1, wildcardPackageName.length - 1); + fn = (packageName) => packageName.includes(targetText); + } + else if (startsWithWildCard) { + const targetText = wildcardPackageName.substring(1); + fn = (packageName) => packageName.endsWith(targetText); + } + else { + const targetText = wildcardPackageName.substring(0, wildcardPackageName.length - 1); + fn = (packageName) => packageName.startsWith(targetText); + } + return { + type: 'wildcard', + apply: fn + }; +} +function createRegexFilter(regexPackageName) { + const regexPattern = regexPackageName.substring(1, regexPackageName.length - 1); + const regex = new RegExp(regexPattern); + return { + type: 'regex', + apply: (packageName) => regex.test(packageName) + }; +} +function createExactMatchFilter(matchingPackageName) { + return { + type: 'string', + apply: (packageName) => packageName === matchingPackageName + }; +} + + /***/ }), /***/ 5544: @@ -40071,6 +40366,7 @@ function getActionInput() { owner: core_1.getInput('owner') ? core_1.getInput('owner') : github_1.context.repo.owner, repo: core_1.getInput('repo') ? core_1.getInput('repo') : github_1.context.repo.repo, packageName: core_1.getInput('package-name'), + packageNames: core_1.getInput('package-names'), numOldVersionsToDelete: Number(core_1.getInput('num-old-versions-to-delete')), minVersionsToKeep: Number(core_1.getInput('min-versions-to-keep')), ignoreVersions: RegExp(core_1.getInput('ignore-versions')), From fa40cba2e71582b7686da5dffb44137dfb7c0965 Mon Sep 17 00:00:00 2001 From: OmarCastro Date: Tue, 31 May 2022 23:43:56 +0100 Subject: [PATCH 15/20] fix: fix package graphql query variable name --- dist/index.js | 8 ++++---- src/packages/get-packages.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dist/index.js b/dist/index.js index a4e7170a..6360a95e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -211,8 +211,8 @@ const rxjs_1 = __nccwpck_require__(5805); const operators_1 = __nccwpck_require__(7801); const graphql_1 = __nccwpck_require__(4223); const query = ` - query getPackages($owner: String!, $name: String!, $first: Int!){ - repository(owner: $owner, name: $name) { + query getPackages($owner: String!, $repo: String!, $first: Int!){ + repository(owner: $owner, name: $repo) { packages(first:$first){ edges { node { @@ -228,8 +228,8 @@ const query = ` } }`; const Paginatequery = ` - query getPackages($owner: String!, $name: String!, $first: Int!, $after: String!){ - repository(owner: $owner, name: $name) { + query getPackages($owner: String!, $repo: String!, $first: Int!, $after: String!){ + repository(owner: $owner, name: $repo) { packages(first:$first){ edges { node { diff --git a/src/packages/get-packages.ts b/src/packages/get-packages.ts index 6f99145e..b29f8436 100644 --- a/src/packages/get-packages.ts +++ b/src/packages/get-packages.ts @@ -29,8 +29,8 @@ export interface GetPackagesQueryResponse { } const query = ` - query getPackages($owner: String!, $name: String!, $first: Int!){ - repository(owner: $owner, name: $name) { + query getPackages($owner: String!, $repo: String!, $first: Int!){ + repository(owner: $owner, name: $repo) { packages(first:$first){ edges { node { @@ -47,8 +47,8 @@ const query = ` }` const Paginatequery = ` - query getPackages($owner: String!, $name: String!, $first: Int!, $after: String!){ - repository(owner: $owner, name: $name) { + query getPackages($owner: String!, $repo: String!, $first: Int!, $after: String!){ + repository(owner: $owner, name: $repo) { packages(first:$first){ edges { node { From d2531724efdbb55705ba2050c9460c2e87127a0f Mon Sep 17 00:00:00 2001 From: OmarCastro Date: Wed, 1 Jun 2022 09:59:54 +0100 Subject: [PATCH 16/20] refactor: move graphql.ts to a common folder - move graphql.ts to a common folder - update imports - remove duplicate graphql.ts --- __tests__/packages/graphql.mock.ts | 2 +- __tests__/version/graphql.mock.ts | 2 +- dist/index.js | 114 ++++++++++------------------ src/{packages => common}/graphql.ts | 0 src/packages/get-packages.ts | 2 +- src/version/delete-version.ts | 2 +- src/version/get-versions.ts | 2 +- src/version/graphql.ts | 20 ----- 8 files changed, 44 insertions(+), 100 deletions(-) rename src/{packages => common}/graphql.ts (100%) delete mode 100644 src/version/graphql.ts diff --git a/__tests__/packages/graphql.mock.ts b/__tests__/packages/graphql.mock.ts index c07c370d..181434c7 100644 --- a/__tests__/packages/graphql.mock.ts +++ b/__tests__/packages/graphql.mock.ts @@ -3,7 +3,7 @@ import { RequestParameters } from '@octokit/graphql/dist-types/types' -import * as Graphql from '../../src/packages/graphql' +import * as Graphql from '../../src/common/graphql' import {GetPackagesQueryResponse} from '../../src/packages' export function getMockedPackagesQueryResponse( diff --git a/__tests__/version/graphql.mock.ts b/__tests__/version/graphql.mock.ts index c2fb04e7..0e47abe7 100644 --- a/__tests__/version/graphql.mock.ts +++ b/__tests__/version/graphql.mock.ts @@ -3,7 +3,7 @@ import { RequestParameters } from '@octokit/graphql/dist-types/types' -import * as Graphql from '../../src/version/graphql' +import * as Graphql from '../../src/common/graphql' import {GetVersionsQueryResponse} from '../../src/version' export function getMockedOldestQueryResponse( diff --git a/dist/index.js b/dist/index.js index 6360a95e..79fbfcc6 100644 --- a/dist/index.js +++ b/dist/index.js @@ -7,6 +7,42 @@ "use strict"; module.exports = JSON.parse('{"_args":[["@octokit/rest@16.43.2","/home/omar/workspace/git/delete-package-versions"]],"_from":"@octokit/rest@16.43.2","_id":"@octokit/rest@16.43.2","_inBundle":false,"_integrity":"sha512-ngDBevLbBTFfrHZeiS7SAMAZ6ssuVmXuya+F/7RaVvlysgGa1JKJkKWY+jV6TCJYcW0OALfJ7nTIGXcBXzycfQ==","_location":"/@octokit/rest","_phantomChildren":{"deprecation":"2.3.1","once":"1.4.0","os-name":"3.1.0"},"_requested":{"type":"version","registry":true,"raw":"@octokit/rest@16.43.2","name":"@octokit/rest","escapedName":"@octokit%2frest","scope":"@octokit","rawSpec":"16.43.2","saveSpec":null,"fetchSpec":"16.43.2"},"_requiredBy":["/@actions/github"],"_resolved":"https://registry.npmjs.org/@octokit/rest/-/rest-16.43.2.tgz","_spec":"16.43.2","_where":"/home/omar/workspace/git/delete-package-versions","author":{"name":"Gregor Martynus","url":"https://github.com/gr2m"},"bugs":{"url":"https://github.com/octokit/rest.js/issues"},"bundlesize":[{"path":"./dist/octokit-rest.min.js.gz","maxSize":"33 kB"}],"contributors":[{"name":"Mike de Boer","email":"info@mikedeboer.nl"},{"name":"Fabian Jakobs","email":"fabian@c9.io"},{"name":"Joe Gallo","email":"joe@brassafrax.com"},{"name":"Gregor Martynus","url":"https://github.com/gr2m"}],"dependencies":{"@octokit/auth-token":"^2.4.0","@octokit/plugin-paginate-rest":"^1.1.1","@octokit/plugin-request-log":"^1.0.0","@octokit/plugin-rest-endpoint-methods":"2.4.0","@octokit/request":"^5.2.0","@octokit/request-error":"^1.0.2","atob-lite":"^2.0.0","before-after-hook":"^2.0.0","btoa-lite":"^1.0.0","deprecation":"^2.0.0","lodash.get":"^4.4.2","lodash.set":"^4.3.2","lodash.uniq":"^4.5.0","octokit-pagination-methods":"^1.1.0","once":"^1.4.0","universal-user-agent":"^4.0.0"},"description":"GitHub REST API client for Node.js","devDependencies":{"@gimenete/type-writer":"^0.1.3","@octokit/auth":"^1.1.1","@octokit/fixtures-server":"^5.0.6","@octokit/graphql":"^4.2.0","@types/node":"^13.1.0","bundlesize":"^0.18.0","chai":"^4.1.2","compression-webpack-plugin":"^3.1.0","cypress":"^4.0.0","glob":"^7.1.2","http-proxy-agent":"^4.0.0","lodash.camelcase":"^4.3.0","lodash.merge":"^4.6.1","lodash.upperfirst":"^4.3.1","lolex":"^6.0.0","mkdirp":"^1.0.0","mocha":"^7.0.1","mustache":"^4.0.0","nock":"^11.3.3","npm-run-all":"^4.1.2","nyc":"^15.0.0","prettier":"^1.14.2","proxy":"^1.0.0","semantic-release":"^17.0.0","sinon":"^8.0.0","sinon-chai":"^3.0.0","sort-keys":"^4.0.0","string-to-arraybuffer":"^1.0.0","string-to-jsdoc-comment":"^1.0.0","typescript":"^3.3.1","webpack":"^4.0.0","webpack-bundle-analyzer":"^3.0.0","webpack-cli":"^3.0.0"},"files":["index.js","index.d.ts","lib","plugins"],"homepage":"https://github.com/octokit/rest.js#readme","keywords":["octokit","github","rest","api-client"],"license":"MIT","name":"@octokit/rest","nyc":{"ignore":["test"]},"publishConfig":{"access":"public"},"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"repository":{"type":"git","url":"git+https://github.com/octokit/rest.js.git"},"scripts":{"build":"npm-run-all build:*","build:browser":"npm-run-all build:browser:*","build:browser:development":"webpack --mode development --entry . --output-library=Octokit --output=./dist/octokit-rest.js --profile --json > dist/bundle-stats.json","build:browser:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=Octokit --output-path=./dist --output-filename=octokit-rest.min.js --devtool source-map","build:ts":"npm run -s update-endpoints:typescript","coverage":"nyc report --reporter=html && open coverage/index.html","generate-bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","lint":"prettier --check \'{lib,plugins,scripts,test}/**/*.{js,json,ts}\' \'docs/*.{js,json}\' \'docs/src/**/*\' index.js README.md package.json","lint:fix":"prettier --write \'{lib,plugins,scripts,test}/**/*.{js,json,ts}\' \'docs/*.{js,json}\' \'docs/src/**/*\' index.js README.md package.json","postvalidate:ts":"tsc --noEmit --target es6 test/typescript-validate.ts","prebuild:browser":"mkdirp dist/","pretest":"npm run -s lint","prevalidate:ts":"npm run -s build:ts","start-fixtures-server":"octokit-fixtures-server","test":"nyc mocha test/mocha-node-setup.js \\"test/*/**/*-test.js\\"","test:browser":"cypress run --browser chrome","update-endpoints":"npm-run-all update-endpoints:*","update-endpoints:fetch-json":"node scripts/update-endpoints/fetch-json","update-endpoints:typescript":"node scripts/update-endpoints/typescript","validate:ts":"tsc --target es6 --noImplicitAny index.d.ts"},"types":"index.d.ts","version":"16.43.2"}'); +/***/ }), + +/***/ 9057: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.graphql = void 0; +/* eslint-disable @typescript-eslint/no-unused-vars */ +const github_1 = __nccwpck_require__(5438); +/** + * Sends a GraphQL query request based on endpoint options + * + * @param {string} token Auth token + * @param {string} query GraphQL query. Example: `'query { viewer { login } }'`. + * @param {object} parameters URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`. + */ +function graphql(token, query, parameters) { + return __awaiter(this, void 0, void 0, function* () { + const github = new github_1.GitHub(token); + return yield github.graphql(query, parameters); + }); +} +exports.graphql = graphql; + + /***/ }), /***/ 9645: @@ -209,7 +245,7 @@ exports.getRepoPackages = exports.queryForRepoPackages = void 0; // eslint-disable-next-line @typescript-eslint/no-unused-vars const rxjs_1 = __nccwpck_require__(5805); const operators_1 = __nccwpck_require__(7801); -const graphql_1 = __nccwpck_require__(4223); +const graphql_1 = __nccwpck_require__(9057); const query = ` query getPackages($owner: String!, $repo: String!, $first: Int!){ repository(owner: $owner, name: $repo) { @@ -306,42 +342,6 @@ function getRepoPackages(owner, repo, numPackages, startCursor, token) { exports.getRepoPackages = getRepoPackages; -/***/ }), - -/***/ 4223: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.graphql = void 0; -/* eslint-disable @typescript-eslint/no-unused-vars */ -const github_1 = __nccwpck_require__(5438); -/** - * Sends a GraphQL query request based on endpoint options - * - * @param {string} token Auth token - * @param {string} query GraphQL query. Example: `'query { viewer { login } }'`. - * @param {object} parameters URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`. - */ -function graphql(token, query, parameters) { - return __awaiter(this, void 0, void 0, function* () { - const github = new github_1.GitHub(token); - return yield github.graphql(query, parameters); - }); -} -exports.graphql = graphql; - - /***/ }), /***/ 221: @@ -484,7 +484,7 @@ exports.deletePackageVersions = exports.deletePackageVersion = void 0; // eslint-disable-next-line @typescript-eslint/no-unused-vars const rxjs_1 = __nccwpck_require__(5805); const operators_1 = __nccwpck_require__(7801); -const graphql_1 = __nccwpck_require__(6320); +const graphql_1 = __nccwpck_require__(9057); let deleted = 0; const mutation = ` mutation deletePackageVersion($packageVersionId: ID!) { @@ -534,7 +534,7 @@ exports.getOldestVersions = exports.queryForOldestVersions = void 0; // eslint-disable-next-line @typescript-eslint/no-unused-vars const rxjs_1 = __nccwpck_require__(5805); const operators_1 = __nccwpck_require__(7801); -const graphql_1 = __nccwpck_require__(6320); +const graphql_1 = __nccwpck_require__(9057); const query = ` query getVersions($owner: String!, $repo: String!, $package: String!, $last: Int!) { repository(owner: $owner, name: $repo) { @@ -651,42 +651,6 @@ function getOldestVersions(owner, repo, packageName, numVersions, startCursor, t exports.getOldestVersions = getOldestVersions; -/***/ }), - -/***/ 6320: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.graphql = void 0; -/* eslint-disable @typescript-eslint/no-unused-vars */ -const github_1 = __nccwpck_require__(5438); -/** - * Sends a GraphQL query request based on endpoint options - * - * @param {string} token Auth token - * @param {string} query GraphQL query. Example: `'query { viewer { login } }'`. - * @param {object} parameters URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`. - */ -function graphql(token, query, parameters) { - return __awaiter(this, void 0, void 0, function* () { - const github = new github_1.GitHub(token); - return yield github.graphql(query, parameters); - }); -} -exports.graphql = graphql; - - /***/ }), /***/ 4428: diff --git a/src/packages/graphql.ts b/src/common/graphql.ts similarity index 100% rename from src/packages/graphql.ts rename to src/common/graphql.ts diff --git a/src/packages/get-packages.ts b/src/packages/get-packages.ts index b29f8436..d714ab63 100644 --- a/src/packages/get-packages.ts +++ b/src/packages/get-packages.ts @@ -3,7 +3,7 @@ import {GraphQlQueryResponse} from '@octokit/graphql/dist-types/types' // eslint-disable-next-line @typescript-eslint/no-unused-vars import {Observable, from, throwError} from 'rxjs' import {catchError, map} from 'rxjs/operators' -import {graphql} from './graphql' +import {graphql} from '../common/graphql' export interface PackageInfo { id: string diff --git a/src/version/delete-version.ts b/src/version/delete-version.ts index d528ca1b..2f247e86 100644 --- a/src/version/delete-version.ts +++ b/src/version/delete-version.ts @@ -1,7 +1,7 @@ // eslint-disable-next-line @typescript-eslint/no-unused-vars import {from, Observable, merge, throwError, of} from 'rxjs' import {catchError, map, tap} from 'rxjs/operators' -import {graphql} from './graphql' +import {graphql} from '../common/graphql' let deleted = 0 diff --git a/src/version/get-versions.ts b/src/version/get-versions.ts index c49d57eb..8a0299b0 100644 --- a/src/version/get-versions.ts +++ b/src/version/get-versions.ts @@ -3,7 +3,7 @@ import {GraphQlQueryResponse} from '@octokit/graphql/dist-types/types' // eslint-disable-next-line @typescript-eslint/no-unused-vars import {Observable, from, throwError} from 'rxjs' import {catchError, map} from 'rxjs/operators' -import {graphql} from './graphql' +import {graphql} from '../common/graphql' export interface VersionInfo { id: string diff --git a/src/version/graphql.ts b/src/version/graphql.ts deleted file mode 100644 index cb6b2ede..00000000 --- a/src/version/graphql.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -import {GitHub} from '@actions/github' -import {GraphQlQueryResponseData} from '@octokit/graphql/dist-types/types' -import {RequestParameters} from '@octokit/types/dist-types/RequestParameters' - -/** - * Sends a GraphQL query request based on endpoint options - * - * @param {string} token Auth token - * @param {string} query GraphQL query. Example: `'query { viewer { login } }'`. - * @param {object} parameters URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`. - */ -export async function graphql( - token: string, - query: string, - parameters: RequestParameters -): Promise { - const github = new GitHub(token) - return await github.graphql(query, parameters) -} From 7aa510172bbfffa65375bc5e3c3e33c84c3bb519 Mon Sep 17 00:00:00 2001 From: Cas van Luijtelaar Date: Wed, 1 Mar 2023 11:46:17 +0100 Subject: [PATCH 17/20] fix merge conflicts --- __tests__/packages/graphql.mock.ts | 2 +- package-lock.json | 5 ++- package.json | 1 + src/common/graphql.ts | 20 ++++++++++++ src/delete.ts | 49 +++++++++++++++++++++++++++++- src/input.ts | 5 +++ 6 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 src/common/graphql.ts diff --git a/__tests__/packages/graphql.mock.ts b/__tests__/packages/graphql.mock.ts index 181434c7..a6601488 100644 --- a/__tests__/packages/graphql.mock.ts +++ b/__tests__/packages/graphql.mock.ts @@ -9,7 +9,7 @@ import {GetPackagesQueryResponse} from '../../src/packages' export function getMockedPackagesQueryResponse( numPackages: number ): GetPackagesQueryResponse { - const packages = [] + const packages: any[] = [] for (let i = 1; i <= numPackages; ++i) { packages.push({ node: { diff --git a/package-lock.json b/package-lock.json index 436811f8..94554553 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@actions/core": "^1.9.1", "@actions/github": "^2.1.1", "@octokit/rest": "^19.0.5", + "graphql": "^16.6.0", "rxjs": "^6.5.4" }, "devDependencies": { @@ -4131,7 +4132,6 @@ "version": "16.6.0", "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.6.0.tgz", "integrity": "sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw==", - "dev": true, "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } @@ -11008,8 +11008,7 @@ "graphql": { "version": "16.6.0", "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.6.0.tgz", - "integrity": "sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw==", - "dev": true + "integrity": "sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw==" }, "has": { "version": "1.0.3", diff --git a/package.json b/package.json index 790ad587..4af36b70 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@actions/core": "^1.9.1", "@actions/github": "^2.1.1", "@octokit/rest": "^19.0.5", + "graphql": "^16.6.0", "rxjs": "^6.5.4" }, "devDependencies": { diff --git a/src/common/graphql.ts b/src/common/graphql.ts new file mode 100644 index 00000000..1f5d5608 --- /dev/null +++ b/src/common/graphql.ts @@ -0,0 +1,20 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import {GitHub} from '@actions/github' +import {GraphQlQueryResponseData} from '@octokit/graphql/dist-types/types' +import {RequestParameters} from '@octokit/types/dist-types/RequestParameters' + +/** + * Sends a GraphQL query request based on endpoint options + * + * @param {string} token Auth token + * @param {string} query GraphQL query. Example: `'query { viewer { login } }'`. + * @param {object} parameters URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`. + */ +export async function graphql( + token: string, + query: string, + parameters: RequestParameters +): Promise { + const github = new GitHub(token) + return await github.graphql(query, parameters) +} \ No newline at end of file diff --git a/src/delete.ts b/src/delete.ts index e701c163..eb10558b 100644 --- a/src/delete.ts +++ b/src/delete.ts @@ -2,16 +2,35 @@ import {Input} from './input' import {EMPTY, Observable, of, throwError} from 'rxjs' -import {reduce, concatMap, map, expand, tap} from 'rxjs/operators' +import {reduce, concatMap, map, expand, tap, mergeMap} from 'rxjs/operators' import { deletePackageVersions, getOldestVersions, RestVersionInfo } from './version' +import {getRepoPackages, getPackageNameFilter, PackageInfo} from './packages' + export const RATE_LIMIT = 100 let totalCount = 0 +export function getPackageNames( + owner: string, + repo: string, + numPackages: number, + cursor: string, + token: string +): Observable { + return getRepoPackages(owner, repo, numPackages, cursor, token).pipe( + expand(value => + value.paginate + ? getRepoPackages(owner, repo, numPackages, value.cursor, token) + : EMPTY + ), + map(value => value.packages) + ) +} + export function getVersionIds( owner: string, packageName: string, @@ -51,6 +70,34 @@ export function finalIds(input: Input): Observable { return of(input.packageVersionIds.slice(0, toDelete)) } if (input.hasOldestVersionQueryInfo()) { + + const filter = getPackageNameFilter(input.packageNames) + if (!filter.isEmpty) { + return getPackageNames( + input.owner, + input.repo, + RATE_LIMIT, + '', + input.token + ) + .pipe( + mergeMap(value => { + return value + .filter(info => filter.apply(info.name)) + .map(info => + finalIds( + new Input({ + ...input, + packageNames: '', + packageName: info.name + }) + ) + ) + }) + ) + .pipe(mergeMap(val => val)) + } + return getVersionIds( input.owner, input.packageName, diff --git a/src/input.ts b/src/input.ts index 7c990e39..20d6debc 100644 --- a/src/input.ts +++ b/src/input.ts @@ -1,6 +1,7 @@ export interface InputParams { packageVersionIds?: string[] owner?: string + repo?: string packageName?: string packageType?: string packageNames?: string @@ -14,6 +15,7 @@ export interface InputParams { const defaultParams = { packageVersionIds: [], owner: '', + repo: '', packageName: '', packageType: '', packageNames: '', @@ -27,6 +29,7 @@ const defaultParams = { export class Input { packageVersionIds: string[] owner: string + repo: string packageName: string packageType: string packageNames: string @@ -42,6 +45,7 @@ export class Input { this.packageVersionIds = validatedParams.packageVersionIds this.owner = validatedParams.owner + this.repo = validatedParams.repo this.packageName = validatedParams.packageName this.packageType = validatedParams.packageType this.packageNames = validatedParams.packageNames @@ -56,6 +60,7 @@ export class Input { hasOldestVersionQueryInfo(): boolean { return !!( this.owner && + this.repo && (this.packageName || this.packageNames) && this.numOldVersionsToDelete >= 0 && this.token From 968ce24232946fb49e5b34d42bd19bcf2d556622 Mon Sep 17 00:00:00 2001 From: Cas van Luijtelaar Date: Wed, 1 Mar 2023 12:01:26 +0100 Subject: [PATCH 18/20] cleanup --- src/common/graphql.ts | 3 +-- src/delete.ts | 2 -- src/packages/get-packages.ts | 3 +-- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/common/graphql.ts b/src/common/graphql.ts index 1f5d5608..764a0945 100644 --- a/src/common/graphql.ts +++ b/src/common/graphql.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ import {GitHub} from '@actions/github' import {GraphQlQueryResponseData} from '@octokit/graphql/dist-types/types' import {RequestParameters} from '@octokit/types/dist-types/RequestParameters' @@ -17,4 +16,4 @@ export async function graphql( ): Promise { const github = new GitHub(token) return await github.graphql(query, parameters) -} \ No newline at end of file +} diff --git a/src/delete.ts b/src/delete.ts index eb10558b..57dfbf99 100644 --- a/src/delete.ts +++ b/src/delete.ts @@ -10,7 +10,6 @@ import { } from './version' import {getRepoPackages, getPackageNameFilter, PackageInfo} from './packages' - export const RATE_LIMIT = 100 let totalCount = 0 @@ -70,7 +69,6 @@ export function finalIds(input: Input): Observable { return of(input.packageVersionIds.slice(0, toDelete)) } if (input.hasOldestVersionQueryInfo()) { - const filter = getPackageNameFilter(input.packageNames) if (!filter.isEmpty) { return getPackageNames( diff --git a/src/packages/get-packages.ts b/src/packages/get-packages.ts index d714ab63..3f686bc5 100644 --- a/src/packages/get-packages.ts +++ b/src/packages/get-packages.ts @@ -1,6 +1,5 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars import {GraphQlQueryResponse} from '@octokit/graphql/dist-types/types' -// eslint-disable-next-line @typescript-eslint/no-unused-vars + import {Observable, from, throwError} from 'rxjs' import {catchError, map} from 'rxjs/operators' import {graphql} from '../common/graphql' From e9cb747d51e698b83153b96cd25a44b704e0323d Mon Sep 17 00:00:00 2001 From: Cas van Luijtelaar Date: Wed, 1 Mar 2023 17:22:35 +0100 Subject: [PATCH 19/20] wevrbf --- src/delete.ts | 2 +- src/version/get-versions.ts | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/delete.ts b/src/delete.ts index 57dfbf99..04351517 100644 --- a/src/delete.ts +++ b/src/delete.ts @@ -2,7 +2,7 @@ import {Input} from './input' import {EMPTY, Observable, of, throwError} from 'rxjs' -import {reduce, concatMap, map, expand, tap, mergeMap} from 'rxjs/operators' +import {reduce, concatMap, map, expand, tap, mergeMap, catchError} from 'rxjs/operators' import { deletePackageVersions, getOldestVersions, diff --git a/src/version/get-versions.ts b/src/version/get-versions.ts index eb8e274e..07e5fc80 100644 --- a/src/version/get-versions.ts +++ b/src/version/get-versions.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import {from, Observable, merge, throwError, of} from 'rxjs' +import {from, Observable, merge, throwError, of, EMPTY} from 'rxjs' import {catchError, map} from 'rxjs/operators' import {Octokit} from '@octokit/rest' import {RestEndpointMethodTypes} from '@octokit/plugin-rest-endpoint-methods/dist-types/generated/parameters-and-response-types' @@ -45,12 +45,7 @@ export function getOldestVersions( }) ).pipe( catchError(err => { - const msg = 'get versions API failed.' - return throwError( - err.errors && err.errors.length > 0 - ? `${msg} ${err.errors[0].message}` - : `${msg} ${err.message}` - ) + return EMPTY }), map(response => { const resp = { From 23d1b6ff03aa4f273630e6f0d1b9891c6920555d Mon Sep 17 00:00:00 2001 From: Cas van Luijtelaar Date: Thu, 2 Mar 2023 14:44:36 +0100 Subject: [PATCH 20/20] Revert "cleanup" This reverts commit 968ce24232946fb49e5b34d42bd19bcf2d556622. --- src/common/graphql.ts | 3 ++- src/delete.ts | 2 ++ src/packages/get-packages.ts | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/common/graphql.ts b/src/common/graphql.ts index 764a0945..1f5d5608 100644 --- a/src/common/graphql.ts +++ b/src/common/graphql.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ import {GitHub} from '@actions/github' import {GraphQlQueryResponseData} from '@octokit/graphql/dist-types/types' import {RequestParameters} from '@octokit/types/dist-types/RequestParameters' @@ -16,4 +17,4 @@ export async function graphql( ): Promise { const github = new GitHub(token) return await github.graphql(query, parameters) -} +} \ No newline at end of file diff --git a/src/delete.ts b/src/delete.ts index 04351517..40fdb902 100644 --- a/src/delete.ts +++ b/src/delete.ts @@ -10,6 +10,7 @@ import { } from './version' import {getRepoPackages, getPackageNameFilter, PackageInfo} from './packages' + export const RATE_LIMIT = 100 let totalCount = 0 @@ -69,6 +70,7 @@ export function finalIds(input: Input): Observable { return of(input.packageVersionIds.slice(0, toDelete)) } if (input.hasOldestVersionQueryInfo()) { + const filter = getPackageNameFilter(input.packageNames) if (!filter.isEmpty) { return getPackageNames( diff --git a/src/packages/get-packages.ts b/src/packages/get-packages.ts index 3f686bc5..d714ab63 100644 --- a/src/packages/get-packages.ts +++ b/src/packages/get-packages.ts @@ -1,5 +1,6 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars import {GraphQlQueryResponse} from '@octokit/graphql/dist-types/types' - +// eslint-disable-next-line @typescript-eslint/no-unused-vars import {Observable, from, throwError} from 'rxjs' import {catchError, map} from 'rxjs/operators' import {graphql} from '../common/graphql'