diff --git a/lib/modules/manager/composer/schema.ts b/lib/modules/manager/composer/schema.ts index fb8c2a8af2c9d7656ebc7079b2c0b1c1f43d9e64..5d0ac8e7e4f8174f8e3a009a11433c382fe815b2 100644 --- a/lib/modules/manager/composer/schema.ts +++ b/lib/modules/manager/composer/schema.ts @@ -26,19 +26,26 @@ export type ComposerRepo = z.infer<typeof ComposerRepo>; export const GitRepo = z.object({ type: z.enum(['vcs', 'git']).transform(() => 'git' as const), url: z.string(), + name: z.string().optional(), }); export type GitRepo = z.infer<typeof GitRepo>; export const PathRepo = z.object({ type: z.literal('path'), url: z.string(), + name: z.string().optional(), }); export type PathRepo = z.infer<typeof PathRepo>; +export const PackageRepo = z.object({ + type: z.literal('package'), +}); + export const Repo = z.discriminatedUnion('type', [ ComposerRepo, GitRepo, PathRepo, + PackageRepo, ]); export type Repo = z.infer<typeof ComposerRepo>; @@ -46,6 +53,7 @@ export const NamedRepo = z.discriminatedUnion('type', [ ComposerRepo, GitRepo.extend({ name: z.string() }), PathRepo.extend({ name: z.string() }), + PackageRepo, ]); export type NamedRepo = z.infer<typeof NamedRepo>; @@ -54,7 +62,7 @@ export type DisablePackagist = z.infer<typeof DisablePackagist>; export const ReposRecord = LooseRecord(z.union([Repo, z.literal(false)]), { onError: ({ error: err }) => { - logger.warn({ err }, 'Composer: error parsing repositories object'); + logger.debug({ err }, 'Composer: error parsing repositories object'); }, }).transform((repos) => { const result: (NamedRepo | DisablePackagist)[] = []; @@ -83,7 +91,7 @@ export type ReposRecord = z.infer<typeof ReposRecord>; export const ReposArray = LooseArray( z.union([ - NamedRepo, + Repo, z .union([ z.object({ packagist: z.literal(false) }), @@ -93,17 +101,28 @@ export const ReposArray = LooseArray( ]), { onError: ({ error: err }) => { - logger.warn({ err }, 'Composer: error parsing repositories array'); + logger.debug({ err }, 'Composer: error parsing repositories array'); }, } -).transform((repos) => repos.filter((x): x is NamedRepo => x !== null)); +).transform((repos) => { + const result: (NamedRepo | DisablePackagist)[] = []; + 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; +}); export type ReposArray = z.infer<typeof ReposArray>; export const Repos = z .union([ReposRecord, ReposArray]) .default([]) // Prevents warnings for packages without repositories field .catch(({ error: err }) => { - logger.warn({ err }, 'Composer: repositories parsing error'); + logger.debug({ err }, 'Composer: invalid "repositories" field'); return []; }) .transform((repos) => { @@ -210,13 +229,20 @@ export const ComposerExtract = z lockfile: z .string() .transform((lockfileName) => readLocalFile(lockfileName, 'utf8')) - .pipe(Json) - .pipe(Lockfile) - .nullable() - .catch(({ error: err }) => { - logger.warn({ err }, 'Composer: lockfile parsing error'); - return null; - }), + .pipe( + z.union([ + z.null(), + z + .string() + .pipe(Json) + .pipe(Lockfile) + .nullable() + .catch(({ error: err }) => { + logger.debug({ err }, 'Composer: lockfile parsing error'); + return null; + }), + ]) + ), }) ) .transform(({ file, lockfile, lockfileName }) => {