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
			| 
								 
											3 years ago
										 
									 | 
							
								// 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 };
							 |