You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

97 lines
2.8 KiB

  1. const { existsSync: exists } = require('fs');
  2. const { dirname, basename, extname, join, resolve, relative, posix } = require('path');
  3. const { v4: uuidv4 } = require('uuid');
  4. const debug = require('debug')('server-connect:path');
  5. module.exports = {
  6. getFilesArray: function(paths) {
  7. let files = [];
  8. if (!Array.isArray(paths)) {
  9. paths = [paths];
  10. }
  11. for (let path of paths) {
  12. if (Array.isArray(path)) {
  13. files = files.concat(module.exports.getFilesArray(path));
  14. } else if (path && path.path) {
  15. files.push(module.exports.toSystemPath(path.path));
  16. } else if (path) {
  17. files.push(module.exports.toSystemPath(path));
  18. }
  19. }
  20. return files;
  21. },
  22. toSystemPath: function(path) {
  23. if (path[0] != '/' || path.includes('../')) {
  24. throw new Error(`path.toSystemPath: Invalid path "${path}".`);
  25. }
  26. return resolve('.' + path);
  27. },
  28. toAppPath: function(path) {
  29. let root = resolve('.');
  30. let rel = relative(root, path).replace(/\\/g, '/');
  31. debug('toAppPath: %O', { root, path, rel });
  32. if (rel.includes('../')) {
  33. throw new Error(`path.toAppPath: Invalid path "${rel}".`);
  34. }
  35. return '/' + rel;
  36. },
  37. toSiteUrl: function(path) {
  38. let root = resolve('public');
  39. let rel = relative(root, path).replace(/\\/g, '/');
  40. debug('toSiteUrl: %O', { root, path, rel });
  41. if (rel.includes('../')) {
  42. return '';
  43. }
  44. return '/' + rel;
  45. },
  46. getUniqFile: function(path) {
  47. let n = 1;
  48. while (exists(path)) {
  49. path = path.replace(/(_(\d+))?(\.\w+)$/, (a, b, c, d) => '_' + (n++) + (d || a));
  50. if (n > 999) throw new Error(`path.getUniqFile: Couldn't create a unique filename for ${path}`);
  51. }
  52. return path;
  53. },
  54. parseTemplate: function(path, template) {
  55. let n = 1, dir = dirname(path), file = template.replace(/\{([^\}]+)\}/g, (a, b) => {
  56. switch (b) {
  57. case 'name': return basename(path, extname(path));
  58. case 'ext' : return extname(path);
  59. case 'guid': return uuidv4();
  60. }
  61. return a;
  62. });
  63. if (file.includes('{_n}')) {
  64. template = file;
  65. file = template.replace('{_n}', '');
  66. while (exists(join(dir, file))) {
  67. file = template.replace('{_n}', n++);
  68. if (n > 999) throw new Error(`path.parseTemplate: Couldn't create a unique filename for ${path}`);
  69. }
  70. }
  71. return join(dir, file);
  72. }
  73. };