@yuneta/gobj-js 7.28.0 → 7.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -428,7 +428,7 @@ var gobjJs = (function(exports) {
428
428
  }
429
429
  };
430
430
  function tab() {
431
- return " ".repeat(Math.max(1, __inside__ * 2));
431
+ return " ".repeat(Math.max(1, __inside__ * 4));
432
432
  }
433
433
  var __trace_machine_format__ = 1;
434
434
  function gobj_set_trace_machine_format(format) {
@@ -7545,28 +7545,43 @@ var gobjJs = (function(exports) {
7545
7545
  * Build a URL/path from segments, ensuring exactly one '/'
7546
7546
  * between each part.
7547
7547
  *
7548
- * - The first segment keeps its leading '/' (absolute) or
7549
- * not (relative).
7550
- * - Trailing '/' is stripped from every segment.
7551
- * - Leading '/' is stripped from every segment except the first.
7548
+ * - The first segment is the ROOT: it keeps its leading '/'
7549
+ * (absolute) or not (relative), and its trailing '/' are
7550
+ * stripped -- but a root made only of '/' stays "/".
7551
+ * - Leading and trailing '/' are stripped from every later
7552
+ * segment, and duplicate '/' inside it are collapsed.
7553
+ * - '.' and '..' of the later segments are resolved, and '..'
7554
+ * never rises above the root: ("/store", "../../etc") is
7555
+ * "/store/etc".
7552
7556
  * - Empty/null/undefined segments are skipped.
7553
7557
  *
7554
- * Mirrors the C helper build_path() from gobj-c/src/helpers.c.
7558
+ * Mirrors the C helper build_path() from gobj-c/src/helpers.c
7559
+ * (tests/build_path.test.js pins the same cases). Up to 7.28.1
7560
+ * a root "/" was lost (("/", "tmp") gave "tmp") and '.'/'..'
7561
+ * were kept as they came.
7555
7562
  ************************************************************/
7556
7563
  function build_path(...segments) {
7557
- let result = "";
7558
- let i = 0;
7564
+ let root = null;
7565
+ let tail = [];
7559
7566
  for (let segment of segments) {
7560
7567
  if (segment == null || segment === "") continue;
7561
7568
  segment = String(segment);
7562
- if (i === 0) segment = segment.replace(/\/+$/, "");
7563
- else segment = segment.replace(/^\/+/, "").replace(/\/+$/, "");
7564
- if (segment === "") continue;
7565
- if (i > 0) result += "/";
7566
- result += segment;
7567
- i++;
7569
+ if (root === null) {
7570
+ root = segment.replace(/(.)\/+$/, "$1");
7571
+ continue;
7572
+ }
7573
+ for (let component of segment.split("/")) {
7574
+ if (component === "" || component === ".") continue;
7575
+ if (component === "..") {
7576
+ tail.pop();
7577
+ continue;
7578
+ }
7579
+ tail.push(component);
7580
+ }
7568
7581
  }
7569
- return result;
7582
+ if (root === null) return "";
7583
+ if (tail.length === 0) return root;
7584
+ return root + (root.endsWith("/") ? "" : "/") + tail.join("/");
7570
7585
  }
7571
7586
  /***************************************
7572
7587
  * Flat json (id -> value)