UNPKG

roblox-ts

Version:

<div align="center"><img width=25% src="https://i.imgur.com/yCjHmng.png"></div> <h1 align="center"><a href="https://roblox-ts.github.io/">roblox-ts</a></h1> <div align="center">A TypeScript-to-Lua Compiler for Roblox</div> <br> <div align="center"> <a hr

243 lines 9.62 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const ajv_1 = __importDefault(require("ajv")); const fs_extra_1 = __importDefault(require("fs-extra")); const path_1 = __importDefault(require("path")); const ajv = new ajv_1.default(); class RojoProjectError extends Error { } exports.RojoProjectError = RojoProjectError; const ROJO_METADATA_REGEX = /^\$/; const LUA_EXT = ".lua"; const FOLDER_EXT = ""; const SUB_EXT_TYPE_MAP = new Map([ ["", "ModuleScript"], [".server", "Script"], [".client", "LocalScript"], ]); const DEFAULT_ISOLATED_CONTAINERS = [ ["StarterPack"], ["StarterGui"], ["StarterPlayer", "StarterPlayerScripts"], ["StarterPlayer", "StarterCharacterScripts"], ["StarterPlayer", "StarterCharacter"], ]; const CLIENT_CONTAINERS = [["StarterPack"], ["StarterGui"], ["StarterPlayer"]]; const SERVER_CONTAINERS = [["ServerStorage"], ["ServerScriptService"]]; function stripExts(filePath) { const ext = path_1.default.extname(filePath); filePath = filePath.slice(0, -ext.length); const subext = path_1.default.extname(filePath); if (subext.length > 0) { filePath = filePath.slice(0, -subext.length); } return filePath; } function arrayStartsWith(a, b) { const minLength = Math.min(a.length, b.length); for (let i = 0; i < minLength; i++) { if (a[i] !== b[i]) { return false; } } return true; } var FileRelation; (function (FileRelation) { FileRelation[FileRelation["OutToOut"] = 0] = "OutToOut"; FileRelation[FileRelation["OutToIn"] = 1] = "OutToIn"; FileRelation[FileRelation["InToOut"] = 2] = "InToOut"; FileRelation[FileRelation["InToIn"] = 3] = "InToIn"; })(FileRelation = exports.FileRelation || (exports.FileRelation = {})); var NetworkType; (function (NetworkType) { NetworkType[NetworkType["Unknown"] = 0] = "Unknown"; NetworkType[NetworkType["Client"] = 1] = "Client"; NetworkType[NetworkType["Server"] = 2] = "Server"; })(NetworkType = exports.NetworkType || (exports.NetworkType = {})); class RojoProject { constructor(basePath, config) { this.partitions = new Array(); this.isolatedContainers = [...DEFAULT_ISOLATED_CONTAINERS]; this.basePath = basePath; this.tree = config.tree; this.parseTree(config.tree, []); } parseTree(tree, rbxPath) { if (tree.$path) { const ext = path_1.default.extname(tree.$path); if (ext === LUA_EXT || ext === FOLDER_EXT) { this.partitions.push({ base: [...rbxPath], fsPath: path_1.default.resolve(this.basePath, tree.$path), isFile: ext === LUA_EXT, }); } } if (tree.$isolated === true) { this.isolatedContainers.push([...rbxPath]); } for (const childName of Object.keys(tree).filter(v => !ROJO_METADATA_REGEX.test(v))) { rbxPath.push(childName); this.parseTree(tree[childName], rbxPath); rbxPath.pop(); } } static fromPath(rojoPath) { return __awaiter(this, void 0, void 0, function* () { if (!path_1.default.isAbsolute(rojoPath)) { rojoPath = path_1.default.resolve(rojoPath); } if (yield fs_extra_1.default.pathExists(rojoPath)) { if (!this.validateRojo) { this.validateRojo = ajv.compile(JSON.parse((yield fs_extra_1.default.readFile(path_1.default.join(__dirname, "..", "rojo-schema.json"))).toString())); } const objectJson = JSON.parse((yield fs_extra_1.default.readFile(rojoPath)).toString()); if (this.validateRojo(objectJson)) { return new RojoProject(path_1.default.resolve(rojoPath, ".."), objectJson); } else { throw new RojoProjectError("Invalid Rojo configuration!\n" + JSON.stringify(this.validateRojo.errors)); } } else { throw new RojoProjectError(`${rojoPath} is not a valid path!`); } }); } static fromPathSync(rojoPath) { if (!path_1.default.isAbsolute(rojoPath)) { rojoPath = path_1.default.resolve(rojoPath); } if (fs_extra_1.default.pathExistsSync(rojoPath)) { if (!this.validateRojo) { this.validateRojo = ajv.compile(JSON.parse(fs_extra_1.default.readFileSync(path_1.default.join(__dirname, "..", "rojo-schema.json")).toString())); } const objectJson = JSON.parse(fs_extra_1.default.readFileSync(rojoPath).toString()); if (this.validateRojo(objectJson)) { return new RojoProject(path_1.default.resolve(rojoPath, ".."), objectJson); } else { throw new RojoProjectError("Invalid Rojo configuration!\n" + JSON.stringify(this.validateRojo.errors)); } } else { throw new RojoProjectError(`${rojoPath} is not a valid path!`); } } static cwd() { return __awaiter(this, void 0, void 0, function* () { return this.fromPath(process.cwd()); }); } getRbxPathFromFile(filePath) { if (!path_1.default.isAbsolute(filePath)) { filePath = path_1.default.resolve(this.basePath, filePath); } for (const partition of this.partitions) { if (partition.isFile) { if (partition.fsPath === filePath) { return [...partition.base]; } } else { if (filePath.startsWith(partition.fsPath)) { const relative = path_1.default.relative(partition.fsPath, stripExts(filePath)).split(path_1.default.sep); if (relative[relative.length - 1] === "init") { relative.pop(); } return partition.base.concat(relative); } } } } getRbxFromFile(filePath) { const subext = path_1.default.extname(path_1.default.basename(filePath, path_1.default.extname(filePath))); return { path: this.getRbxPathFromFile(filePath), type: SUB_EXT_TYPE_MAP.get(subext) || "Unknown", }; } isGame() { return this.tree.$className === "DataModel"; } getContainer(from, rbxPath) { if (this.isGame()) { if (rbxPath) { for (const container of from) { if (arrayStartsWith(rbxPath, container)) { return container; } } } } } getFileRelation(filePath, modulePath) { const fileContainer = this.getContainer(this.isolatedContainers, this.getRbxPathFromFile(filePath)); const moduleContainer = this.getContainer(this.isolatedContainers, this.getRbxPathFromFile(modulePath)); if (fileContainer && moduleContainer) { if (fileContainer === moduleContainer) { return FileRelation.InToIn; } else { return FileRelation.OutToIn; } } else if (fileContainer && !moduleContainer) { return FileRelation.InToOut; } else if (!fileContainer && moduleContainer) { return FileRelation.OutToIn; } else { // !fileContainer && !moduleContainer return FileRelation.OutToOut; } } isIsolated(filePath) { return this.getContainer(this.isolatedContainers, this.getRbxPathFromFile(filePath)) !== undefined; } getNetworkType(filePath) { const rbxPath = this.getRbxPathFromFile(filePath); if (this.getContainer(SERVER_CONTAINERS, rbxPath)) { return NetworkType.Server; } if (this.getContainer(CLIENT_CONTAINERS, rbxPath)) { return NetworkType.Client; } return NetworkType.Unknown; } static relative(rbxFrom, rbxTo) { const maxLength = Math.max(rbxFrom.length, rbxTo.length); let diffIndex = maxLength; for (let i = 0; i < maxLength; i++) { if (rbxFrom[i] !== rbxTo[i]) { diffIndex = i; break; } } const result = new Array(); if (diffIndex < rbxFrom.length) { for (let i = 0; i < rbxFrom.length - diffIndex; i++) { result.push(".."); } } for (let i = diffIndex; i < rbxTo.length; i++) { result.push(rbxTo[i]); } return result; } } exports.RojoProject = RojoProject; //# sourceMappingURL=RojoProject.js.map