async updIndividualPkgDetails(pkgName, dependencyDetails) {
        if ( this.uibPackageJson === null ) throw new Error('[uibuilder:UibPackages.js:updIndividualPkgDetails] this.uibPackageJson is null')
        const pj = this.uibPackageJson

        if ( pj.uibuilder === undefined || pj.uibuilder.packages === undefined || pj.dependencies === undefined ) throw new Error('pgkMgt:updIndividualPkgDetails: pj.uibuilder, pj.uibuilder.packages or pj.dependencies is undefined')

        // Make sure only packages in uibRoot/package.json dependencies are processed
        if ( !pj.dependencies[pkgName] ) return

        const packages =  pj.uibuilder.packages

        packages[pkgName] = {}
        const pkg = packages[pkgName]

        const lsp = dependencyDetails[pkgName]
        // save the version/location spec from the dependencies prop so everything is together
        pkg.spec = pj.dependencies[pkgName]

        if ( lsp.missing ) {
            pkg.missing = true
            pkg.problems = lsp.problems
        } else {
            // Get/Update package details
            pkg.installFolder = lsp.path
            pkg.installedVersion = lsp.version

            /** If we can, lets work out what resource is actually needed
             *  when using one of these packages in the browser.
             *  If we can't, leave a ? to make it obvious
             * Annoyingly, a few packages have decided to make the `browser` property an object instead of a string.
             *   (e.g. vgauge) - ignore in that case as it isn't clear what the intent is.
             */
            if (lsp.browser && (typeof lsp.browser === 'string') ) pkg.estimatedEntryPoint = lsp.browser
            else if (lsp.jsdelivr) pkg.estimatedEntryPoint = lsp.jsdelivr
            else if (lsp.unpkg) pkg.estimatedEntryPoint = lsp.unpkg
            else if (lsp.main) pkg.estimatedEntryPoint = lsp.main
            else pkg.estimatedEntryPoint = '?'
            if ( pkg.estimatedEntryPoint === 'none') pkg.estimatedEntryPoint = '?'

            // Homepage - used for a help ref in the Editor
            if (lsp.homepage) pkg.homepage = lsp.homepage
            else pkg.homepage = `https://www.npmjs.com/search?q=${pkgName}`

            // The base url used by uib - note this is changed if this is a scoped package
            pkg.packageUrl = '/' + pkgName

            // As the url may have changed (by removing scope), record the usable url
            pkg.url = `../uibuilder/vendor${pkg.packageUrl}/${pkg.estimatedEntryPoint}`

            // If the package name is npm @scoped, remove the scope, add leading / & track scope name
            if ( pkgName.startsWith('@') ) {
                // pkg.packageUrl = '/' + pkgName.replace(/^@.*\//, '')
                pkg.scope = pkgName.replace(pkg.packageUrl, '')
            }
        }

        if ( pj.dependencies[pkgName] && pj.dependencies[pkgName].includes(':') ) {
            // Must be installed from somewhere other than npmjs so don't try to find latest version
            pkg.latestVersion = null
            pkg.installedFrom = pj.dependencies[pkgName].split(':')[0]
            pkg.outdated = {}
        } else {
            pkg.installedFrom = 'npm'

            // Add current version details
            let res = await this.npmOutdated(pkgName)
            try {
                res = JSON.parse(res)
            } catch (e) { /* */ }
            if ( res[pkgName] ) {
                res = {
                    current: res[pkgName].current,
                    wanted: res[pkgName].wanted,
                    latest: res[pkgName].latest,
                }
            }
            pkg.outdated = res
        }
    }
Write updated <folder>/package.json (async)
Also makes a backup copy to package.json.bak
@param {string} folder The folder where to write the file
@param {object} json The Object data to write to the file