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.6 KiB
						
					
					
				
			
		
		
	
	
							97 lines
						
					
					
						
							2.6 KiB
						
					
					
				| // This file is taken from Node.js project.
 | |
| // Full implementation can be found from https://github.com/nodejs/node/blob/main/lib/internal/querystring.js
 | |
| 
 | |
| const hexTable = Array.from(
 | |
|   { length: 256 },
 | |
|   (_, i) => "%" + ((i < 16 ? "0" : "") + i.toString(16)).toUpperCase(),
 | |
| );
 | |
| 
 | |
| // These characters do not need escaping when generating query strings:
 | |
| // ! - . _ ~
 | |
| // ' ( ) *
 | |
| // digits
 | |
| // alpha (uppercase)
 | |
| // alpha (lowercase)
 | |
| // rome-ignore format: the array should not be formatted
 | |
| const noEscape = new Int8Array([
 | |
|   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15
 | |
|   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31
 | |
|   0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, // 32 - 47
 | |
|   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48 - 63
 | |
|   0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79
 | |
|   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, // 80 - 95
 | |
|   0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111
 | |
|   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,  // 112 - 127
 | |
| ]);
 | |
| 
 | |
| /**
 | |
|  * @param {string} str
 | |
|  * @returns {string}
 | |
|  */
 | |
| function encodeString(str) {
 | |
|   const len = str.length;
 | |
|   if (len === 0) return "";
 | |
| 
 | |
|   let out = "";
 | |
|   let lastPos = 0;
 | |
|   let i = 0;
 | |
| 
 | |
|   outer: for (; i < len; i++) {
 | |
|     let c = str.charCodeAt(i);
 | |
| 
 | |
|     // ASCII
 | |
|     while (c < 0x80) {
 | |
|       if (noEscape[c] !== 1) {
 | |
|         if (lastPos < i) out += str.slice(lastPos, i);
 | |
|         lastPos = i + 1;
 | |
|         out += hexTable[c];
 | |
|       }
 | |
| 
 | |
|       if (++i === len) break outer;
 | |
| 
 | |
|       c = str.charCodeAt(i);
 | |
|     }
 | |
| 
 | |
|     if (lastPos < i) out += str.slice(lastPos, i);
 | |
| 
 | |
|     // Multi-byte characters ...
 | |
|     if (c < 0x800) {
 | |
|       lastPos = i + 1;
 | |
|       out += hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)];
 | |
|       continue;
 | |
|     }
 | |
|     if (c < 0xD800 || c >= 0xE000) {
 | |
|       lastPos = i + 1;
 | |
|       out +=
 | |
|         hexTable[0xE0 | (c >> 12)] +
 | |
|         hexTable[0x80 | ((c >> 6) & 0x3F)] +
 | |
|         hexTable[0x80 | (c & 0x3F)];
 | |
|       continue;
 | |
|     }
 | |
|     // Surrogate pair
 | |
|     ++i;
 | |
| 
 | |
|     // This branch should never happen because all URLSearchParams entries
 | |
|     // should already be converted to USVString. But, included for
 | |
|     // completion's sake anyway.
 | |
|     if (i >= len) {
 | |
|       throw new Error("URI malformed");
 | |
|     }
 | |
| 
 | |
|     const c2 = str.charCodeAt(i) & 0x3FF;
 | |
| 
 | |
|     lastPos = i + 1;
 | |
|     c = 0x10000 + (((c & 0x3FF) << 10) | c2);
 | |
|     out +=
 | |
|       hexTable[0xF0 | (c >> 18)] +
 | |
|       hexTable[0x80 | ((c >> 12) & 0x3F)] +
 | |
|       hexTable[0x80 | ((c >> 6) & 0x3F)] +
 | |
|       hexTable[0x80 | (c & 0x3F)];
 | |
|   }
 | |
|   if (lastPos === 0) return str;
 | |
|   if (lastPos < len) return out + str.slice(lastPos);
 | |
|   return out;
 | |
| }
 | |
| 
 | |
| module.exports = { encodeString };
 |