UNPKG

makecode-core

Version:

MakeCode (PXT) - web-cached build tool

283 lines 11.1 kB
"use strict"; /// <reference path="../external/pxtpackage.d.ts" /> Object.defineProperty(exports, "__esModule", { value: true }); exports.stringifyConfig = exports.setLogging = exports.debug = exports.error = exports.log = exports.Project = exports.cloudRoot = void 0; exports.downloader = require("./downloader"); exports.files = require("./files"); exports.service = require("./service"); exports.loader = require("./loader"); const files_1 = require("./files"); exports.cloudRoot = "https://makecode.com/api/"; function jsonCopyFrom(trg, src) { let v = JSON.parse(JSON.stringify(src)); for (let k of Object.keys(src)) { ; trg[k] = v[k]; } } class Project { constructor(directory, cache = null) { this.directory = directory; this.cache = cache; this.writePxtModules = true; this.linkPxtModules = false; this.symlinkPxtModules = false; this.outputPrefix = "built"; } get hwVariant() { return this._hwVariant; } set hwVariant(value) { this._hwVariant = value; if (this.mainPkg) this.mainPkg.mkcConfig.hwVariant = value; } async guessHwVariantAsync() { var _a; if (this.mainPkg.mkcConfig.hwVariant) return; const variants = await this.service.getHardwareVariantsAsync(); const cfg = this.mainPkg.config; for (const v of variants) { if (cfg.dependencies[v.name] || ((_a = cfg.testDependencies) === null || _a === void 0 ? void 0 : _a[v.name])) { (0, exports.log)("guessing hw-variant: " + hwid(v)); this.hwVariant = hwid(v); return; } } (0, exports.log)("selecting first hw-variant: " + hwid(variants[0])); this.hwVariant = hwid(variants[0]); function hwid(cfg) { return cfg.name.replace(/hw---/, ""); } } readFileAsync(filename) { return exports.files.readPrjFileAsync(this.directory, filename); } saveBuiltFilesAsync(res) { return exports.files.saveBuiltFilesAsync(this.directory, res, this.outputPrefix); } async savePxtModulesAsync(filesmap0) { var _a; let filesmap = filesmap0; if (this.linkPxtModules || this.symlinkPxtModules) { let libsPath = await exports.files.findParentDirWithAsync("..", "pxtarget.json"); if (libsPath) libsPath = exports.files.relativePath(".", libsPath).replace(/\\/g, "/") + "/libs"; filesmap = JSON.parse(JSON.stringify(filesmap0)); const pxtmod = "pxt_modules/"; const filesByPkg = {}; const filenames = Object.keys(filesmap); for (const s of filenames) { if (s.startsWith(pxtmod)) { const id = s.slice(pxtmod.length).replace(/\/.*/, ""); if (!filesByPkg[id]) filesByPkg[id] = []; filesByPkg[id].push(s); } } for (const id of Object.keys(filesByPkg)) { let lnk = (_a = this.mkcConfig.links) === null || _a === void 0 ? void 0 : _a[id]; let rel = ""; if (lnk) rel = exports.files.relativePath(this.directory + "/pxt_modules/foobar", lnk); else if (await exports.files.fileExistsAsync(`${libsPath}/${id}/pxt.json`)) { lnk = `${libsPath}/${id}`; rel = `../../${lnk}`; } if (lnk && this.linkPxtModules) { for (const fn of filesByPkg[id]) delete filesmap[fn]; (0, exports.log)(`link ${id} -> ${lnk}`); const pxtJson = JSON.stringify({ additionalFilePath: rel, }, null, 4); filesmap["pxt_modules/" + id + "/pxt.json"] = pxtJson; if (/---/.test(id)) { filesmap["pxt_modules/" + id.replace(/---.*/, "") + "/pxt.json"] = pxtJson; } } else if (lnk && this.symlinkPxtModules) { for (const fn of filesByPkg[id]) { const bn = fn.replace(/.*\//, ""); if (await exports.files.fileExistsAsync(`${lnk}/${bn}`)) { filesmap[fn] = { symlink: `${rel}/${bn}` }; // log(`symlink ${fn} -> ${rel}/${bn}`) } else { (0, exports.log)(`not link ${fn}`); } } } } } return exports.files.savePxtModulesAsync(this.directory, filesmap); } async readPxtConfig() { const pxtJson = await this.readFileAsync("pxt.json"); return JSON.parse(pxtJson); } async readPackageAsync() { if (!this.mkcConfig) this.mkcConfig = JSON.parse(await this.readFileAsync("mkc.json").then(s => s, _err => "{}")); const res = { config: await this.readPxtConfig(), mkcConfig: this.mkcConfig, files: {}, }; if (res.mkcConfig.overrides) jsonCopyFrom(res.config, res.mkcConfig.overrides); res.files["pxt.json"] = stringifyConfig(res.config); for (let f of res.config.files.concat(res.config.testFiles || [])) { res.files[f] = await this.readFileAsync(f); } if (res.files["main.ts"] === undefined) res.files["main.ts"] = ""; // avoid bogus warning from PXT return res; } async loadPkgAsync() { if (this.mainPkg) return; const prj = await this.readPackageAsync(); exports.loader.guessMkcJson(prj); if (this.hwVariant) prj.mkcConfig.hwVariant = this.hwVariant; // TODO handle require("lzma") in worker prj.config.binaryonly = true; const pxtJson = (prj.files["pxt.json"] = stringifyConfig(prj.config)); this.mainPkg = prj; if (pxtJson != this.lastPxtJson) { this.lastPxtJson = pxtJson; if (this.service) await this.service.setUserAsync(null); } } updateEditorAsync() { return this.loadEditorAsync(true); } async loadEditorAsync(forceUpdate = false) { if (this.editor && !forceUpdate) return false; await this.loadPkgAsync(); const newEditor = await exports.downloader.downloadAsync(await this.getCacheAsync(), this.mainPkg.mkcConfig.targetWebsite, !forceUpdate); if (!this.editor || newEditor.versionNumber != this.editor.versionNumber) { this.editor = newEditor; if (this.service) { this.service.dispose(); } this.service = new exports.service.Ctx(this.editor); return true; } else { return false; } } async getCacheAsync() { if (!this.cache) this.cache = await exports.files.mkHomeCacheAsync(); return this.cache; } async maybeWritePxtModulesAsync() { await this.loadEditorAsync(); await this.loadPkgAsync(); const wasThis = this.service.lastUser == this; this.service.setUserAsync(this); if (this.service.supportsGhPkgs) { await this.service.installGhPackagesAsync(this.mainPkg); } else { await exports.loader.loadDeps(this.editor, this.mainPkg); } if (this.writePxtModules && !wasThis) { (0, exports.log)("writing pxt_modules/*"); await this.savePxtModulesAsync(this.mainPkg.files); } } async linkedPackage(id) { var _a, _b, _c; const folder = (_c = (_b = (_a = this.mainPkg) === null || _a === void 0 ? void 0 : _a.mkcConfig) === null || _b === void 0 ? void 0 : _b.links) === null || _c === void 0 ? void 0 : _c[id]; if (folder) return exports.files.readProjectAsync(folder); return null; } async buildAsync(simpleOpts = {}) { var _a; this.mainPkg = null; // force reload await this.maybeWritePxtModulesAsync(); await this.service.setUserAsync(this); const res = await this.service.simpleCompileAsync(this.mainPkg, simpleOpts); const err = res.errorMessage; if (err) throw new Error(err); const binjs = "binary.js"; if (res.outfiles[binjs]) { const appTarget = await this.service.languageService.getAppTargetAsync(); const boardDef = (_a = appTarget.simulator) === null || _a === void 0 ? void 0 : _a.boardDefinition; if (boardDef) { res.outfiles[binjs] = `// boardDefinition=${JSON.stringify(boardDef)}\n` + res.outfiles[binjs]; } const webConfig = this.editor.webConfig || (await this.service.languageService.getWebConfigAsync()); const configs = await (0, files_1.monoRepoConfigsAsync)(this.directory, true); const version = `v${await (0, files_1.collectCurrentVersionAsync)(configs) || "0"}`; const meta = { simUrl: webConfig.simUrl, cdnUrl: webConfig.cdnUrl, version, target: appTarget.id, targetVersion: appTarget.versions.target, }; res.outfiles[binjs] = `// meta=${JSON.stringify(meta)}\n` + res.outfiles[binjs]; } await this.saveBuiltFilesAsync(res); //delete res.outfiles //delete (res as any).procDebugInfo //console.log(res) return res; } async buildSimJsInfoAsync(result) { return await this.service.buildSimJsInfoAsync(result); } async mkChildProjectAsync(folder) { const prj = new Project(folder, await this.getCacheAsync()); prj.service = this.service; prj.mkcConfig = this.mkcConfig; if (this._hwVariant) prj.hwVariant = this._hwVariant; prj.outputPrefix = this.outputPrefix; prj.writePxtModules = this.writePxtModules; prj.editor = this.editor; return prj; } } exports.Project = Project; let log = (msg) => { console.log(msg); }; exports.log = log; let error = (msg) => { console.error(msg); }; exports.error = error; let debug = (msg) => { console.debug(msg); }; exports.debug = debug; function setLogging(fns) { exports.log = fns.log; exports.error = fns.error; exports.debug = fns.debug; } exports.setLogging = setLogging; function stringifyConfig(cfg) { return JSON.stringify(cfg, null, 4) + "\n"; } exports.stringifyConfig = stringifyConfig; //# sourceMappingURL=mkc.js.map