Home Reference Source

cables_dev/cables_electron/src/utils/ops_util.js

  1. import { utilProvider, SharedOpsUtil } from "cables-shared-api";
  2. import path from "path";
  3. import fs from "fs";
  4. import projectsUtil from "./projects_util.js";
  5. import filesUtil from "./files_util.js";
  6.  
  7. class OpsUtil extends SharedOpsUtil
  8. {
  9. constructor(provider)
  10. {
  11. super(provider);
  12. this.PREFIX_LOCAL_OPS = "Ops.Local.";
  13. }
  14.  
  15. validateAndFormatOpCode(code)
  16. {
  17. return {
  18. "formatedCode": this._helperUtil.removeTrailingSpaces(code),
  19. "error": false,
  20. "message": null
  21. };
  22. }
  23.  
  24. isCoreOp(opName)
  25. {
  26. const opsDir = this._cables.getCoreOpsPath();
  27. const opDir = this.getOpSourceDir(opName);
  28. return opDir.startsWith(opsDir);
  29. }
  30.  
  31. addPermissionsToOps(opDocs, user, teams = [], project = null)
  32. {
  33. if (!opDocs) return opDocs;
  34. opDocs.forEach((opDoc) =>
  35. {
  36. const file = this.getOpAbsoluteFileName(opDoc.name);
  37. opDoc.allowEdit = true;
  38. if (file)
  39. {
  40. try
  41. {
  42. fs.accessSync(file, fs.constants.R_OK | fs.constants.W_OK);
  43. opDoc.allowEdit = true;
  44. }
  45. catch (e)
  46. {
  47. // not allowed to read/write
  48. opDoc.allowEdit = false;
  49. }
  50. }
  51. });
  52. return opDocs;
  53. }
  54.  
  55. userHasWriteRightsOp(user, opName, teams = [], project = null)
  56. {
  57. if (!user) return false;
  58. if (!opName) return false;
  59. if (!opName.startsWith(this.PREFIX_OPS)) return false;
  60. if (opName.indexOf("..") > -1) return false;
  61. if (opName.indexOf(" ") > -1) return false;
  62. if (opName.startsWith(".")) return false;
  63. if (opName.endsWith(".")) return false;
  64.  
  65. const validName = this.isOpNameValid(opName);
  66. if (!validName) return false;
  67.  
  68. const file = this.getOpAbsoluteFileName(opName);
  69. if (file)
  70. {
  71. if (fs.existsSync(file))
  72. {
  73. try
  74. {
  75. fs.accessSync(file, fs.constants.R_OK | fs.constants.W_OK);
  76. return true;
  77. }
  78. catch (e)
  79. {
  80. // not allowed to read/write
  81. return false;
  82. }
  83. }
  84. else if (this._cables.isPackaged() && file.startsWith(this._cables.getOpsPath()))
  85. {
  86. return false;
  87. }
  88. else
  89. {
  90. return true;
  91. }
  92. }
  93. return true;
  94. }
  95.  
  96. getOpAbsolutePath(opName)
  97. {
  98. return projectsUtil.getAbsoluteOpDirFromHierarchy(opName);
  99. }
  100.  
  101. getOpSourceDir(opName, relative = false)
  102. {
  103. if (!opName) return null;
  104. if (relative) return super.getOpSourceDir(opName, relative);
  105. return projectsUtil.getAbsoluteOpDirFromHierarchy(opName);
  106. }
  107.  
  108. getOpTargetDir(opName, relative = false)
  109. {
  110. let targetDir = "";
  111. if (relative)
  112. {
  113. if (opName.endsWith(".")) opName = opName.substring(0, opName.length - 1);
  114. return path.join(opName, "/");
  115. }
  116. else
  117. {
  118. targetDir = projectsUtil.getAbsoluteOpDirFromHierarchy(opName);
  119. }
  120. return targetDir;
  121. }
  122.  
  123. getOpSourceNoHierarchy(opName, relative = false)
  124. {
  125. return super.getOpSourceDir(opName, relative);
  126. }
  127.  
  128. getOpRenameConsequences(newName, oldName, targetDir = null)
  129. {
  130. return [];
  131. }
  132.  
  133. getOpRenameProblems(newName, oldName, userObj, teams = [], newOpProject = null, oldOpProject = null, opUsages = [], checkUsages = true, targetDir = null)
  134. {
  135. const problems = super.getOpRenameProblems(newName, oldName, userObj, teams, newOpProject, oldOpProject, opUsages, checkUsages);
  136. if (problems.no_rights_target && targetDir)
  137. {
  138. if (fs.existsSync(targetDir))
  139. {
  140. try
  141. {
  142. fs.accessSync(targetDir, fs.constants.R_OK | fs.constants.W_OK);
  143. delete problems.no_rights_target;
  144. }
  145. catch (e)
  146. {
  147. // not allowed to read/write
  148. }
  149. }
  150. }
  151. if (problems.target_exists && targetDir)
  152. {
  153. const newOpDir = path.join(targetDir, this.getOpTargetDir(newName, true), this.getOpFileName(newName));
  154. if (!fs.existsSync(newOpDir))
  155. {
  156. delete problems.target_exists;
  157. const existingOpDir = this.getOpSourceDir(newName);
  158. problems.overruled_by_other_op = "The new Op would conflict with the Op at:<br/> <a onclick=\"CABLESUILOADER.talkerAPI.send('openDir', { 'dir': '" + existingOpDir + "'});\">" + existingOpDir + "</a>";
  159. }
  160. }
  161. return problems;
  162. }
  163.  
  164. getOpAssetPorts(op, includeLibraryAssets = false)
  165. {
  166. const assetPorts = [];
  167. if (!op) return assetPorts;
  168. if (!op.portsIn) return assetPorts;
  169.  
  170. for (let i = 0; i < op.portsIn.length; i++)
  171. {
  172. const port = op.portsIn[i];
  173. if (
  174. port.value &&
  175. typeof port.value == "string" &&
  176. port.name &&
  177. port.value.length &&
  178. (port.display === "file" ||
  179. port.name.toLowerCase().indexOf("file") > -1 ||
  180. port.name.toLowerCase().indexOf("url") > -1 ||
  181. // port names in cubemapfromtextures !
  182. port.name.toLowerCase().indexOf("posx") > -1 ||
  183. port.name.toLowerCase().indexOf("posy") > -1 ||
  184. port.name.toLowerCase().indexOf("posz") > -1 ||
  185. port.name.toLowerCase().indexOf("negx") > -1 ||
  186. port.name.toLowerCase().indexOf("negy") > -1 ||
  187. port.name.toLowerCase().indexOf("negz") > -1)
  188. )
  189. {
  190. if (!port.value.toLowerCase().startsWith("/assets/library"))
  191. {
  192. assetPorts.push(port);
  193. }
  194. else if (includeLibraryAssets)
  195. {
  196. assetPorts.push(port);
  197. }
  198. }
  199. }
  200. return assetPorts;
  201. }
  202.  
  203. getOpNameByAbsoluteFileName(fileName)
  204. {
  205. if (!fileName) return "";
  206. const parts = path.parse(fileName);
  207. if (parts && parts.name) return parts.name;
  208. return "";
  209. }
  210.  
  211. updateOpCode(opName, author, code)
  212. {
  213. filesUtil.unregisterOpChangeListeners([opName]);
  214. const newCode = super.updateOpCode(opName, author, code);
  215. setTimeout(() =>
  216. {
  217. filesUtil.registerOpChangeListeners([opName]);
  218. }, 1000);
  219. return newCode;
  220. }
  221.  
  222. getOpNpmPackages(opName)
  223. {
  224. let toInstall = [];
  225. const opDoc = this._docsUtil.getDocForOp(opName);
  226. if (opDoc && opDoc.hasOwnProperty("dependencies"))
  227. {
  228. const npmDeps = opDoc.dependencies.filter((dep) => { return dep.type === "npm"; });
  229. npmDeps.forEach((npmDep) =>
  230. {
  231. const version = npmDep.version || "";
  232. if (npmDep.src)
  233. {
  234. npmDep.src.forEach((src) =>
  235. {
  236. if (version)
  237. {
  238. src = src + "@" + version;
  239. }
  240. else
  241. {
  242. if (npmDep.name.includes("@")) src = npmDep.name;
  243. }
  244. if (!toInstall.includes(src))
  245. {
  246. toInstall.push(src);
  247. }
  248. });
  249. }
  250. });
  251. }
  252. return toInstall;
  253. }
  254.  
  255. renameToCoreOp(oldName, newName, currentUser, removeOld, cb = null)
  256. {
  257. let oldOpDir = this.getOpSourceDir(oldName);
  258. let newOpDir = oldOpDir.replace(oldName, newName);
  259. return this._renameOp(oldName, newName, currentUser, true, removeOld, false, oldOpDir, newOpDir, cb);
  260. }
  261.  
  262. renameToExtensionOp(oldName, newName, currentUser, removeOld, cb = null)
  263. {
  264. let oldOpDir = this.getOpSourceDir(oldName);
  265. let newOpDir = oldOpDir.replace(oldName, newName);
  266. return this._renameOp(oldName, newName, currentUser, true, removeOld, false, oldOpDir, newOpDir, cb);
  267. }
  268.  
  269. renameToTeamOp(oldName, newName, currentUser, removeOld, cb = null)
  270. {
  271. let oldOpDir = this.getOpSourceDir(oldName);
  272. let newOpDir = oldOpDir.replace(oldName, newName);
  273. return this._renameOp(oldName, newName, currentUser, false, removeOld, false, oldOpDir, newOpDir, cb);
  274. }
  275.  
  276. renameToUserOp(oldName, newName, currentUser, removeOld, cb = null)
  277. {
  278. let oldOpDir = this.getOpSourceDir(oldName);
  279. let newOpDir = oldOpDir.replace(oldName, newName);
  280. return this._renameOp(oldName, newName, currentUser, false, removeOld, false, oldOpDir, newOpDir, cb);
  281. }
  282.  
  283. renameToPatchOp(oldName, newName, currentUser, removeOld, newId, cb = null)
  284. {
  285. let oldOpDir = this.getOpSourceDir(oldName);
  286. let newOpDir = oldOpDir.replace(oldName, newName);
  287. return this._renameOp(oldName, newName, currentUser, false, removeOld, newId, oldOpDir, newOpDir, cb);
  288. }
  289.  
  290. getPatchOpNamespace(opName)
  291. {
  292. return this.getNamespace(opName);
  293. }
  294.  
  295. getPatchOpsNamespaceForProject(proj)
  296. {
  297. return this.PREFIX_LOCAL_OPS;
  298. }
  299.  
  300. userHasReadRightsOp(user, opName, teams = null, project = null, opOwner = null)
  301. {
  302. return true;
  303. }
  304. }
  305. export default new OpsUtil(utilProvider);