UNPKG

gamelet-cli

Version:

Download project from code.gamelet.com, edit/test in vscode and sync back to server.

773 lines 72 kB
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.download = void 0;
const file_1 = require("../utils/file");
const net_1 = require("../utils/net");
const merges_1 = require("./merges");
const cli_progress_1 = __importDefault(require("cli-progress"));
const inquirer_1 = __importDefault(require("inquirer"));
const ArrayUtil_1 = require("../server/utils/ArrayUtil");
const tempFolder = '/.temp';
const cliFolder = __dirname + '/../../..';
const dtsPrepend = "// @ts-nocheck\n";
const download = ({ projectCode, folder, token, sourceHandler, targetItems, force, debug }) => {
    let fullProject;
    let engineInfo;
    (0, net_1.apiSetToken)(token);
    (0, file_1.setFileCacheFolder)(folder);
    return Promise.resolve()
        .then(() => {
        if (!projectCode) {
            return Promise.reject('Please specify a project code that is created on code.gamelet.com');
        }
        if (!folder) {
            return Promise.reject('Please specify a folder to install');
        }
        if (!token) {
            return Promise.reject('No valid token is provided');
        }
        return Promise.resolve();
    })
        .then(() => (0, file_1.isEmptyFolder)(folder))
        .then(empty => {
        if (sourceHandler == 'download') {
            if (debug) {
                // just do it
            }
            else if (!empty) {
                return inquirer_1.default.prompt([
                    {
                        type: 'list',
                        name: 'confirm',
                        message: 'The folder is not empty!',
                        choices: [
                            'Quit',
                            'Force downloading project into this folder'
                        ]
                    }
                ])
                    .then(choice => {
                    if (choice.confirm == 'Quit') {
                        return Promise.reject('Quit: The folder is not empty.');
                    }
                    else {
                        return Promise.resolve();
                    }
                });
            }
            else {
                console.log(`Create workspace in ${folder}/ ...`);
            }
        }
        else {
            console.log('sync workspace from CG ...');
        }
    })
        .then(() => (0, file_1.rmdir)(`${folder}${tempFolder}`).catch(_e => { }))
        .then(() => Promise.all([
        getEngineInfo().then(info => (engineInfo = info)),
        (0, net_1.apiGet)(`/get/full_project/${projectCode}`)
            .then(json => fullProject = json),
    ]))
        .then(() => updatePackageJsons(fullProject, folder))
        .then(() => saveToken(fullProject, token, folder))
        .then(() => secureSourcesBase(fullProject, folder, token))
        .then(() => includeItem(targetItems, 'source') && downloadSources(fullProject, folder, token, sourceHandler, force))
        .then(() => includeItem(targetItems, 'resource') && downloadResources(fullProject, folder, 3))
        .then(() => (includeItem(targetItems, 'source') || includeItem(targetItems, 'resource')) &&
        downloadStaticFiles(engineInfo, folder)
            .then(() => adjustStaticFiles(fullProject, folder)))
        .then(() => includeItem(targetItems, 'score') && downloadScoreModes(fullProject, folder))
        .then(() => includeItem(targetItems, 'item') && downloadItems(fullProject, folder))
        .then(() => includeItem(targetItems, 'badge') && downloadBadges(fullProject, folder))
        .then(() => (0, file_1.wait)(300))
        .then(() => (0, file_1.rmdir)(`${folder}${tempFolder}`).catch(_e => { }))
        .then(() => {
        console.log();
        console.log('done');
    })
        .catch(err => {
        console.log();
        console.error(err);
    })
        .then(() => console.log());
};
exports.download = download;
function secureSourcesBase(fullProject, folder, token) {
    let basePath = getSourceBasePath(folder);
    if (!(0, file_1.fileExists)(basePath)) {
        let progressBar = new cli_progress_1.default.SingleBar({}, cli_progress_1.default.Presets.shades_classic);
        console.log('Missing sources.base, downloading from CG ...');
        let tempName = Date.now().toString(36) + '.' + Math.round(10 + Math.random() * 1000000).toString(36);
        return (0, file_1.downloadFile)((0, net_1.cgUrl)(`/download/${fullProject.project.code}?token=${token}`), basePath, progressBar, {
            tempFile: `${folder}${tempFolder}/${tempName}.zip`,
            noCache: true,
        })
            .then(() => progressBar && progressBar.stop());
    }
    else {
        return Promise.resolve();
    }
}
function includeItem(targetItems, item) {
    return !targetItems || targetItems.includes(item);
}
function saveToken(fullProject, token, folder) {
    let filename = `${fullProject.project.code.toLowerCase()}.token`;
    let fullpath = `${folder}/.cg/${filename}`;
    return checkSavedToken(fullpath, token)
        .then(saved => {
        if (!saved) {
            console.log(`Building workspace: saving access token ...`);
            return (0, file_1.saveData)(fullpath, token)
                .then(() => deleteOldTokens(folder, filename))
                .then(() => { });
        }
        else {
            return Promise.resolve();
        }
    });
}
function deleteOldTokens(folder, currentTokenFile) {
    let path = `${folder}/.cg`;
    return (0, file_1.listFiles)(path)
        .then(files => {
        files = files.filter(f => f != currentTokenFile && f.toLowerCase().endsWith('.token'));
        return Promise.all(files.map(f => (0, file_1.unlink)(`${path}/${f}`)));
    });
}
function checkSavedToken(filename, token) {
    if ((0, file_1.fileExists)(filename)) {
        return (0, file_1.getFileString)(filename, true)
            .then(savedToken => token == savedToken);
    }
    else {
        return Promise.resolve(false);
    }
}
function getEngineInfo() {
    return (0, net_1.apiGet)(`/get/engine_info`);
}
function updatePackageJsons(fullProject, folder) {
    console.log(`Building workspace: update package configs ...`);
    return Promise.all([
        createPackageJson(fullProject.project, folder),
        createTsconfig(fullProject.project, folder),
        (0, file_1.copyFile)(cliFolder + '/assets/gitignore.txt', `${folder}/.gitignore`),
        (0, file_1.copyFile)(cliFolder + '/assets/common.d.ts', `${folder}/typings/common.d.ts`),
        mergeLaunchJson(folder),
    ]);
}
function mergeLaunchJson(folder) {
    let srcFile = cliFolder + '/assets/launch.json';
    let destFile = `${folder}/.vscode/launch.json`;
    if ((0, file_1.fileExists)(destFile)) {
        return Promise.all([(0, file_1.getFileJson)(srcFile, true), (0, file_1.getFileJson)(destFile, true)])
            .then(results => {
            let needSave = false;
            let srcJson = results[0];
            let destJson = results[1];
            srcJson.configurations = srcJson.configurations || [];
            srcJson.configurations.forEach(config => {
                let search = destJson.configurations.find(c => c.name == config.name);
                if (!search) {
                    destJson.configurations.push(config);
                    needSave = true;
                }
            });
            if (needSave) {
                return (0, file_1.saveData)(destFile, JSON.stringify(destJson, null, 4));
            }
            else {
                return Promise.resolve();
            }
        })
            .catch(_e => {
            return (0, file_1.copyFile)(srcFile, destFile);
        });
    }
    else {
        return (0, file_1.copyFile)(srcFile, destFile);
    }
}
async function createPackageJson(projectJson, folder) {
    let lastBuildVer = projectJson.lastBuildVer || '0.0.0';
    let verArr = lastBuildVer.split('.').map(str => Number(str));
    verArr[2]++;
    let nextVer = verArr.join('.');
    let content = await (0, file_1.renderTwig)(cliFolder + '/assets/package.json.twig', {
        CG_URL: (0, net_1.cgUrl)(''),
        project: projectJson,
        version: nextVer,
    });
    if ((0, file_1.fileExists)(folder + '/package.json')) {
        try {
            const contentJson = JSON.parse(content);
            let current = await (0, file_1.getFileJson)(folder + '/package.json', true);
            contentJson.devDependencies = mergeDependencies(contentJson.devDependencies, current.devDependencies);
            Object.assign(current, contentJson);
            content = JSON.stringify(current, null, 4);
        }
        catch (e) {
        }
    }
    await (0, file_1.saveData)(folder + '/package.json', content);
}
function mergeDependencies(list1, list2) {
    const deps = [];
    const codes1 = Object.keys(list1);
    for (let lib in list1) {
        deps.push({
            lib: lib,
            version: list1[lib],
        });
    }
    for (let lib in list2) {
        if (!codes1.includes(lib)) {
            deps.push({
                lib: lib,
                version: list2[lib],
            });
        }
    }
    ArrayUtil_1.ArrayUtil.sortOn(deps, 'lib', true);
    const result = {};
    for (let dep of deps) {
        result[dep.lib] = dep.version;
    }
    return result;
}
function createTsconfig(projectJson, folder) {
    return (0, file_1.renderTwig)(cliFolder + '/assets/tsconfig.json.twig', {
        CG_URL: (0, net_1.cgUrl)(''),
        project: projectJson,
    })
        .then(content => (0, file_1.saveData)(folder + '/tsconfig.json', content));
}
let sourcesProcessing;
function downloadSources(fullProject, folder, token, sourceHandler, force) {
    if (sourceHandler == 'skip') {
        return Promise.resolve();
    }
    console.log(`Building workspace: download sources ...`);
    return (0, file_1.isGitCommitted)(folder)
        .then(committed => {
        if (!committed && !force) {
            return Promise.reject('Please commit your current sources first.');
        }
        else {
            return Promise.resolve();
        }
    })
        .then(() => {
        let zipFilename = folder + tempFolder + '/sources.zip';
        let progressBar = new cli_progress_1.default.SingleBar({}, cli_progress_1.default.Presets.shades_classic);
        sourcesProcessing = [];
        return (0, file_1.downloadFile)((0, net_1.cgUrl)(`/download/${fullProject.project.code}?token=${token}`), zipFilename, progressBar, { noCache: true })
            .then(() => {
            progressBar.stop();
            return (0, file_1.getFileZip)(zipFilename);
        })
            .then(jszip => {
            if (sourceHandler == 'merge') {
                return mergeSources(jszip, folder);
            }
            else {
                return overwriteSources(jszip, folder);
            }
        })
            .then(result => result && (0, file_1.moveFile)(zipFilename, getSourceBasePath(folder)));
    });
}
function getSourceBasePath(folder) {
    return `${folder}/.cg/sources.base`;
}
function overwriteSources(jszip, folder) {
    let saveSrcFiles = [];
    let progressBar = new cli_progress_1.default.SingleBar({
        format: ` {bar} {percentage}% | Overwriting ({value}/{total})`
    }, cli_progress_1.default.Presets.shades_classic);
    for (let filename in jszip.files) {
        if (filename.startsWith('src/')) {
            saveSrcFiles.push(saveSrcFile(jszip.file(filename), folder, progressBar));
        }
    }
    progressBar.start(saveSrcFiles.length, 0);
    return Promise.all(saveSrcFiles)
        .then(() => {
        progressBar && progressBar.stop();
        return true;
    });
}
function saveSrcFile(file, dest, progressBar) {
    if (sourcesProcessing.length > 49) {
        return (0, file_1.wait)(10).then(() => saveSrcFile(file, dest, progressBar));
    }
    sourcesProcessing.push(file);
    return file.async('string')
        .then(content => {
        return (0, file_1.saveData)(dest + '/' + file.name, content);
    })
        .then(() => {
        progressBar && progressBar.increment(1);
        let index = sourcesProcessing.indexOf(file);
        sourcesProcessing.splice(index, 1);
    });
}
function mergeSources(jszip, folder) {
    let basezip = getSourceBasePath(folder);
    if (!(0, file_1.fileExists)(basezip)) {
        return Promise.reject('Cannot merge: source base missing.');
    }
    return (0, file_1.getFileZip)(basezip)
        .then(basezip => {
        let saveSrcFiles = [];
        let progressBar = new cli_progress_1.default.SingleBar({
            format: ` {bar} {percentage}% | Merging ({value}/{total})`
        }, cli_progress_1.default.Presets.shades_classic);
        for (let filename in jszip.files) {
            if (filename.startsWith('src/')) {
                saveSrcFiles.push(mergeSrcFile(jszip.file(filename), basezip.file(filename), folder, progressBar));
            }
        }
        return Promise.all(saveSrcFiles)
            //.then(results => !results.find(result => !result))
            .then(results => {
            progressBar && progressBar.stop();
            results.filter(result => result.name == 'deleted').forEach(result => {
                console.log(`Source deleted: ${result.filename}`);
            });
            results.filter(result => result.name == 'added').forEach(result => {
                console.log(`Source added: ${result.filename}`);
            });
            return true;
        });
    });
}
function mergeSrcFile(file, base, folder, progressBar) {
    if (sourcesProcessing.length > 19) {
        return (0, file_1.wait)(30).then(() => mergeSrcFile(file, base, folder, progressBar));
    }
    sourcesProcessing.push(file);
    return Promise.all([fileToText(file), fileToText(base)])
        .then(contents => {
        return (0, merges_1.sourceMerge)(file.name, contents[0], contents[1], folder);
    })
        .then(result => {
        progressBar && progressBar.increment(1);
        let index = sourcesProcessing.indexOf(file);
        sourcesProcessing.splice(index, 1);
        return result;
    });
}
function fileToText(file) {
    if (file) {
        return file.async('string');
    }
    else {
        return Promise.resolve(null);
    }
}
function isLibArchive(resource, file) {
    return resource.type.startsWith('build') && file.endsWith('archive.zip');
}
let resourceTotalBar;
let resourceBars;
function addResourceProgress() {
    resourceTotalBar && resourceTotalBar.increment(1);
}
function downloadResources(fullProject, folder, concurrent) {
    console.log(`Building workspace: download resources ...`);
    return Promise.resolve()
        .then(() => (0, file_1.listFiles)(`${folder}/resource`))
        .then(oldDirs => {
        let pack = fullProject.resourcePack;
        let resToLoad = [];
        let resIds = [];
        for (let alias in pack.aliasMap) {
            let resourceInfo = pack.aliasMap[alias];
            let resource = pack.resourceMap[resourceInfo.resourceId];
            resIds.push(resourceInfo.resourceId);
            for (let file of resource.meta.files) {
                let info = {
                    file: file,
                    resource: resource,
                    alias: alias,
                };
                if (file.endsWith('.d.ts') || !isLibArchive(resource, file)) {
                    resToLoad.push(info);
                }
            }
            let oldDirIndex = oldDirs.indexOf(resource.id.toString(36));
            if (oldDirIndex != -1) {
                oldDirs.splice(oldDirIndex, 1);
            }
        }
        resourceBars = new cli_progress_1.default.MultiBar({
            clearOnComplete: false,
            hideCursor: true,
            format: ` {bar} {percentage}% | {file} ({value}/{total})`
        }, cli_progress_1.default.Presets.shades_classic);
        let collectInfo = {};
        resourceTotalBar = resourceBars.create(resToLoad.length, 0, { file: 'Total' });
        return startDownloadResources(collectInfo, resToLoad, folder, concurrent)
            .then(() => resourceBars && resourceBars.stop())
            .then(() => logDownloadResourceResult(collectInfo))
            .then(() => deleteResDirs(folder, oldDirs))
            .then(() => deleteOldDtses(folder, resIds));
    });
}
function logDownloadResourceResult(collectInfo) {
    let list = ArrayUtil_1.ArrayUtil.listValuesOfObject(collectInfo);
    let files = 0;
    for (let info of list) {
        files += info.files.length;
    }
    console.log(` ${list.length} resource(s) added (${files} file(s))`);
}
function deleteOldDtses(folder, resIds) {
    return (0, file_1.listFiles)(`${folder}/typings`)
        .then(files => {
        let filesToDelete = [];
        files.forEach(f => {
            let search = f.match(/\.cg_([a-z0-9]+)\.d\.ts$/);
            if (search) {
                let resId = parseInt(search[1], 36);
                if (!resIds.includes(resId)) {
                    filesToDelete.push(f);
                }
            }
        });
        sourcesProcessing = [];
        return Promise.all(filesToDelete.map(f => deleteFile(`${folder}/typings/${f}`)))
            .then(() => {
            console.log(` ${filesToDelete.length} old Dts removed`);
        });
    });
}
function deleteFile(file) {
    if (sourcesProcessing.length > 19) {
        return (0, file_1.wait)(30).then(() => deleteFile(file));
    }
    sourcesProcessing.push(file);
    return (0, file_1.unlink)(file)
        .then(() => {
        let index = sourcesProcessing.indexOf(file);
        sourcesProcessing.splice(index, 1);
    });
}
function deleteResDirs(folder, dirs) {
    sourcesProcessing = [];
    return Promise.all(dirs.map(dir => deleteResDir(folder, dir)))
        .then(() => console.log(` ${dirs.length} old resource(s) removed`));
}
function deleteResDir(folder, dir) {
    if (sourcesProcessing.length > 19) {
        return (0, file_1.wait)(30).then(() => deleteResDir(dir));
    }
    sourcesProcessing.push(dir);
    return (0, file_1.rmdir)(`${folder}/resource/${dir}`)
        .then(() => {
        let index = sourcesProcessing.indexOf(dir);
        sourcesProcessing.splice(index, 1);
    });
}
function startDownloadResources(collectInfo, resToLoad, folder, concurrent) {
    return Promise.all(resToLoad.map(info => {
        return downloadResource(collectInfo, info, folder, concurrent);
    }));
}
function getResourceFolder(folder, resource) {
    return `${folder}/resource/${resource.id.toString(36)}`;
}
function downloadResource(collectInfo, info, folder, concurrent) {
    if (resourceBars.bars.length > concurrent) {
        return (0, file_1.wait)(100).then(() => downloadResource(collectInfo, info, folder, concurrent));
    }
    let resource = info.resource;
    let file = info.file;
    let alias = info.alias;
    let url = (0, net_1.cgUrl)(`${resource.url}${file}`);
    let dest = getResourceFolder(folder, resource) + `/${file}`;
    let dispName = alias;
    let isDts = file.endsWith('.d.ts');
    let modifyContent = null;
    if (isDts) {
        let destFile = file.split('/').pop().replace(/\.d\.ts$/, `.cg_${resource.id.toString(36)}.d.ts`);
        dest = `${folder}/typings/${alias}_${destFile}`;
        dispName += '.d.ts';
        modifyContent = (content) => {
            if (!content.startsWith(dtsPrepend)) {
                content = dtsPrepend + content;
            }
            return content;
        };
    }
    let resourceBar = resourceBars.create(100, 0, { file: dispName });
    let tempName = Date.now().toString(36) + '.' + Math.round(10 + Math.random() * 1000000).toString(36);
    let tempFile = `${folder}${tempFolder}/${tempName}`;
    return (0, file_1.downloadFile)(url, dest, resourceBar, {
        dispName: dispName,
        tempFile: tempFile,
        appendSize: isDts ? dtsPrepend.length : 0,
        modifyContent: modifyContent,
    })
        .then(realDownload => {
        if (realDownload) {
            let resourceInfo = collectInfo[resource.id];
            if (!resourceInfo) {
                collectInfo[resource.id] = {
                    resource: resource,
                    files: [],
                };
            }
            collectInfo[resource.id].files.push(file);
        }
        addResourceProgress();
        resourceBars.remove(resourceBar);
    });
}
let staticBar;
function downloadStaticFiles(engineInfo, folder) {
    console.log(`Building workspace: download static files ...`);
    let version = 'min';
    //version = 'debug' + parseInt(engineInfo.version, 36).toString(24);
    let tempStaticFolder = `${folder}/.cg/static`;
    let promises = [
        downloadStaticFile(`${engineInfo.url}static/css/preload.css`, `${folder}/static/css/preload.css`),
        downloadStaticFile(`${engineInfo.url}static/img/logo_42.png`, `${folder}/static/img/logo_42.png`),
        downloadStaticFile(`https://cdnjs.cloudflare.com/ajax/libs/pace/1.0.2/pace.min.js`, `${folder}/static/js/pace.min.js`),
        downloadStaticFile(`${engineInfo.url}static/js/index.offline.html`, `${tempStaticFolder}/index.html`),
        downloadStaticFile(`${engineInfo.url}static/js/systemjs-starter.offline.${version}.js`, `${tempStaticFolder}/systemjs-starter.offline.js`),
        downloadStaticFile(`${engineInfo.url}static/js/systemjs-starter.offline-dev.${version}.js`, `${tempStaticFolder}/systemjs-starter.offline-dev.js`),
        downloadStaticFile(`${engineInfo.url}static/js/boot.prod.${version}.js`, `${tempStaticFolder}/boot.prod.js`),
    ];
    staticBar = new cli_progress_1.default.SingleBar({}, cli_progress_1.default.Presets.shades_classic);
    staticBar.start(promises.length, 0);
    return Promise.all(promises)
        .then(() => staticBar && staticBar.stop());
}
function downloadStaticFile(url, dest) {
    return (0, file_1.downloadFile)(url, dest)
        .then(() => staticBar && staticBar.increment(1));
}
function adjustStaticFiles(fullProject, folder) {
    return Promise.all([
        adjustIndexHtml(fullProject, folder),
        generateScriptJs(fullProject, folder),
    ])
        .catch(err => {
        console.error(err);
    });
}
function adjustIndexHtml(fullProject, folder) {
    let project = fullProject.project;
    let filename = `${folder}/.cg/static/index.html`;
    return (0, file_1.getFileString)(filename)
        .then(text => {
        text = text.replace('%appName%', project.name);
        text = text.replace('</body>', `    <script src="output/build.js" type="text/javascript"></script>\n</body>`);
        return (0, file_1.saveData)(`${folder}/index.html`, text);
    });
}
function generateScriptJs(fullProject, folder) {
    let project = fullProject.project;
    let staticCacheFolder = `${folder}/.cg/static`;
    let starterFilename = `${staticCacheFolder}/systemjs-starter.offline.js`;
    let booterFilename = `${staticCacheFolder}/boot.prod.js`;
    let devFilename = `${staticCacheFolder}/systemjs-starter.offline-dev.js`;
    let starterScripts;
    let scripts = '';
    let appendScripts = (_scripts, text) => {
        if (_scripts && !_scripts.endsWith(';')) {
            _scripts += ';';
        }
        return _scripts + text.trim();
    };
    return (0, net_1.apiGet)(`/get/offlineDevRenderParameters/${project.code}`)
        .then(renderParams => {
        return Promise.resolve()
            .then(() => {
            return (0, file_1.getFileString)(starterFilename)
                .then(content => {
                starterScripts = content.replace('"%CG_CFG%"', JSON.stringify({ data: renderParams }));
            });
        })
            .then(() => {
            return (0, file_1.getFileString)(devFilename)
                .then(content => {
                scripts = appendScripts(scripts, content);
            });
        })
            .then(() => {
            return (0, file_1.getFileString)(booterFilename)
                .then(content => {
                scripts = appendScripts(scripts, content);
            });
        })
            .then(() => {
            return (0, net_1.apiGet)(`/list/resources/dependency/project/${project.code}`);
        })
            .then(data => {
            let libs = data.list;
            let libsPack = {};
            return Promise.all(libs.map(lib => prepareLibContent(lib, libsPack, folder)))
                .then(() => {
                let systemBootFuncs = libs.map(lib => `function(){${libsPack[lib.id]};CgLibs.bootModule('${lib.meta.pcode}')}`);
                systemBootFuncs.unshift(`function(){CgLibs.initBoots([${libs.map(lib => JSON.stringify(lib)).join(',')}])}`);
                scripts = appendScripts(scripts, 'var __cgSystemBoots=[' + systemBootFuncs.join(',') + '];');
                scripts = appendScripts(scripts, starterScripts);
            });
        })
            .then(() => (0, file_1.saveData)(`${folder}/static/js/scripts.js`, scripts));
    });
}
function prepareLibContent(lib, libsPack, folder) {
    let file = `${folder}/resource/${lib.id.toString(36)}/${lib.meta.main}`;
    return (0, file_1.getFileString)(file)
        .then(content => {
        libsPack[lib.id] = content;
    });
}
function downloadBadges(fullProject, folder) {
    console.log(`Building workspace: download badges ...`);
    let project = fullProject.project;
    let data;
    return (0, net_1.apiPost)(`/glt/client/${project.code}`, {
        api: '/list/game_badges',
        data: {
            start: 0,
            length: 1000,
        }
    })
        .then(_d => (data = _d))
        .then(() => {
        let list = data.list;
        if (list.length) {
            return downloadBadgeImages(list, folder, 3);
        }
        else {
            console.log('  no badges found');
            return Promise.resolve();
        }
    })
        .then(() => (0, file_1.saveData)(`${folder}/static/json/badges.json`, JSON.stringify(data, null, 4)));
}
let badgeBars;
function downloadBadgeImages(badges, folder, concurrent) {
    badgeBars = new cli_progress_1.default.MultiBar({
        clearOnComplete: false,
        hideCursor: true,
        format: ` {bar} {percentage}% | {file} ({value}/{total})`
    }, cli_progress_1.default.Presets.shades_classic);
    let totalBar = badgeBars.create(badges.length, 0, { file: 'Total' });
    return Promise.all(badges.map(badge => {
        return downloadBadgeImage(badge, folder, concurrent)
            .then(() => totalBar && totalBar.increment(1));
    }))
        .then(() => badgeBars && badgeBars.stop());
}
function downloadBadgeImage(badge, folder, concurrent) {
    if (badgeBars.bars.length > concurrent) {
        return (0, file_1.wait)(100).then(() => downloadBadgeImage(badge, folder, concurrent));
    }
    let url = badge.iconUrl;
    let ext = url.split('.').pop();
    let dispName = badge.code;
    let localUri = `/static/img/badge/${badge.code}.${ext}`;
    let dest = `${folder}${localUri}`;
    badge.iconUrl = localUri;
    badge.aquired = 0;
    let badgeBar = badgeBars.create(100, 0, { file: dispName });
    let tempName = Date.now().toString(36) + '.' + Math.round(10 + Math.random() * 1000000).toString(36);
    let tempFile = `${folder}${tempFolder}/${tempName}`;
    return (0, file_1.downloadFile)(url, dest, badgeBar, {
        dispName: dispName,
        tempFile: tempFile,
    })
        .then(() => badgeBars.remove(badgeBar));
}
function downloadItems(fullProject, folder) {
    console.log(`Building workspace: download items ...`);
    let project = fullProject.project;
    let pack = fullProject.resourcePack;
    let refPcodes = [];
    let data;
    for (let id in pack.resourceMap) {
        let resource = pack.resourceMap[id];
        if (resource.type == 'buildLib' && resource.meta.gitems) {
            let pcode = resource.meta.pcode;
            if (!refPcodes.includes(pcode)) {
                refPcodes.push(pcode);
            }
        }
    }
    return (0, net_1.apiPost)(`/glt/client/${project.code}`, {
        api: '/list/game_items',
        data: {
            refPcodes: refPcodes.join(','),
            start: 0,
            length: 1000,
        }
    })
        .then(_d => (data = _d))
        .then(() => {
        let list = data.list;
        if (list.length) {
            return downloadItemImages(list, folder, 3);
        }
        else {
            console.log('  no items found');
            return Promise.resolve();
        }
    })
        .then(() => (0, file_1.saveData)(`${folder}/static/json/items.json`, JSON.stringify(data, null, 4)));
}
let itemBars;
function downloadItemImages(items, folder, concurrent) {
    itemBars = new cli_progress_1.default.MultiBar({
        clearOnComplete: false,
        hideCursor: true,
        format: ` {bar} {percentage}% | {file} ({value}/{total})`
    }, cli_progress_1.default.Presets.shades_classic);
    let totalBar = itemBars.create(items.length, 0, { file: 'Total' });
    return Promise.all(items.map(item => {
        return downloadItemImage(item, folder, concurrent)
            .then(() => totalBar && totalBar.increment(1));
    }))
        .then(() => itemBars && itemBars.stop());
}
function downloadItemImage(item, folder, concurrent) {
    if (itemBars.bars.length > concurrent) {
        return (0, file_1.wait)(100).then(() => downloadItemImage(item, folder, concurrent));
    }
    let url = item.iconUrl;
    let ext = url.split('.').pop();
    let dispName = item.code;
    let localUri = `/static/img/item/${item.code}.${ext}`;
    let dest = `${folder}${localUri}`;
    item.iconUrl = localUri;
    let itemBar = itemBars.create(100, 0, { file: dispName });
    let tempName = Date.now().toString(36) + '.' + Math.round(10 + Math.random() * 1000000).toString(36);
    let tempFile = `${folder}${tempFolder}/${tempName}`;
    return (0, file_1.downloadFile)(url, dest, itemBar, {
        dispName: dispName,
        tempFile: tempFile,
    })
        .then(() => itemBars.remove(itemBar));
}
function downloadScoreModes(fullProject, folder) {
    console.log(`Building workspace: download score modes ...`);
    let project = fullProject.project;
    let data;
    return (0, net_1.apiPost)(`/glt/client/${project.code}`, {
        api: '/list/score_modes',
        data: {}
    })
        .then(_d => (data = _d))
        .then(() => (0, file_1.saveData)(`${folder}/static/json/score_modes.json`, JSON.stringify(data, null, 4)));
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG93bmxvYWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZ2FtZWxldC9kb3dubG9hZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSx3Q0FBOE47QUFDOU4sc0NBQW1FO0FBQ25FLHFDQUEyRDtBQUMzRCxnRUFBdUM7QUFDdkMsd0RBQWdDO0FBQ2hDLHlEQUFzRDtBQUV0RCxNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUE7QUFDM0IsTUFBTSxTQUFTLEdBQUcsU0FBUyxHQUFHLFdBQVcsQ0FBQztBQUMxQyxNQUFNLFVBQVUsR0FBRyxrQkFBa0IsQ0FBQztBQUUvQixNQUFNLFFBQVEsR0FBRyxDQUFDLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRTtJQUNqRyxJQUFJLFdBQVcsQ0FBQztJQUNoQixJQUFJLFVBQVUsQ0FBQztJQUNmLElBQUEsaUJBQVcsRUFBQyxLQUFLLENBQUMsQ0FBQztJQUNuQixJQUFBLHlCQUFrQixFQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRTNCLE9BQU8sT0FBTyxDQUFDLE9BQU8sRUFBRTtTQUNuQixJQUFJLENBQUMsR0FBRyxFQUFFO1FBQ1AsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ2YsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLG1FQUFtRSxDQUFDLENBQUM7UUFDL0YsQ0FBQztRQUNELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNWLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDO1FBQ2hFLENBQUM7UUFDRCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDVCxPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsNEJBQTRCLENBQUMsQ0FBQztRQUN4RCxDQUFDO1FBQ0QsT0FBTyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDN0IsQ0FB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