How to iterate through object through multiple level nested objects

There is a object with some file informations for each library. Some of these have values for dependencies, which can be a npm package or another library in this object.

Now I need to get the npm packages of all affected libraries.

I tried to create this reduce, but with that I only get the first level npm packages.

export const getUsedDeps = (deps) => {
    const directDependencies = deps.reduce(
    (depsAcc, dep) => {
        if (dep?.type === 'static') {
        const isNpmPackage = dep.target.match(regexIsNpm)
        const depName = isNpmPackage?.[1]
        const version = getVersion(depName)

        // Check if npm package, then add to result object, else iterate dependencies
        if (depName && version) {
            depsAcc[depName] = version
        } else if (!isNpmPackage) {
            return {
            ...depsAcc,
            ...getUsedDependencies(rootPackage, deps, depName)
            }
        }
        }
        return depsAcc
    },
    {}
    )
    return directDependencies
}

@apollo/client (which is in a library dependency) is missing – see example data below.

In this example you could easily get all npm packages of languages-backend by using map(). But there is also languages-util-graphql as a dependency. So in this case I also have to get "npm:@apollo/client".
In this way of course there could be multiple level nested dependecies. So I have to handle the looping. That’s why I tried to use reduce().

Another problem is how to also handle circuit dependencies – which should be there, but I have to handle this error. For example languages-util-graphql depends on languages-backend.

const deps = {
"languages-backend": {
    "data": {
    "files": [
        {
        "file": "apps/languages/backend/project.json",
        "hash": "55ca6cd2c772625ed7f6265c587366244ec33c1c"
        },
        {
        "file": "apps/languages/backend/src/app/app.module.ts",
        "hash": "4d583158d652329bee41c3424d6d98a72b6a5fd5",
        "deps": [
            "npm:@nestjs/common",
            "npm:@nestjs/graphql",
            "npm:@nestjs/config"
        ]
        },
        {
        "file": "apps/languages/backend/src/app/app.service.ts",
        "hash": "4bc9870b67f86c46ea8b4d9fbfcda1982cd73151",
        "deps": [
            "npm:@nestjs/common"
        ]
        },
        {
        "file": "apps/languages/backend/src/app/dictionary/dictionary.resolvers.ts",
        "hash": "798e56123950ad6fbb3c3229a3f1c3408415e397",
        "deps": [
            "npm:@nestjs/graphql",
            "languages-util-graphql"
        ]
        },
        {
        "file": "apps/languages/backend/src/app/dictionary/dictionary.service.ts",
        "hash": "c66a1106fad68ac4d9d4164fd129524314851f71",
        "deps": [
            "npm:check-types",
            "npm:nanoid",
            "npm:@nestjs/common",
            "npm:mongodb",
            "languages-util-graphql"
        ]
        },
        {
        "file": "apps/languages/backend/src/main.ts",
        "hash": "ee24ba3ce6ee4ed7ac398e5c59785ed2ec5b573e",
        "deps": [
            "npm:helmet",
            "npm:@nestjs/common",
            "npm:@nestjs/core"
        ]
        }
    ]
    }
},
"languages-util-graphql": {
    "data": {
    "files": [
        {
        "file": "libs/languages/util-graphql/src/lib/generated.ts",
        "hash": "882e919d29255013450a5a0644c6a0a6f8bf4b37",
        "deps": [
            "npm:@apollo/client"
        ]
        },
        {
        "file": "libs/languages/util-graphql/tsconfig.json",
        "hash": "667a3463d1d1367fdaa0a33be5eded304f7873f1"
        }
    ]
    }
}
}

The result should be (the version values get calculated in an external function):

{
    '@nestjs/common': '^8.2.3',
    '@nestjs/graphql': '^9.1.2',
    '@nestjs/config': '^1.1.6',
    'check-types': '^11.1.2',
    'nanoid': '^3.1.30',
    'mongodb': '^4.2.1',
    'helmet': '^4.6.0',
    '@apollo/client': '^3.5.6',
    '@nestjs/core': '^8.2.3'
}