braid-text 0.2.101 → 0.2.103

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.
Files changed (2) hide show
  1. package/index.js +69 -4
  2. package/package.json +2 -3
package/index.js CHANGED
@@ -2473,10 +2473,6 @@ function create_braid_text() {
2473
2473
  return i
2474
2474
  }
2475
2475
 
2476
- var {
2477
- encode_file_path_component, encode_to_avoid_icase_collision
2478
- } = require('url-file-db/canonical_path')
2479
-
2480
2476
  // Mapping between keys and their encoded filenames
2481
2477
  // Populated at init time, used to avoid re-encoding and handle case collisions
2482
2478
  var key_to_filename = new Map()
@@ -2735,6 +2731,75 @@ function create_braid_text() {
2735
2731
  }
2736
2732
  }
2737
2733
 
2734
+ // -----------------------------------------------------------------------------
2735
+ // File Path Encoding Utilities (from url-file-db/canonical_path)
2736
+ // -----------------------------------------------------------------------------
2737
+
2738
+ function encode_file_path_component(component) {
2739
+ // Encode characters that are unsafe on various filesystems:
2740
+ // < > : " / \ | ? * - Windows restrictions
2741
+ // % - Reserved for encoding
2742
+ // \x00-\x1f, \x7f - Control characters
2743
+ var encoded = component.replace(/[<>:"|\\?*%\x00-\x1f\x7f/]/g, encode_char)
2744
+
2745
+ // Encode Windows reserved filenames (con, prn, aux, nul, com1-9, lpt1-9)
2746
+ var windows_reserved = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\..*)?$/i
2747
+ var match = component.match(windows_reserved)
2748
+ if (match) {
2749
+ var reserved_word = match[1]
2750
+ var last_char = reserved_word[reserved_word.length - 1]
2751
+ var encoded_reserved = reserved_word.slice(0, -1) + encode_char(last_char)
2752
+ var encoded_extension = encoded.slice(reserved_word.length)
2753
+ encoded = encoded_reserved + encoded_extension
2754
+ }
2755
+
2756
+ // Encode trailing dots and spaces (stripped by Windows)
2757
+ if (encoded.endsWith('.') || encoded.endsWith(' ')) {
2758
+ var last_char = encoded[encoded.length - 1]
2759
+ encoded = encoded.slice(0, -1) + encode_char(last_char)
2760
+ }
2761
+
2762
+ return encoded
2763
+ }
2764
+
2765
+ function encode_to_avoid_icase_collision(component, existing_icomponents) {
2766
+ var icomponent = component.toLowerCase()
2767
+
2768
+ while (existing_icomponents.has(icomponent)) {
2769
+ var found_letter = false
2770
+
2771
+ // Find the last letter (a-zA-Z) that isn't part of a %XX encoding
2772
+ for (var i = component.length - 1; i >= 0; i--) {
2773
+ if (i >= 2 && component[i - 2] === '%') {
2774
+ i -= 2
2775
+ continue
2776
+ }
2777
+
2778
+ var char = component[i]
2779
+
2780
+ // Only encode letters - encoding non-letters doesn't help resolve case collisions
2781
+ if (!/[a-zA-Z]/.test(char)) {
2782
+ continue
2783
+ }
2784
+
2785
+ component = component.slice(0, i) + encode_char(char) + component.slice(i + 1)
2786
+ icomponent = component.toLowerCase()
2787
+ found_letter = true
2788
+ break
2789
+ }
2790
+
2791
+ if (!found_letter) {
2792
+ throw new Error('Should never happen - safety check')
2793
+ }
2794
+ }
2795
+
2796
+ return component
2797
+ }
2798
+
2799
+ function encode_char(char) {
2800
+ return '%' + char.charCodeAt(0).toString(16).toUpperCase().padStart(2, '0')
2801
+ }
2802
+
2738
2803
  function ascii_ify(s) {
2739
2804
  return s.replace(/[^\x20-\x7E]/g, c => '\\u' + c.charCodeAt(0).toString(16).padStart(4, '0'))
2740
2805
  }
package/package.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "name": "braid-text",
3
- "version": "0.2.101",
3
+ "version": "0.2.103",
4
4
  "description": "Library for collaborative text over http using braid.",
5
5
  "author": "Braid Working Group",
6
6
  "repository": "braid-org/braid-text",
7
7
  "homepage": "https://braid.org",
8
8
  "dependencies": {
9
9
  "@braid.org/diamond-types-node": "^2.0.0",
10
- "braid-http": "~1.3.85",
11
- "url-file-db": "^0.0.25"
10
+ "braid-http": "~1.3.86"
12
11
  }
13
12
  }