renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
278 lines • 9.99 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ComposerExtract = exports.Lockfile = exports.PackageFile = exports.Repos = exports.ReposArray = exports.ReposRecord = exports.NamedRepo = exports.Repo = exports.PackageRepo = exports.PathRepo = exports.GitRepo = exports.ComposerRepo = void 0;
const zod_1 = require("zod");
const logger_1 = require("../../../logger");
const fs_1 = require("../../../util/fs");
const regex_1 = require("../../../util/regex");
const schema_utils_1 = require("../../../util/schema-utils");
const bitbucket_tags_1 = require("../../datasource/bitbucket-tags");
const git_tags_1 = require("../../datasource/git-tags");
const github_tags_1 = require("../../datasource/github-tags");
const packagist_1 = require("../../datasource/packagist");
const composer_1 = require("../../versioning/composer");
exports.ComposerRepo = zod_1.z.object({
type: zod_1.z.literal('composer'),
/**
* The regUrl is expected to be a base URL. GitLab composer repository installation guide specifies
* to use a base URL containing packages.json. Composer still works in this scenario by determining
* whether to add / remove packages.json from the URL.
*
* See https://github.com/composer/composer/blob/750a92b4b7aecda0e5b2f9b963f1cb1421900675/src/Composer/Repository/ComposerRepository.php#L815
*/
url: zod_1.z.string().transform((url) => url.replace(/\/packages\.json$/, '')),
});
exports.GitRepo = zod_1.z.object({
type: zod_1.z.enum(['vcs', 'git']).transform(() => 'git'),
url: zod_1.z.string(),
name: zod_1.z.string().optional(),
});
exports.PathRepo = zod_1.z.object({
type: zod_1.z.literal('path'),
url: zod_1.z.string(),
name: zod_1.z.string().optional(),
});
exports.PackageRepo = zod_1.z.object({
type: zod_1.z.literal('package'),
});
exports.Repo = zod_1.z.discriminatedUnion('type', [
exports.ComposerRepo,
exports.GitRepo,
exports.PathRepo,
exports.PackageRepo,
]);
exports.NamedRepo = zod_1.z.discriminatedUnion('type', [
exports.ComposerRepo,
exports.GitRepo.extend({ name: zod_1.z.string() }),
exports.PathRepo.extend({ name: zod_1.z.string() }),
exports.PackageRepo,
]);
const DisablePackagist = zod_1.z.object({ type: zod_1.z.literal('disable-packagist') });
const bitbucketUrlRegex = (0, regex_1.regEx)(/^(?:https:\/\/|git@)bitbucket\.org[/:](?<packageName>[^/]+\/[^/]+?)(?:\.git)?$/);
exports.ReposRecord = (0, schema_utils_1.LooseRecord)(zod_1.z.union([exports.Repo, zod_1.z.literal(false)]), {
onError: ({ error: err }) => {
logger_1.logger.debug({ err }, 'Composer: error parsing repositories object');
},
}).transform((repos) => {
const result = [];
for (const [name, repo] of Object.entries(repos)) {
if (repo === false) {
if (name === 'packagist' || name === 'packagist.org') {
result.push({ type: 'disable-packagist' });
}
continue;
}
if (repo.type === 'path' || repo.type === 'git') {
result.push({ name, ...repo });
continue;
}
if (repo.type === 'composer') {
result.push(repo);
continue;
}
}
return result;
});
exports.ReposArray = (0, schema_utils_1.LooseArray)(zod_1.z.union([
exports.Repo,
zod_1.z
.union([
zod_1.z.object({ packagist: zod_1.z.literal(false) }),
zod_1.z.object({ 'packagist.org': zod_1.z.literal(false) }),
])
.transform(() => ({ type: 'disable-packagist' })),
]), {
onError: ({ error: err }) => {
logger_1.logger.debug({ err }, 'Composer: error parsing repositories array');
},
}).transform((repos) => {
const result = [];
for (let idx = 0; idx < repos.length; idx++) {
const repo = repos[idx];
if (repo.type === 'path' || repo.type === 'git') {
result.push({ name: `__${idx}`, ...repo });
}
else {
result.push(repo);
}
}
return result;
});
exports.Repos = zod_1.z
.union([exports.ReposRecord, exports.ReposArray])
.default([]) // Prevents warnings for packages without repositories field
.catch((0, schema_utils_1.withDebugMessage)([], 'Composer: invalid "repositories" field'))
.transform((repos) => {
let packagist = true;
const repoUrls = [];
const gitRepos = {};
const pathRepos = {};
for (const repo of repos) {
if (repo.type === 'composer') {
repoUrls.push(repo.url);
}
else if (repo.type === 'git') {
gitRepos[repo.name] = repo;
}
else if (repo.type === 'path') {
pathRepos[repo.name] = repo;
}
else if (repo.type === 'disable-packagist') {
packagist = false;
}
}
if (packagist && repoUrls.length) {
repoUrls.push('https://repo.packagist.org');
}
const registryUrls = repoUrls.length ? repoUrls : null;
return { registryUrls, gitRepos, pathRepos };
});
const RequireDefs = (0, schema_utils_1.LooseRecord)(zod_1.z.string().transform((x) => x.trim())).catch({});
exports.PackageFile = zod_1.z
.object({
type: zod_1.z.string().optional(),
config: zod_1.z
.object({
platform: zod_1.z.object({
php: zod_1.z.string(),
}),
})
.nullable()
.catch(null),
repositories: exports.Repos,
require: RequireDefs,
'require-dev': RequireDefs,
})
.transform(({ type: composerJsonType, config, repositories, require, 'require-dev': requireDev, }) => ({
composerJsonType,
config,
repositories,
require,
requireDev,
}));
const LockedPackage = zod_1.z.object({
name: zod_1.z.string(),
version: zod_1.z.string(),
});
exports.Lockfile = zod_1.z
.object({
'plugin-api-version': zod_1.z.string().optional(),
packages: (0, schema_utils_1.LooseArray)(LockedPackage).catch([]),
'packages-dev': (0, schema_utils_1.LooseArray)(LockedPackage).catch([]),
})
.transform(({ 'plugin-api-version': pluginApiVersion, packages, 'packages-dev': packagesDev, }) => ({ pluginApiVersion, packages, packagesDev }));
exports.ComposerExtract = zod_1.z
.object({
content: zod_1.z.string(),
fileName: zod_1.z.string(),
})
.transform(({ content, fileName }) => {
const lockfileName = fileName.replace(/\.json$/, '.lock');
return {
file: content,
lockfileName,
lockfile: lockfileName,
};
})
.pipe(zod_1.z.object({
file: schema_utils_1.Json.pipe(exports.PackageFile),
lockfileName: zod_1.z.string(),
lockfile: zod_1.z
.string()
.transform((lockfileName) => (0, fs_1.readLocalFile)(lockfileName, 'utf8'))
.pipe(zod_1.z.union([
zod_1.z.null(),
zod_1.z
.string()
.pipe(schema_utils_1.Json)
.pipe(exports.Lockfile)
.nullable()
.catch((0, schema_utils_1.withDebugMessage)(null, 'Composer: does not match schema')),
])),
}))
.transform(({ file, lockfile, lockfileName }) => {
const { composerJsonType, require, requireDev } = file;
const { registryUrls, gitRepos, pathRepos } = file.repositories;
const deps = [];
const profiles = [
{
depType: 'require',
req: require,
locked: lockfile?.packages ?? [],
},
{
depType: 'require-dev',
req: requireDev,
locked: lockfile?.packagesDev ?? [],
},
];
for (const { depType, req, locked } of profiles) {
for (const [depName, currentValue] of Object.entries(req)) {
if (depName === 'php') {
deps.push({
depType,
depName,
currentValue,
datasource: github_tags_1.GithubTagsDatasource.id,
packageName: 'containerbase/php-prebuild',
});
continue;
}
if (pathRepos[depName]) {
deps.push({
depType,
depName,
currentValue,
skipReason: 'path-dependency',
});
continue;
}
const dep = {
depType,
depName,
currentValue,
};
if (!depName.includes('/')) {
dep.skipReason = 'unsupported';
}
const lockedDep = locked.find((item) => item.name === depName);
if (lockedDep && composer_1.api.isVersion(lockedDep.version)) {
dep.lockedVersion = lockedDep.version.replace((0, regex_1.regEx)(/^v/i), '');
}
const gitRepo = gitRepos[depName];
if (gitRepo) {
const bitbucketMatchGroups = bitbucketUrlRegex.exec(gitRepo.url)?.groups;
if (bitbucketMatchGroups) {
dep.datasource = bitbucket_tags_1.BitbucketTagsDatasource.id;
dep.packageName = bitbucketMatchGroups.packageName;
deps.push(dep);
continue;
}
dep.datasource = git_tags_1.GitTagsDatasource.id;
dep.packageName = gitRepo.url;
deps.push(dep);
continue;
}
dep.datasource = packagist_1.PackagistDatasource.id;
if (registryUrls) {
dep.registryUrls = registryUrls;
}
deps.push(dep);
}
}
if (!deps.length) {
return null;
}
const res = { deps };
if (composerJsonType) {
res.managerData = { composerJsonType };
}
if (require.php) {
res.extractedConstraints = { php: require.php };
}
if (lockfile) {
res.lockFiles = [lockfileName];
}
return res;
});
//# sourceMappingURL=schema.js.map