als-store
Version:
Library for streamlined file management and advanced data caching, featuring intelligent file searching, dynamic cache control, and flexible file operations
64 lines (53 loc) • 2.29 kB
JavaScript
const os = require('os')
const platform = os.platform()
const windowsInvalidChars = /[<>:"\/\\|?*\x00-\x1F]/g;
const windowsReservedNames = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\.[^.]*)?$/i;
const isValidFilename = require('als-filename-validator')
function encode(value) {
if (value === undefined) return ''
if (value === null) return 'null'
if (value === NaN) return 'NaN'
if (typeof value !== 'string') return value.toString()
value = value.replace(/\./g, '[.]')
if (platform !== 'win32') return value
value = value.replace(windowsInvalidChars, (char) => {
return "_x" + char.charCodeAt(0).toString(16).toUpperCase();
});
value = value.replace(windowsReservedNames, (match) => {
return "_r" + match.split('').map(c => c.charCodeAt(0).toString(16).toUpperCase()).join('');
});
return value;
}
function decode(value) {
if (value === 'undefined' || value === '' || value === '[^]') return undefined
if (value === 'null') return null
if (value === 'NaN') return NaN
if (typeof value !== 'string') return value
value = value.replace(/\[\.\]/g, '.')
value = value.replace(/^\[\^\]/, '')
if (platform !== 'win32') return value
value = value.replace(/_x([0-9A-F]{2})/g, (match, charCode) => {
return String.fromCharCode(parseInt(charCode, 16));
});
value = value.replace(/_r([0-9A-F]+)/g, (match, hexString) => {
let chars = [];
for (let i = 0; i < hexString.length; i += 2) {
chars.push(String.fromCharCode(parseInt(hexString.substr(i, 2), 16)));
}
return chars.join('');
});
return value;
}
function paramsToName(params) {
if(params.length === 0) throw new Error('should be at lease one value')
const keys = Object.keys(params)
let name = keys.map(key => encode(params[key])).join('.')
while (name.endsWith('.')) {name = name.slice(0, -1)} // remove dots in the end
if (name === '' && keys.length === 1) name = '[^]'
if (isValidFilename(name, platform)) return name
else throw new Error(`${name} is not valid file name`)
}
function nameToParams(name) {
return name.split(/(?<!\[\.)\.(?!\])/).map(v => decode(v))
}
module.exports = {nameToParams,paramsToName,encode,decode}