feat(core): Introduce native implementations for Base64, random generation and normalization; remove runtime plugin dependencies; update tests, docs and package metadata
This commit is contained in:
@@ -1,10 +1,89 @@
|
||||
import * as plugins from './smartstring.plugins.js';
|
||||
|
||||
/**
|
||||
* the type for base 64
|
||||
*/
|
||||
export type TStringInputType = 'string' | 'base64' | 'base64uri';
|
||||
|
||||
/**
|
||||
* Cross-platform base64 implementation
|
||||
* Works in both Node.js and browser environments
|
||||
*/
|
||||
const universalBase64 = {
|
||||
encode: (str: string): string => {
|
||||
if (typeof Buffer !== 'undefined') {
|
||||
// Node.js environment
|
||||
return Buffer.from(str, 'utf8').toString('base64');
|
||||
} else if (typeof btoa !== 'undefined') {
|
||||
// Browser environment
|
||||
// Handle Unicode properly
|
||||
const utf8Bytes = new TextEncoder().encode(str);
|
||||
const binaryString = Array.from(utf8Bytes, byte => String.fromCharCode(byte)).join('');
|
||||
return btoa(binaryString);
|
||||
} else {
|
||||
// Fallback pure JS implementation
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
const bytes = new TextEncoder().encode(str);
|
||||
let result = '';
|
||||
let i = 0;
|
||||
|
||||
while (i < bytes.length) {
|
||||
const a = bytes[i++];
|
||||
const b = i < bytes.length ? bytes[i++] : 0;
|
||||
const c = i < bytes.length ? bytes[i++] : 0;
|
||||
|
||||
const bitmap = (a << 16) | (b << 8) | c;
|
||||
|
||||
result += chars.charAt((bitmap >> 18) & 63);
|
||||
result += chars.charAt((bitmap >> 12) & 63);
|
||||
result += i - 2 < bytes.length ? chars.charAt((bitmap >> 6) & 63) : '=';
|
||||
result += i - 1 < bytes.length ? chars.charAt(bitmap & 63) : '=';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
},
|
||||
|
||||
decode: (str: string): string => {
|
||||
// Handle base64uri by converting back to standard base64
|
||||
const base64String = str
|
||||
.replace(/-/g, '+')
|
||||
.replace(/_/g, '/')
|
||||
.padEnd(str.length + ((4 - (str.length % 4)) % 4), '=');
|
||||
|
||||
if (typeof Buffer !== 'undefined') {
|
||||
// Node.js environment
|
||||
return Buffer.from(base64String, 'base64').toString('utf8');
|
||||
} else if (typeof atob !== 'undefined') {
|
||||
// Browser environment
|
||||
const binaryString = atob(base64String);
|
||||
const bytes = new Uint8Array(binaryString.length);
|
||||
for (let i = 0; i < binaryString.length; i++) {
|
||||
bytes[i] = binaryString.charCodeAt(i);
|
||||
}
|
||||
return new TextDecoder().decode(bytes);
|
||||
} else {
|
||||
// Fallback pure JS implementation
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
let bytes: number[] = [];
|
||||
let i = 0;
|
||||
|
||||
while (i < base64String.length) {
|
||||
const encoded1 = chars.indexOf(base64String.charAt(i++));
|
||||
const encoded2 = chars.indexOf(base64String.charAt(i++));
|
||||
const encoded3 = chars.indexOf(base64String.charAt(i++));
|
||||
const encoded4 = chars.indexOf(base64String.charAt(i++));
|
||||
|
||||
const bitmap = (encoded1 << 18) | (encoded2 << 12) | (encoded3 << 6) | encoded4;
|
||||
|
||||
bytes.push((bitmap >> 16) & 255);
|
||||
if (encoded3 !== 64) bytes.push((bitmap >> 8) & 255);
|
||||
if (encoded4 !== 64) bytes.push(bitmap & 255);
|
||||
}
|
||||
|
||||
return new TextDecoder().decode(new Uint8Array(bytes));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* handle base64 strings
|
||||
*/
|
||||
@@ -50,21 +129,24 @@ export let base64 = {
|
||||
* encodes the string
|
||||
*/
|
||||
encode: (stringArg: string) => {
|
||||
return plugins.jsBase64.encode(stringArg);
|
||||
return universalBase64.encode(stringArg);
|
||||
},
|
||||
|
||||
/**
|
||||
* encodes a stringArg to base64 uri style
|
||||
*/
|
||||
encodeUri: (stringArg: string) => {
|
||||
return plugins.jsBase64.encodeURI(stringArg);
|
||||
return universalBase64.encode(stringArg)
|
||||
.replace(/\+/g, '-')
|
||||
.replace(/\//g, '_')
|
||||
.replace(/=/g, '');
|
||||
},
|
||||
|
||||
/**
|
||||
* decodes a base64 encoded string
|
||||
*/
|
||||
decode: (stringArg: string) => {
|
||||
return plugins.jsBase64.decode(stringArg);
|
||||
return universalBase64.decode(stringArg);
|
||||
},
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user