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 }; |