mirror of https://github.com/renovatebot/renovate
113 lines
2.5 KiB
TypeScript
113 lines
2.5 KiB
TypeScript
import { logger } from '../../../logger';
|
|
import { isNotNullOrUndefined } from '../../../util/array';
|
|
import type { Http } from '../../../util/http';
|
|
import { MaybeTimestamp } from '../../../util/timestamp';
|
|
import type { Release, ReleaseResult } from '../types';
|
|
import { type File, PagedResponseSchema } from './schema/prefix-dev';
|
|
|
|
const MAX_PREFIX_DEV_GRAPHQL_PAGE = 100;
|
|
|
|
const query = `
|
|
query search($channel: String!, $package: String!, $page: Int = 0) {
|
|
package(channelName: $channel, name: $package) {
|
|
variants(limit: 500, page: $page) {
|
|
pages
|
|
page {
|
|
createdAt
|
|
version
|
|
yankedReason
|
|
urls {
|
|
url
|
|
kind
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`;
|
|
|
|
export async function getReleases(
|
|
http: Http,
|
|
channel: string,
|
|
packageName: string,
|
|
): Promise<ReleaseResult | null> {
|
|
logger.debug(
|
|
{ channel, packageName },
|
|
'lookup package from prefix.dev graphql API',
|
|
);
|
|
|
|
const files = await getPagedResponse(http, query, {
|
|
channel,
|
|
package: packageName,
|
|
});
|
|
|
|
if (!files.length) {
|
|
return null;
|
|
}
|
|
|
|
let homepage: string | undefined = undefined;
|
|
let sourceUrl: string | undefined = undefined;
|
|
|
|
const releases: Record<string, Release> = {};
|
|
for (const file of files) {
|
|
const version = file.version;
|
|
|
|
homepage ??= file.urls.HOME;
|
|
sourceUrl ??= file.urls.DEV;
|
|
|
|
releases[version] ??= { version };
|
|
|
|
// we assume all packages are roughly released on the same time
|
|
releases[version].releaseTimestamp =
|
|
releases[version].releaseTimestamp ??
|
|
MaybeTimestamp.parse(file.createdAt);
|
|
|
|
// if the version has not been marked as deprecated, check other releases packages of the same version
|
|
releases[version].isDeprecated ??= isNotNullOrUndefined(file.yankedReason);
|
|
}
|
|
|
|
return {
|
|
homepage,
|
|
sourceUrl,
|
|
releases: Object.values(releases),
|
|
};
|
|
}
|
|
|
|
async function getPagedResponse(
|
|
http: Http,
|
|
query: string,
|
|
data: any,
|
|
): Promise<File[]> {
|
|
const result: File[] = [];
|
|
|
|
for (let page = 0; page <= MAX_PREFIX_DEV_GRAPHQL_PAGE; page++) {
|
|
const res = await http.postJson(
|
|
'https://prefix.dev/api/graphql',
|
|
{
|
|
body: {
|
|
operationName: 'search',
|
|
query,
|
|
variables: {
|
|
...data,
|
|
page,
|
|
},
|
|
},
|
|
},
|
|
PagedResponseSchema,
|
|
);
|
|
|
|
const currentPage = res.body.data.package?.variants;
|
|
if (!currentPage) {
|
|
break;
|
|
}
|
|
|
|
result.push(...currentPage.page);
|
|
|
|
if (page >= currentPage.pages - 1) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|